A polished, fully original retro falling-block puzzle game in Rust — built end-to-end by two local LLM subagents orchestrated by a single Pi coding-agent session. No cloud model, no human-written code.
Demonstration purpose: this repository shows that locally-hosted open models + an agent harness (Pi) with subagent orchestration can produce working, tested, gated, audited software. The entire implementation and adversarial test suite was written by the models; the human never wrote a line.
| Role | Model | Hosted on | Job |
|---|---|---|---|
| Coordinating parent (Pi session) | Qwen3.8 Flash-Next | local (RTX Spark box) | orchestration, environment diagnosis, final verification only |
| IMPL subagent | Qwen3.8 Flash-Next 125B/6B MoE | local llama.cpp, RTX Spark box | all game code, music synthesis, unit tests, commits |
| TEST subagents (fresh each round) | Qwen3.8 27B | local llama.cpp, RTX 5090 | independent adversarial verification, 46 regression tests, PASS/BLOCK verdicts |
Everything ran on models served from the same desk. See docs/JOURNEY.md for the full story — including the failures — and docs/REQUIREMENTS.md for the original (condensed) build prompt.
- 10x20 playfield, 7 tetromino-style pieces with 7-bag randomizer
- CW/CCW rotation with an 8-offset wall/floor kick table
- Soft drop (1 pt/cell), hard drop (2 pt/cell), single to quad line clears
- Scoring 100/300/500/800 x level, level-up every 10 lines (cap 20), geometric gravity curve
- Next-piece preview, ghost piece, pause, restart, game over, title and game-over screens
- 1980s arcade look: chunky pixel blocks, bright colors, dark background, scanline overlay
- Original 4-channel procedural chiptune music (square lead, triangle bass, off-beat pulse, noise blips) synthesized at runtime in Rust — plus original SFX for rotate / line clear / hard drop / game-over. Zero downloaded assets; nothing copyrighted (a dedicated test guards that the lead melody does not open like any existing tune).
Controls: Left/Right move, Down soft drop, Up or X rotate CW, Z rotate CCW, Space hard drop, P pause, R restart, Esc quit. Also A/D/S/W/Q aliases with DAS auto-repeat.
cargo run --release # play
cargo test # 107 tests
cargo run -q -- --selfcheck # headless logic verification -> SELFCHECK OK
Rust 1.85+ and a GPU/GL context; Linux X11 tested. Only dependency: macroquad 0.4 (with audio).
Troubleshooting ("cannot find -lasound" at link time): some distros ship libasound.so.2 without the libasound.so dev symlink. Either install libasound2-dev, or point build-support/ld/libasound.so at your libasound.so.2 (see .cargo/config.toml).
The TEST agent (a different model on a different machine) ran the full gate on the final commit and adversarially audited it:
- cargo fmt / check / clippy -D warnings — clean
- 107 tests passing (61 unit + 46 adversarial integration: exhaustive wall/floor rotation sweeps, spawn-collision game over, pause byte-identity, restart wipes, multi-row clears, scoring/level math, gravity monotonicity, and more)
- Headless --selfcheck OK; under xvfb-run the release binary ran a full 15 s main loop with zero panics and live audio init
- Compliance audit: no "tetris"/"korobeiniki" string anywhere in source or binaries — this caused the one BLOCK round, see the journey
Round-1 verdict was BLOCK: the auditor refused to pass the repo over a single non-compliant identifier and forced a real repair cycle. That discipline is the point of the demo.
src/main.rs rendering shell + input + scenes (macroquad)
src/game.rs game state machine, scoring, levels, events
src/board.rs collision, line clears, rotation-with-kicks
src/piece.rs piece geometries, 7-bag
src/audio.rs graceful audio layer (game never crashes if audio fails)
src/synth.rs procedural chiptune + SFX synthesis (WAV in memory)
src/selfcheck.rs headless invariant checks (--selfcheck)
tests/ 46 adversarial integration tests (written by the TEST agent)
docs/ journey + original requirements
- Verified on Linux/X11 (and Xvfb); not exhaustively tested on other platforms.
- On a headless machine the binary exits via miniquad's XOpenDisplay() panic before game code runs — dependency behavior, not game code (use --selfcheck / xvfb-run there).
- The game is an original work homaging the genre of 80s arcade falling-block games, not any specific commercial product.
Built in one evening of wall-clock time by qwen3.8-flash-next (llama.cpp, RTX Spark box) and qwen3.8-coding 27B (llama.cpp, RTX 5090), orchestrated by one Pi v0.85.1 session using the pi-subagents workflow extension. No API dollars spent.

