Falling-Sand Playground, Explained

After reading this you can predict how sand piles, why oil floats on water, how fire sweeps through wood and dies, and how a handful of local pixel rules produce all of it.

What a falling-sand game actually is

A falling-sand game is a cellular automaton. The screen is a grid of cells, each cell holds exactly one material (sand, water, oil, fire, wood, wall, or empty air), and time advances in discrete steps. On every step the program sweeps the grid and applies a short list of rules to each cell based only on its immediate neighbours. Nothing plans ahead. A grain of sand does not know there is a floor two hundred cells below. It only checks the cell under it.

Here is the hook. Paint a vertical column of 100 sand cells in the middle of an empty box. Step the simulation. Each grain tries to move straight down. When the bottom grain lands on the floor, the grain above it lands on that, and so on. Once the column bottoms out, grains that cannot fall straight down try to slide diagonally. After a few hundred steps you get a cone with sides sloping at roughly 45 degrees. Nobody wrote "make a cone." The cone is what the fall-then-slide rule produces when you run it many times.

When this model is useful and when it is not

Use a falling-sand grid when you want to see how simple local rules build large patterns, and when a rough, cell-by-cell look at pouring, stacking, and burning is enough. It is excellent for intuition about granular piles, buoyancy ordering, and spreading fronts. It is cheap: a 200 by 200 grid is 40,000 cells, and a modern browser steps that tens of times per second.

Do not read real physical numbers off it. The grid has no true velocity, no pressure, no surface tension, and no conservation of momentum. Water here levels out because cells shuffle sideways, not because a pressure gradient drives flow. If you need accurate fluid dynamics with vortices and pressure, use a solver built for it.

This is a toy model. The "45 degree" sand slope and the "oil on water" ordering are artifacts of the movement rules and the density ranking, not measured material properties. Treat every result as qualitative.

The update rules, stated precisely

Give every material a density \rho and a small rule set. Empty air has \rho = 0. A cell decides its move by comparing its density to the cell it wants to enter.

\text{move down if } \rho_{\text{here}} \gt \rho_{\text{below}}

Here \rho_{\text{here}} is the density of the material in the current cell and \rho_{\text{below}} is the density of the cell directly beneath it. A grain of sand (\rho = 4) sitting above water (\rho = 2) satisfies 4 \gt 2, so the sand and water swap: sand sinks, water rises by one cell. Oil (\rho = 1) above water fails the test because 1 \lt 2, so oil stays on top.

Powders and liquids differ in one rule. A powder that cannot move down tries the two diagonal cells below and stops if both are blocked, which is why powders build slopes and stand up in heaps. A liquid that cannot move down or diagonally then tries straight left or right, which lets it spread flat and fill a container. Steam is a liquid with negative buoyancy: it runs the same rule upside down, rising until it cools.

Fire is a timed state. When it appears it lights any flammable neighbour, and after a fixed number of steps it turns to smoke.

t_{\text{next}} = t - 1, \quad \text{become smoke when } t = 0

Here t is the remaining life of a fire cell in steps. If a wooden neighbour catches, it becomes a new fire cell with a fresh t, so the burn front keeps moving while each individual flame is short-lived.

Sweep the grid from the bottom row upward. If you sweep top-down, a falling grain can move down into a cell you then process again in the same step, and it drops several cells at once. Bottom-up keeps each grain to at most one move per step.

A worked example: the demo pour

The demo starts with the default materials. Reproduce a small, hand-checkable version so you can follow every cell.

Sand into a two-column funnel

Take a grid 5 cells wide and 6 cells tall. Put walls forming a V: the bottom row has a single gap in the centre column, and the two lower corners are walls. Drop 4 sand grains into the top-centre cell over 4 steps.

  1. Step 1: one grain enters cell (row 0, col 2). Below is empty, so it falls to row 1.
  2. Step 2: that grain falls to row 2; a second grain enters at row 0.
  3. Step 3: the lead grain reaches the gap at row 5 and rests on the floor. The stack begins.
  4. Step 4: the next grain lands on top of it. It cannot go down (occupied) and cannot slide diagonally (walls block both sides of the funnel), so it stops directly above.

Result after settling: the 4 grains stack vertically through the gap because the funnel walls remove the diagonal option. Widen the gap to 3 cells and the same 4 grains spread into a low heap instead, because now the diagonal slide succeeds. The only thing you changed was the geometry, and the pile shape followed.

