A JavaScript port for easy access
s: sand, w: water, a: air, x: stone, 1: seed, e: fish egg
ctrl: single place, up/down arrow: change place size
The above is a port of the C program doing essentially the same thing out of the box, with one key difference.
The desktop C version of this programs comes with a single C file, and several rulesets. The C file is simply an engine, with the rulesets being written in custom scripting language.
The scripting language can define elements by giving a color, and listing tags of the element. These tags can then be used in rules to describe how elements with specified tags act. In order to simplify the rulewriting process, you can make shorthands for terms. Look through the following sections to get an idea of the syntax and how these rules work.
An element is defined as shown on the right. First, pick a color in hex. If you want the user to be able to draw the element to the canvas, you can add a single character to the end to denote a key the user can press to select it. The lines following the element start with a '-' and have strings that denote 'tags' of this element. These tags can be selected in rules and used to have elements interact with eachother.
Here we've defined a tan element with the keybind "s", it is tagged as "sand", "solid", "fallable", and "pileable". The solid tag can be used to make sure nothing falls through it. The fallable tag can be used to make sure it falls straight down, and pileable can be used to make elements form piles rather than pillars.
Symbols can be used in rule definitions in order to make rules more coherent. They can be defined by typing any character not including "#", "*" or " ". You assign it to an element tag, color, or reference, by adding a '=>' before a string containing the tag you want to use in shorthand.
In this example, we add shorthand for "fallable", "passthrough", "solid", and "pileable" elements with the characters "f", "0", "s" and "p", and the color "#ff0000" with "r", and the reference (0, -1) with "^" which you can see being used in rules later on.
Rules are initialized with the "rule:" phrase. They can include 3 flags in any order at any point in the line, "x", "y", and a "num%". The flags 'x' and 'y' tell the engine that the rule can be mirrored horizontally and/or vertically ("x" and "y" respectively). Say you want to select the pattern a b c in your rule, but would also want the same rule flipped to select c b a and perform the same action (also flipped) on it, you would just specify 'x'. The "num%" flag will make it so there's only a "num%" chance of it happening any given execution. This can be used to feign slowness or friction in certain rules.
The rules themselves are defined in two 5 by 5 series of character seperated by whitespaces. There must be a two character seperator in the 3rd row between the two 5x5 sides. I always put "=>" here, but the engine technically doesn't check which two characters you use. The first 5x5 set is the pattern selector. The engine will look for this pattern of elements in the world. Entries can be colors, tags, previously defined shorthand, or '*'. The '*' character will select anything.
The second 5x5 body is how the engine responds when it finds the pattern in the first block. In this block, the "*" character means "unchanged". A color means it will simply set that element in the selected pattern to that color. An element tag will select a random element with that tag, and place it there. And references, which will set it to an element in the pattern, using coordinates in relation to it. For example, if the response element in the middle is "(1, 1)", it will set itself to the element diagonally down and to the right.
The rule on the right uses the symbols previously defined to search the whole screen for a "pileable" element, that sits on top of a "solid" element, and has a "passthrough" element down and to the right, and it ignores all other elements in the 5x5 scanning area. It's mirror horizontally, and so this rule will work to the left as well. Recall that '\' was defined as a reference that points down 1 and right 1, and / as a reference that points up 1, and left 1. In this rule's response, the pileable element gets set to whatever was in the bottom right, i.e. the passthrough element. And the passthrough element gets set to whatever was up and left from it, i.e. the pileable element. The passthrough and pileable elements are effectively swapped, and it appears as the pileable element sliding off the solid element.
A visual representation can be seen here. The engine searches for the image on the left, where all white are ignored spaces, the tan is a sand element which has the tag "pileable", the grey is a stone element which has the tag "solid", and the blue is an air element which has the property "passthrough". The engine recognizes this as satisfying the rule, and swaps the sand and air.
I will now run you through the Sand ruleset.