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):

  1. Workspace setup — a Cargo workspace: pure-Rust core, a WASM frontend, a native egui frontend.
  2. Maze — the 30×28 classic grid, pellets, spawn points, ghost house, loaded from a text map.
  3. Movement & collision — grid-aligned Pac-Man, arrow-key input, wall collision, tunnel wrap.
  4. Ghost AI — Blinky, Pinky, Inky, Clyde with distinct chase, scatter, and frightened modes.
  5. Pellets, scoring, lives — eating, power pellets, score, lives, death, win/lose.
  6. WASM frontend — a canvas renderer (wasm-bindgen + web-sys), keyboard input, the game loop.
  7. Sprites & animation — Pac-Man's four directions + chomp, ghost colours, frightened/eaten states.
  8. 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.

← Play both builds All Workshop projects