Reading the slope and the settling curve

The most measurable output of a powder is its angle of repose: the steepest stable slope of the heap. With the fall-then-diagonal rule and no friction term, a grain slides whenever a diagonal cell is open, so the heap stabilises near a 1-to-1 rise over run, about 45 degrees. Add a rule that only slides on every second attempt and the effective slope steepens.

You can also watch how fast a poured column settles. The chart below tracks the height of the tallest sand column as grains pour in at one grain per step into a flat box. The height climbs, then the pile spreads sideways and the peak height grows more slowly.

Peak height rises fast at first, then flattens as new grains slide outward instead of stacking up.

Notice the curve bends. Early on nearly every grain adds to the height. By step 100 the pile is wide, so an incoming grain often slides down the flank and the peak barely moves.

Density ordering you can predict

Because moves depend only on comparing densities, you can rank the materials and know in advance how they layer. Assign the values the simulation uses and sort them.

Density ranking and resulting layer order (top to bottom)
MaterialDensityBehaviourSettles
Steam-1risestop
Fire0climbs flammabletransient
Oil1floats on waterupper liquid
Water2fills containerslower liquid
Salt3powder, sinks in oilon floor
Sand4powder, sinks in wateron floor

Pour oil and water into the same box and the oil ends on top every time, because \rho_{\text{oil}} = 1 \lt \rho_{\text{water}} = 2 and the swap rule only fires when the upper cell is denser. Drop sand into that stack and it passes through both liquids to the floor, since 4 \gt 2 \gt 1.

Assign each of oil, water, sand and steam a density from -2 to 5, and the four materials sort into horizontal layers with the largest density on the bottom and negative densities rising to the top. With oil 1, water 2, sand 4, steam -1 you get, top to bottom: steam, oil, water, sand.

Common mistakes and how to avoid them

Four errors account for most confusion when people build or read these grids.

Top-down sweeping
Processing rows from the top makes grains teleport downward, because a moved grain gets reprocessed in the same step. Sweep bottom-up for falling materials.
Forgetting the "already moved" flag
Without marking a cell as done for the current step, water can shuffle back and forth and never settle. Each cell should move at most once per step.
Expecting real conservation
A swap keeps material count constant, but fire turning to smoke and smoke fading to air deliberately destroy cells. The grid does not conserve mass by design.
Reading angle or flow speed as physical
The 45 degree slope and the spreading rate come from the neighbour rules and the step rate, not from grams or newtons.

One more subtlety: fire needs somewhere to go. A spark surrounded by wall and non-flammable material simply counts down its life t and turns to smoke without spreading. A single spark in a dense wooden lattice, by contrast, ignites new flames faster than old ones die, so the front sweeps across and only stops when it runs out of fuel.

Related simulations to explore next

If local rules building global order interests you, several other sandboxes on this site show the same theme from different angles. The Cloth Simulator uses Verlet integration where each point mass only pulls on its neighbours, yet a whole sheet drapes and tears. The Lightning Simulator grows a branching discharge one cell at a time, much like the fire front here. For real fluid behaviour with pressure and vortices that this toy cannot produce, try the Fluid Flow Simulator. And to see how a Chladni plate gathers real sand grains into nodal lines, visit Chladni Plate Patterns.

Frequently asked questions

Why does sand always pile at about 45 degrees?

Because a grain slides diagonally whenever the diagonal-below cell is open, and a diagonal step covers one cell across for one cell down. That 1-to-1 ratio is a 45 degree slope. Change the diagonal rule (slide only sometimes) and the angle changes.

Why does oil sit on top of water?

The swap rule fires only when the upper cell is denser than the lower one. Oil has density 1 and water has density 2, so oil above water never swaps down, while water above oil (density 2 above 1) does swap. The stable arrangement is oil on top.

Why does fire go out on its own?

Each fire cell carries a life counter that decreases by one every step and becomes smoke at zero. Fire keeps going only while it lights new flammable cells faster than existing flames expire. Remove the fuel and the whole fire dies within a few steps.

Does the simulation conserve the amount of material?

Only for moves that swap two cells. Reactions like wood to fire to smoke to air are designed to remove material, so total cell counts drop over time. That is intentional, not a bug.

Why should the grid be swept from the bottom up?

So a grain moves at most one cell per step. Sweeping top-down lets a grain that just fell get reprocessed lower in the same sweep, dropping it multiple cells and breaking the one-move-per-step assumption.