Pac-Man — how it was built
The spec, the instructions, and the honest version of how it went.
Both versions were built by Huginn, the coding agent: Kai writes the spec, Huginn writes the code — one small checkpoint at a time, each one passing a hard gate before it's committed. One build ran on a small local model (Qwen3.6-27B, INT4); one on a cloud model (DeepSeek). Both are Rust, compiled to WebAssembly.
The honest part
Pac-Man is the counterweight to the solar system. The solar system went almost in one shot: every checkpoint was specified in tight detail with a test that asserted real behaviour (planets actually move, hover actually picks the right body), so it came together cleanly and needed only one round of visual fixes after review.
Pac-Man did not go that smoothly — and the reason is the spec, not the
model. The original plan was a sensible eight-step build order: maze → movement → ghosts
→ scoring → web → polish. But it was shallow on the things that actually make Pac-Man
feel right — the ghosts' scatter/chase wave timing, the exact collision rules, the
authentic maze geometry, the corridor widths. A clean cargo build tells you
nothing about whether the maze is playable. So those gaps only surfaced when we sat down
and played it — and we had to bolt on five more checkpoints to fix them:
- 09 — scatter/chase waves: the ghost-AI mode timing wasn't authentic.
- 10 — overlap collision: Pac-Man and ghosts could slip through each other.
- 11 — frightened randomness & speed: power-pellet behaviour was off.
- 12 — authentic playable maze: the maze wasn't a faithful, playable layout.
- 13 — single-width corridors: the corridors were the wrong width.
That's the whole lesson, and it's exactly why it's worth showing: with agentic building, the spec and the gate carry as much weight as the model. Specify the behaviour precisely and test it, and you get a near one-shot. Under-specify the feel and lean on a compile-only gate, and you pay it back later in bugs found by hand. The harness is the lever — the model is only half the story.
The instructions we handed Huginn
Each build started from a settled design doc plus an operating manual (AGENTS.md)
carrying a non-negotiable per-checkpoint gate:
Do exactly one small checkpoint per turn, then stop.
Before every commit, the gate must be green:
• cargo build — zero warnings, not just zero errors
• cargo test — passes; add tests for the new logic
• cargo clippy --all-targets -- -D warnings — clean; fix the cause, never silence
• commit on the dev branch, never push, then summarize and stop
And a kickoff that drove one step at a time (representative):
Read AGENTS.md and the design doc, implement the next checkpoint only,
pass the gate, commit on the dev branch, then stop.
The spec — checkpoint by checkpoint
The original build order (settled up front):
- Workspace setup — a Cargo workspace: pure-Rust core, a WASM frontend, a native egui frontend.
- Maze — the 30×28 classic grid, pellets, spawn points, ghost house, loaded from a text map.
- Movement & collision — grid-aligned Pac-Man, arrow-key input, wall collision, tunnel wrap.
- Ghost AI — Blinky, Pinky, Inky, Clyde with distinct chase, scatter, and frightened modes.
- Pellets, scoring, lives — eating, power pellets, score, lives, death, win/lose.
- WASM frontend — a canvas renderer (wasm-bindgen + web-sys), keyboard input, the game loop.
- Sprites & animation — Pac-Man's four directions + chomp, ghost colours, frightened/eaten states.
- UI & states — start screen, game-over, score display, level reset.
…then, found in play and added reactively: 09 scatter/chase waves, 10 overlap collision, 11 frightened randomness & speed, 12 authentic playable maze, 13 single-width corridors. Thirteen checkpoints where the solar system took eight — the difference is what the spec pinned down before the first line of code, not the model that wrote it.