A Noita-inspired sand-simulation game with space theming. Hand-written in Rust, single-file, falling-sand physics through 14 materials, procedural biomes, guns with augments, and a crash-landing intro.
This game, like most of the others in my side-projects work, is an experiment in fully agentic generation. The interesting question for this one was language: most of my other projects were JavaScript / Three.js / Pixi.js, where the agent had a million examples to draw from. Could the same agentic loop close on a Rust desktop game written from scratch, with no engine, just pixels for a framebuffer and winit for a window? The answer was yes, but the shape of how it succeeded was different.
So read this README in two layers. There's the game (a Noita-style sand simulation you crash-land into) and the meta question (what changes when you push the agentic loop into a less-trodden language and a tighter problem domain). The second is the more interesting one.
You crash-land on a procedurally-generated alien surface. Below you are five biomes (Stone Caves, Forest, Frozen Caverns, Toxic Swamp, Lava Pits), each with their own materials, hazards, and creatures. You have a gun with randomised stats and an augment system that swaps what it fires (Plasma Bolt, Scatter Shot, Missile) and how (Accelerator, Splitter, Bouncer, Igniter, Freezer, Acid, Explosive). Materials interact: water freezes near ice, ice melts near fire, lava plus water becomes stone plus steam, fire ignites wood and oil and gas. Slimes hop, bats fly in wavy patterns, both deal damage on contact. You can levitate by holding jump, with a fuel meter that recharges on the ground.
Two modes:
- Game mode — combat, exploration, take damage from hazards, shoot enemies.
- Sandbox mode — full material palette, place anything anywhere, watch the simulation run.
I wanted to know whether the agent loop that worked well for Pixi.js and Three.js would still work for Rust. Rust is stricter, the iteration cycle is slower (compilation), and there is less canonical "this is how you do X" prior art for game-dev specifically. Sand simulation is also a tight problem with well-defined invariants (cellular automaton update rules, conservation of mass per cell, etc.) so it's a good test of whether the agent can hold a coherent simulation in its head.
Install Rust from https://rustup.rs/ or via winget install Rustlang.Rust.GNU, then:
git clone https://github.com/danfking/sand-game.git
cd sand-game
cargo run --releaseThe release build is meaningfully faster for the simulation step, worth the extra compile time.
Same commands. The pixels and winit crates handle the platform layer; no Windows-specific code.
- Tab — toggle Sandbox / Game mode
- Left click — shoot, aim with mouse
- Right click + drag — place material
- Q — cycle projectile (Plasma Bolt → Scatter Shot → Missile)
- R — cycle modifier (None → Accelerator → Splitter → Bouncer → Igniter → Freezer → Acid → Explosive)
- Left click — place selected material
- Click palette — select material from the right-side palette
- WASD / arrows — move
- Space / W / Up — jump (hold to levitate)
1 Sand, 2 Stone, 3 Water, 4 Wood, 5 Fire, 6 Smoke, 7 Oil, 8 Acid, 9 Lava, 0 Eraser, G Gunpowder, E Gas, I Ice, T Steam.
- C — clear world (resets player position)
- N — generate new procedural world
- S — save world to file
- L — load world from file
- ESC — exit
pixels— pixel-buffer rendering. Just gives you a writable framebuffer, no scene graph.winit— window and event loop.pollster— small async runtime for GPU init.randwithsmall_rngfor fast deterministic randomness in the simulation hot path.env_loggerandlog.
The whole thing is a single src/main.rs file (around 4400 lines). I considered breaking it up several times and didn't. The cellular-automaton update touches almost every part of the program, and the "everything in one file" constraint kept the coupling explicit rather than hidden behind module boundaries.
This is the section worth reading even if you don't care about the game.
- Rust slows the iteration loop and the agent adapts. Each compile is seconds to tens of seconds. The agent ends up making larger, more deliberate edits, because the cost per round-trip is higher. Compared to Pixi.js projects where it was happy to make small probing changes, here it converged on bigger commits that "should work" before testing. This is actually an improvement in code quality. Fast compile cycles encourage sloppier hypothesis-testing.
- Single-file architecture worked, surprisingly. I expected the agent to want to split this into modules. It didn't. It treated the file as a single artefact and made internally consistent changes across it. The material interaction matrix, the projectile system, the player state, the procedural generation, all stayed coherent in one file. My hunch is that for a tight simulation with shared state, a single file is easier for the agent than scattered modules.
- Specific visual references close the verification loop. "Make it like Noita" was a hard target. Pixel resolution (320x180), pixel scale (4x), player sprite size (12x19), camera feel (zoomed). Each of those is a measurable thing the agent can check itself against. Compare to the projects where I just said "fantasy" or "watercolour", which left every decision underspecified.
- Materials-and-interactions is a combinatorial design space the agent handles well. Fourteen materials means up to 14×14 = 196 possible interactions. Most are "nothing happens", but the meaningful ones (fire ignites oil, lava freezes near ice, acid dissolves stone but not metal) are individually small enough for the agent to reason about cleanly. The phase-by-phase development log in ARCHITECTURE.md shows how this scaled.
- Audio is the missing layer. Same pattern as my other side-projects: sound effects are still on the "future work" list. Audio loops require taste judgments the agent can't make alone, the same problem as visual polish in the other projects, just for a different sense. I'd want a different agent loop to close this.
Playable proof of concept. Thirteen phases done, audio still on the future list. The crash-landing intro, procedural biomes, all 14 materials with their interactions, guns and augments, slime and bat enemies, levitation with fuel, save/load, all working. Game mode and sandbox mode both playable.
If I came back: audio (crash impact, ambient wind, weapon shots, material interactions), more enemy types, and atmosphere transitions during the crash sequence (space → atmosphere → surface).
See ARCHITECTURE.md for the development phase log (which doubles as a system tour) and notes on the simulation update strategy.
This repository was extracted from a private monorepo where I work on many side projects together. The single initial commit reflects the migration, not the development cadence; the work itself unfolded across many sessions.
MIT. See LICENSE.