Skip to content
chowjiamingPublic

About

Falling-sand cellular automaton in Rust, compiled to WebAssembly

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

43 Commits

Folders and files

Repository files navigation

Sandboxed

CI License: MIT

A falling-sand cellular automaton written in Rust, compiled to WebAssembly, and rendered in the browser.

Live demo

Paint sand, water, stone, fire, and wood onto a 320×200 grid. The page loads a small wood-and-fire scene so burning is visible immediately. The simulation runs in WASM: a flat Vec<Cell>, no per-frame allocation, and a thin wasm-bindgen boundary so the core stays unit-testable with plain cargo test.

Why Rust → WASM

  • Performance — dense grid, no GC pauses in the hot loop
  • Safety — particle swaps without undefined behavior
  • Portability — one codebase for native tests and the browser

Controls

Input Action
Click / drag Paint the selected material (gapless stroke)
Shift-drag Straight line (horizontal, vertical, or 45°)
Right-click Erase
Brush slider Radius 1–8; [ ] or scroll wheel
1–9 / 0 / O I G Select material
Arrow keys Fan facing
Scenes Sink, Float, Burn, Wind, Glass presets
Pause / Step Freeze the sim; advance one tick
Space / . Pause toggle / single-step
? Toggle shortcut overlay
Hover Material + heat under the cursor
Sand Falls and piles; sinks through water
Water Flows and spreads
Stone Static obstacle
Fire Rises, flickers, burns out; heats neighbors
Wood Static; ignites when heat reaches 80
Steam Rises; condenses when cool; water boils next to fire
Fan Four facing buttons (or arrow keys); blows gases in that 4×4
Gunpowder Falls like sand; explodes from fire or heat 80
Smoke Rises slower than steam; leftover from burned-out fire
Oil Floats on water; ignites from fire or heat 60
Ice Static; melts to water at heat 25; water freezes below 15
Glass Sand baked at heat 180; locked like stone
Erase / Clear Remove cells

Quickstart

Requires a Rust toolchain, just, wasm-pack, and miniserve.

cargo install just wasm-pack miniserve
just serve          # http://localhost:8080
just verify         # fmt, clippy, tests, wasm-pack — same as CI

Pushes to main run that suite and deploy the site to GitHub Pages.

Performance

Native World::step() at 960×600, release, 300 ticks (just bench):

Scene Before chunks After chunks
Sparse (1 grain) 1,014 steps/s 16,303 steps/s (~16×)
Dense (top quarter) 833 steps/s 604 steps/s

Sparse worlds skip idle 16×16 chunks. A full grid still visits every active chunk, so dense scenes are not faster. The live demo stays at 320×200; these numbers are simulation throughput, not browser composite FPS.

Layout

File Role
src/world.rs Grid storage and simulation rules
src/renderer.rs Grid → RGBA frame buffer
src/lib.rs Thin wasm-bindgen boundary
index.html Canvas, palette UI, rAF loop
justfile Local tasks matching CI

License

MIT © Joseph Chow

About

Falling-sand cellular automaton in Rust, compiled to WebAssembly

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages