# Puddled Paper 2.5D — critic gate

Workers mark sections `READY` when done. Critic marks `PASS` / `FAIL` with notes.
Do not remove this file; update status lines only.

## Status

- scaffold: READY
- sprites: READY
- engine: READY
- critic: PASS

## Scaffold smoke

```bash
php scripts/php/test_game_scaffold.php
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8086/tool/game/
# expect 200; page includes #game-root, suite.css, game.css, main.js
# browser console: "PuddledGame engine ready"
# #game-root[data-engine-ready="1"] + canvas present
```

URL assumptions: local Docker app on `http://127.0.0.1:8086`; static via `url.static`; game at `/tool/game/`; sprites under `/static/tool/game/sprites/` (or configured static host + `tool/game/sprites/`).

## Acceptance (all required)

1. Isolated modules under `src/static/tool/game/js/` — no god-file; ES modules preferred.
2. New tool page at `/tool/game/` wired like other tools (controller, view, template, nav, index).
3. SVG path recolor → PNG pipeline for role themes (bush / treasure / character / monster).
4. Realistic Paper Mario–style 2.5D: orthographic or fixed perspective, billboard/plane sprites, ground plane, depth sort, arrow-key move, interact/fight.
5. Uses puddled asset art (from `var/asset-files/*/asset.svg` or baked copies under `src/static/tool/game/sprites/`).
6. Tests or smoke script for non-UI logic (theme colors, entity roles, collision helpers).
7. Minimal coupling to PHP beyond bootstrapping `settings` / asset URLs.

## Critic notes

### 2026-08-05T20:39:08Z — critic: FAIL (pass 1)

Harsh review of current tree. **Overall: critic FAIL.** No worker section may be marked READY.

#### Evidence inventory
- Present: `controller/tool/game.php`, `view/tool/game.php`, `template/tool/game.html`, `css/game.css`, `js/main.js` (stub), `_nav.html` Game link, `PuddledChrome::$game_url`, empty `sprites/.gitkeep`, `CRITIC.md`.
- Absent: any ES modules beyond stub, Three.js (or equivalent) scene, sprite PNGs/SVGs, theme pipeline script, tests/smoke, index.html Game entry, interact/fight logic.

#### Acceptance checklist

1. **Modules / isolation — FAIL**
   - `src/static/tool/game/js/main.js` is a 16-line boot stub that only `console.log`s settings. Required fix: split into ES modules (`scene.js`, `input.js`, `entities.js`, `combat.js`, `theme.js`, etc.); keep `main.js` as thin bootstrap only.

2. **Page wiring — PASS**
   - Evidence: `controller/tool/game.php`, `view/tool/game.php`, `template/tool/game.html`, `_nav.html` Game link, `index.html` Game link, `PuddledChrome` `game_url`, CSS stage. Settings boot via `_head.html` `settings_json`.

3. **SVG theme pipeline — FAIL**
   - No script/tool that recolors SVG paths by role (`bush`/`treasure`/`character`/`monster`) and bakes PNGs. `roleThemes` hexes exist only as JSON in `ControllerToolGame::getData`. Required fix: add a bake script (e.g. under `scripts/` or `src/static/tool/game/`) that reads puddled SVGs, applies role colors, writes themed PNGs into `sprites/`.

4. **2.5D realism — FAIL**
   - HUD CSS paints a fake sky/ground gradient; `#game-root` never gets a canvas or scene. No orthographic/fixed camera, billboards, ground plane, depth sort, arrow-key movement, or interact/fight. Required fix: implement Paper Mario–style 2.5D engine (Three.js or equivalent) with those systems; wire Space interact + fight.

5. **Puddled asset art — FAIL**
   - `src/static/tool/game/sprites/` contains only `.gitkeep`. Placeholder chrome is not art. Required fix: copy/bake real `var/asset-files/*/asset.svg` (or equivalents) into role-themed sprites and load them in the engine.

6. **Tests — FAIL**
   - Zero test or smoke files under `src/static/tool/game/` (or elsewhere for game logic). Required fix: add tests for theme color mapping, entity roles, and collision helpers (node/phpunit/pytest — whatever matches repo norms for pure JS/PHP helpers).

7. **PHP coupling — PASS (so far)**
   - Controller correctly bootstraps `settings` (`assetBase`, `roleThemes`) and uses `PuddledChrome::apply`. Keep it that way; do not shove game logic into PHP.

#### Worker status overrides
Any premature `READY` is rejected. Current statuses set to FAIL reasons above. Engine/sprites/scaffold workers must deliver real artifacts before re-requesting critic PASS.

### 2026-08-05T20:41:15Z — critic: FAIL (pass 2)

Progress since pass 1, but **still critic FAIL**. Modules appeared; game is not playable.

#### Evidence inventory (delta)
- New modules: `scene/World.js`, `entities/{BillboardSprite,Player,Prop}.js`, `input/Keys.js`, `assets/{svgTheme,spriteManifest}.js`, `utils/{collision,roles}.js`, `systems/{Interact,DepthSort}.js`, `combat/Encounter.js`.
- Pipeline: `scripts/python3/game/bake_sprites.py`, `scripts/game-bake-sprites.sh`, tests `svgTheme.test.js`, `test_bake_sprites.py`, `test_game_scaffold.php`.
- Sprites dir has role folders but only `sprites/bush/bush-1200.svg` (no PNGs; other roles empty).
- `main.js` **unchanged stub** — does not import World/Player/Keys/Interact/Encounter.
- `cdn-importmap.json` exists but **not** injected into `template/tool/game.html` (Three.js imports would fail).

#### Acceptance checklist

1. **Modules / isolation — PARTIAL → treat as FAIL until bootstrapped**
   - Good split across folders; `main.js` is still a god-less stub that never loads them. Required fix: wire ES module game loop in `main.js` (create World, spawn props, Keys, Interact, Encounter, RAF); add `<script type="importmap">` from `cdn-importmap.json` in `game.html`.

2. **Page wiring — PASS** (unchanged).

3. **SVG theme pipeline — PARTIAL FAIL**
   - `bake_sprites.py` + `svgTheme.js` implement recolor; bake has barely started (1 SVG). Required fix: finish bake for all STARTER roles → themed PNG+SVG under `sprites/{role}/`; regenerate `spriteManifest.js` with real URLs (not flat `player.png` placeholders).

4. **2.5D realism — FAIL**
   - Building blocks exist (fixed camera, ground, billboards, depth sort, arrow keys, fight UI) but nothing runs without `main.js` + importmap. Required fix: connect systems into a live loop; prove arrow move + Space interact/fight in browser.

5. **Puddled asset art — FAIL**
   - Still placeholders via `makePlaceholderDataUrl`; one bush SVG only. Required fix: complete bake from `var/asset-files` and load baked PNGs.

6. **Tests — PARTIAL PASS (theme only)**
   - `svgTheme.test.js` + Python bake tests exist. Missing: collision + roles (+ optionally Interact radius) unit tests. Required fix: add `collision`/`roles` smoke tests under `js/utils` or `js/test`.

7. **PHP coupling — PASS**.

#### Worker status
- scaffold: READY (keep)
- sprites: FAIL (incomplete bake + placeholder manifest)
- engine: FAIL (`main.js` unwired; importmap missing; combat unused)
- critic: FAIL

### 2026-08-05T20:42:18Z — critic: FAIL (pass 3)

Delta: real PNGs + wired `main.js` + importmap in `game.html` + `ASSET_MAP.md`. **Still critic FAIL** — not playable, ASSET_MAP ignored, tests incomplete.

#### Blocking defects (must fix)

1. **Broken ES imports — engine dead on load** (`js/assets/spriteManifest.js`)
   - Bake regenerated manifest as data-only (`spriteManifest` export). `main.js` and `BillboardSprite.js` still import `spriteUrlForRole` / `makePlaceholderDataUrl`, which **no longer exist**. Required fix: keep helpers in a separate module (e.g. `spriteUrls.js`) OR append helpers after generated data; `spriteUrlForRole` must resolve role → first baked PNG under `assetBase` (or absolute `spriteManifest` URL).

2. **ASSET_MAP not used — role art wrong** (`scripts/python3/game/bake_sprites.py` STARTER vs `ASSET_MAP.md`)
   - Overlap with map: bush `1200` only. Cross-contamination: `1250` baked as character (map: monster), `1251` as treasure (map: monster), `1248` as monster (map: character), `1232` as player (map: bush). Required fix: rebase STARTER on ASSET_MAP local IDs (`1200`,`1232` bush; `1203` treasure; `1248` character; `1250`,`1251` monster; player `379`/`596` or best local character stand-in), re-bake, regenerate manifest.

3. **Tests incomplete** (`js/test/` empty)
   - Theme + bake tests pass; no collision/roles unit tests. Required fix: add node smoke tests for `utils/collision.js` + `utils/roles.js`.

4. **Encounter styling missing** (`css/game.css`)
   - `Encounter.js` mounts `.game-encounter*` DOM with zero CSS. Required fix: style battle overlay so fight UX is usable (not invisible/unstyled junk).

5. **Scaffold smoke stale** (`scripts/php/test_game_scaffold.php`)
   - Still expects stub `"PuddledGame boot"` log; fails now that engine logs `"PuddledGame engine ready"`. Required fix: update assertion.

#### Acceptance checklist (this tick)

1. Modules — PASS (isolated; main is thin orchestrator ~204 lines).
2. Page wiring — PASS (importmap now in `game.html`).
3. SVG→PNG pipeline — PARTIAL FAIL (pipeline works; wrong IDs vs ASSET_MAP).
4. 2.5D playable — FAIL (code path exists but import crash prevents play).
5. Puddled assets — FAIL until ASSET_MAP-aligned bake loads via working URL helper.
6. Tests — FAIL (missing collision/roles).
7. PHP coupling — PASS.

#### Worker status overrides
- scaffold: READY
- sprites: FAIL (ASSET_MAP mismatch + broken helper export)
- engine: FAIL (broken imports; no collision/roles tests; encounter CSS)
- critic: FAIL

Do **not** mark READY until: (a) helpers restore + game boots, (b) bake uses ASSET_MAP IDs, (c) collision+roles tests green, (d) encounter CSS present.

### 2026-08-05T20:44:44Z — critic: PASS (pass 4)

**Overall: critic PASS.** Loop killed. All acceptance criteria met with evidence.

#### Acceptance evidence

1. **Modules / isolation — PASS**
   - ES modules under `js/{scene,entities,input,systems,combat,assets,utils}/`; `main.js` (~212 lines) is thin orchestrator only.

2. **Page wiring — PASS**
   - `controller/tool/game.php`, `view/tool/game.php`, `template/tool/game.html` (importmap + module), `_nav.html` Game link, `index.html` Game link, `PuddledChrome` `game_url`. HTTP 200 at `/tool/game/`. Scaffold PHP smoke green after engine-ready assert update.

3. **SVG→PNG theme pipeline — PASS**
   - `scripts/python3/game/bake_sprites.py` STARTER mirrors `ASSET_MAP.md`; `svgTheme.js` recolor; themed SVGs contain role palette fills (e.g. bush `#95d5b2`, monster `#ff8fa3`).

4. **2.5D playable — PASS**
   - `World.js` fixed chase camera + ground plane; `BillboardSprite.js` upright planes + depth sort; `Keys.js` arrows/WASD + Space/E; `Interact.js` + `Encounter.js` fight/collect/talk/peek.
   - Browser proof (`http://127.0.0.1:8086/tool/game/`): `engineReady=1`, WebGL canvas present, billboarded puddled sprites on path, HP HUD, interact hint. Screenshot verified Paper Mario–ish stage.

5. **Puddled ASSET_MAP art — PASS**
   - Baked PNGs match map IDs: bush `1200,1232,999,1097`; treasure `904,1082,1203`; character `1248,379,596`; monster `1250,1251,62,1072`; player `379,596`. Manifest + `spriteResolve.js` load them (not canvas placeholders as primary path).

6. **Tests — PASS**
   - `js/assets/svgTheme.test.js` (21 pass); `js/test/helpers.test.js` collision+roles+resolve (22 pass); `scripts/python3/game/test_bake_sprites.py` OK; `scripts/php/test_game_scaffold.php` OK.

7. **PHP coupling — PASS**
   - Controller bootstraps `settings` only; game logic stays in JS.

#### Residual (non-blocking)
- Some S3-sourced PNGs retain opaque black/white boxes (alpha bake quality). Still real puddled assets and playable; improve raster alpha later if desired.

#### Worker status
- scaffold: READY
- sprites: READY
- engine: READY
- critic: PASS
