The Rink of Insanity

The Rink of Insanity is a skating-themed 2d esolang designed by User:BoundedBeans. Rather than describing the control flow directly, it outlines a path for skaters to follow to perform the instruction.
==Skaters==
Skaters behave somewhat like instruction pointers or threads in other languages, except that you need a lot of them to do anything useful.
There are a few types of skaters.
===Insane skaters===
These are the skaters that actually know how to skate (this esolang is mainly a work of sarcasm over the creator's dislike for skating).
Insane skaters mainly do the computation, through collisions.
Insane skaters have a starting direction and a current direction which is initialized to their starting direction. They move in their current direction every tick. Insane skaters get deleted if they leave the playfield.
===Sane skaters===
Sane skaters always occupy one of the following tiles: wall, coin pile, mirror, door, portal. They search for a correct tile either directly in front or in front and to the left, with directly in front having priority. If they move to the left, they turn left. They can turn elsewhere through mirrors. If a mirror takes them onto ice or broken ice, they become insane skaters. They start by moving left, unless they are from a helmet. Sane skaters reverse when hitting the edge of the playfield.
===Zamboni===
Zambonis start by moving down, unless they are from a helmet. Zambonis' directions can be changed with mirrors, though. Zambonis turn broken ice back into ice when they come into contact with it. Zambonis wrap around the playfield.
===Collisions===
If at the start of the tick before it has had a turn to move, a skater occupies the same tile or an adjacent tile to another skater of any type, it reverses its direction and if the tile the skater is on is ice, it changes to broken ice.
However, collisions work a bit differently if one skater is blocked behind a door. Both skaters are deleted and a new skater is put in its place, with the direction that would cause it to still be blocked by the door. The type of the new skater is a sane skater as long as at least one of the original skaters is sane. Otherwise, it is insane. A newly merged skater can never be a zamboni.
Zambonis can have collisions, but this merely deletes the other skater and doesn't change the zamboni's direction.
==Comments==
Anything after % to the end of the line will be replaced with spaces (plain ice) before the program executes. Note that comments can increase the size of the grid.
==Tiles==
===Ice===
Insane skaters and zambonis can move through this tile. If a collision between two insane skaters or one insane skater and one sane skater happens on this tile, it changes to broken ice.
===Broken ice===
Insane skaters cannot enter this tile. A sane skater becomes insane when entering this tile, and will move through it as normal ice until it leaves. Zambonis transform it to ice when they touch it.
===Wall===
Insane skaters reverse their direction if they enter a wall. Zambonis and sane skaters pass through.
===Coin piles===
Can either hold a 16-bit unsigned number or null. Insane skaters change it to 0 if it is null, and add 1 to the integer otherwise. Sane skaters input into it if it is null, otherwise they print it (null is printed as 0). Zambonis have an internal value which they swap with that of the coin pile, and they retain this even if they become other kinds of skaters.
Coin piles can either be in dollars or cents. Dollars work with ascii characters, cents work with numbers.
Coin piles start as null. They cannot be turned back into null except by swapping with Zambonis. (Incrementing from 65535 just wraps back to zero.) However, duplicating a zamboni with a splitter copies the value, so it is possible to always hold some nulls in "storage" to swap with later.
Input is provided in a special format in UTF-16. The command line arguments (including the file name) are specified, terminated by null characters, the whole list terminated by the empty string. This means there will always be two null characters at the end. Then, the actual input will begin. Null here refers to Unicode character 0. If actual null is input into the coin pile, that indicates EOF. If in the Rink Of Insanity program there is a line containing [no cmd args] with only whitespace surrounding it, the program will not take in command line arguments. That line will not be included in the grid.
===Mirrors===
Mirrors bounce a skater off of it like a ray of light.
===Deciders===
Deciders take the internal value collected by zambonis (even if the skater is no longer a zamboni), and check if it is null. If it isn't null, it retrieves the least significant bit of it. If it is 1, it turns right, otherwise it turns left. It then right-shifts the internal value by 1, with wrapping. If it is null, it continues moving in its current direction. This allows input testing, but can also be used as a general test since they can be modified in other ways.
===Doors===
Doors can only be entered from a specific axis. If it is touched by a skater traveling on the other axis, it will wait until the door changes. If it is traveled through by a skater traveling on the correct axis, it will switch the correct axis. If anything is let through because of that, it will, naturally, go back to its original axis.
===Portals===
If a portal is entered, it skips until the next portal in its path, all in one tick.
===Helmets===
If a skater touches one of these, it changes the skater's type to the type corresponding to the helmet.
===Splitter===
If a skater touches one of these, it will turn into two copies, one which turns left, and one which turns right. They are also moved one tile in their new direction to prevent a collision.
===Skipper===
The skater skips over one tile, in the same tick as encountering this command.
==Syntax==
Character	Action/Tile
(space) 	ice
@ 	broken ice
# 	wall
$ 	dollar coin pile
¢ 	cent coin pile
/ or \ 	mirrors
+ 	deciders
 	door that can be entered on the x axis
- 	door that can be entered on the y axis
O 	portal
s 	sane helmet
i 	insane helmet
z 	zamboni helmet
¥ 	splitter
; 	skipper
><^v 	spawn skater moving in the arrow's direction, tile as ice
S 	spawn sane skater, tile as wall
Z 	spawn zamboni, tile as ice
===Logic gates===
This gate uses the presence of a skater to the coming from the left to the X as the inputs, and the output goes to the Y also as the presence of a skater.
It produces an output every 53 ticks, with an offset from the start larger than the cycle length (the offset shouldn't affect anything if you hook it up to other gates.) although positive input can come early and still have an effect.
This is a NOR gate, so any gate can be constructed out of many of these. (If everything works correctly of course; I have no implementation as of the creation of it).
You might need to modify the clock at the top 
NOR:
 />\
 %All this blank stuff here
 %is to synchronize the
 %clock.
 %
 %You should be able to increase this if needed to synchronize with other gates
 %and the travel time between them.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 \ ¥ \
 /¥ \
 /¥\
 O
 X | -
 
 X | -
 
 \;\ \ 
 / \ 
 
 /;/$ -;/
 \ -
 \\
 O
 z
 \¥/
 \ /
 O
 /+\
 | \\
 /+\
 | \ Y
This enables combinational logic, but due to the presence of mirrors being able to change direction and splitters able to duplicate skaters, it's possible to duplicate a bit or create a loop by feeding it back to an earlier gate. The necessary hardcoded bits to use exclusively NOR gates can be used with a loop of mirrors and a splitter (similarly to the one at the top of this gate). This allows it to emulate any finite-state automaton. Since there are a finite amount of tiles (and thus coin pile integers and ice breakage states), and skaters must occupy their own tile, The Rink Of Insanity cannot be any more powerful than that.
Category:Finite state automata
Category:Two-dimensional languages
Category:Concurrent programming
Category:Languages
Category:2023
Category:Thematic
Category:Unimplemented