Field Notes · kept as written, during the work

Maze Muncher — The Build Log

The milestone status reports kept during the build — including the playtest round that found the wisp-eyes bug, and the fixes as they were reported to the lead.

Back to the guide: /tutorials/maze-muncher · These are the status reports written during the build, kept as filed — milestone by milestone, bugs included.

_Last updated: 2026-08-29_

Current milestone: M5 — Maze pack (in progress, branch feat/maze-pack)

Lead: main (maze-pack project). Sibling: pm-game (polish), via lead-a. Spec: docs/specs/maze-pack.md. Ship gate: node tools/maze-qa.mjs.

Status report to lead-a — playtest fixes (2026-08-29, after delivery)

Tommy playtested; three findings, all fixed on feat/maze-pack (249/249 tests, 21/21 gate). NOTE for pm-game: these touch files outside the maze-pack ownership map (src/logic/wisp.js, modes.js, entities/wisps.js, engine/input.js, main.js, public/index.html) — done at the user's direct request; please integrate rather than re-implement.

  • BUG (pre-existing, not maze-pack specific): eaten wisps stayed eyes forever, bouncing on one track. Cause: chooseTurn's one-step greedy rule can't route around a wall block to the den door. Fix: eyes now follow a memoized BFS distance map to home (homeDistances in wisp.js; chase/scatter behavior unchanged). Regression test tests/integration/eyes-return.test.js samples corridor tiles in all 21 mazes — it failed on every maze including Lattice before the fix.
  • Difficulty: early levels eased via level-aware tuning in modes.js — frightened 10 s (L1) / 8 s (L2) / 6 s (L3-4) / shrinking to 2 s; den-release thresholds x2 (L1), x1.5 (L2) with failsafe 8 s / 6 s. createModeState() / createDenReleaseState(rng) without a level keep the base numbers (backward compatible; existing tests untouched). The 80:64 speed ratio was NOT touched (spec: load-bearing).
  • Pause / restart: P or Esc pauses, R or Enter restarts (input.js action callback; main.js paused phase + restartGame()).

Status report to lead-a — DELIVERED (2026-08-29)

Branch feat/maze-pack is complete and ready for pm-game integration.

  • 20 new original mazes (m02–m21) + maze 1 = 21 levels, rotating via mazeForLevel(level); each with its own palette. Generated deterministically (node tools/maze-gen.mjs --seed 20260829 --count 20).
  • Extra life every 10,000 points (src/logic/lives.js, wired through a single addScore() in main.js; fires for pellets, power, wisps, fruit).
  • Gate: node tools/maze-qa.mjs 21/21 PASS; npm test 225/225 (99 base + 8 lives + 21 per-maze gate + 84 per-maze sims + validator self-tests + contract tests). Reviewer pass: no Critical findings; both Suggestions addressed (legacy carve-out reserved for m01 and documented).
  • No changes to src/levels/parse.js or the maze format. No plan-approval requests were needed.
  • For pm-game (owner of src/entities): src/entities/fruit.js's FRUIT_SPAWN_TILE default and its comment still describe maze 1's (14,13); main.js now passes spawnTile: maze.wispSpawns['1'] so the default is dead code. Suggest updating the comment/default when you next touch fruit.js — we did not edit it (frozen for this project).
  • Integration note: main.js diff is limited to game.maze per level, addScore(), the fruit spawnTile arg, canvas sizing from 28×31 constants, and the READY overlay showing the maze name.

Status report to lead-a — progress (2026-08-29, later)

  • Merged into feat/maze-pack: wiring (per-level maze rotation, palette rendering, extra life every 10,000 pts — src/logic/lives.js + 8 tests) and mazes (tools/maze-gen.mjs, seeded/deterministic; 20 generated mazes in src/levels/pack-generated.js, spread into MAZE_PACK after maze 1).
  • Gate: node tools/maze-qa.mjs → 21/21 PASS. Den rows span 5–22 (upper / middle / lower bands), 7 mazes have two tunnel rows, 224–343 pellets each, minimum pairwise wall distance 124 cells (rule: ≥ 80).
  • npm test: 107/107 green on the merged branch.
  • Incident: the mazes agent stalled one line short of done (missing import { GENERATED_MAZES } in mazes.js); main finished it and also moved two palette hues out of the lime band. No format/parse.js changes.
  • Pending: qa's gate tests + per-maze sims, then a final gate run on the merged tree and a reviewer pass. Then ready for pm-game integration.

Status report to lead-a — kickoff (2026-08-29)

  • Branch feat/maze-pack created from feat/m2-first-wisp (99/99 tests green at the base).
  • Landed the shared contract before fan-out: spec, the QA validator (parse · symmetry · 1-2 tunnel rows · pen membership · connectivity · no dead ends · one-tile corridors · pellet counts · distinctness ≥ 80 wall cells), and the backward-compatible MAZE_PACK export (LEVEL_1/MAZES unchanged; mazeForLevel(level) added).
  • Team running in parallel worktrees: mazes (generator + 20 mazes + palettes), wiring (per-level maze rotation, palette rendering, extra life every 10,000 pts via pure src/logic/lives.js), qa (gate tests + per-maze headless sims).
  • No parse.js / maze-format changes planned or permitted without plan approval; none requested so far.
  • Coordination note for pm-game: main.js changes are limited to (a) game.maze per level instead of a module-level maze const, (b) an addScore() helper for the extra-life rule, (c) passing the fruit spawn tile from the maze. FRUIT_SPAWN_TILE in src/entities/fruit.js is maze-1-specific; we work around it via spawnFruit's existing spawnTile option rather than editing entities.
  • Blockers: none. lead-a / pm-game sessions not reachable on this machine at kickoff; this file is the report of record until they are.

Earlier milestones

  • M1 scaffold, M2 first wisp, M3 tuning/spec, M4 pack: complete on feat/m2-first-wisp (99 tests).

← Back to the guide