Engine: state the body shape the renderer needs, and check real snapshots against it (#24 item 5)
The engine's client renderer reads fixed fields off each body in a snapshot: alive, hp, mate, x, y, angle (see static/engine/scene.js, topdown.js, presence.js, gun.js for snap.me). But nothing states that shape as a contract, and the engine's render tests (src/engine/scene.test.ts and friends) build their own snapshots, so they pass whatever a real game sends. That is how the forge's game template once sent down instead of alive and every enemy drew as a corpse with 145 tests green (apps/forge#11). This engine is copied into that template, so the next game inherits whatever we write here.
Do:
In src/engine/ define the body shape once (a type plus a small runtime check, e.g. bodyProblems(body): string[] or assertBody(body)), covering every field the renderer and presence/gun code actually read. Derive the list by reading those files, not from this issue.
Add a test that builds a REAL snapshot from val's own server code (a headless match, the way the existing tests play matches) and runs every body, and me, through the check. It must fail if val's snapshot drops or renames one of those fields.
Keep src/engine/boundary.test.ts passing: nothing in the engine may import the game.
Document the shape in the engine's header comment, so the next game knows what to send.
Acceptance: renaming alive in val's snapshot code makes the new test fail (prove it in the pull); bun test green; no gameplay or rendering change.
Engine: state the body shape the renderer needs, and check real snapshots against it (#24 item 5)
The engine's client renderer reads fixed fields off each body in a snapshot:
alive,hp,mate,x,y,angle(seestatic/engine/scene.js,topdown.js,presence.js,gun.jsforsnap.me). But nothing states that shape as a contract, and the engine's render tests (src/engine/scene.test.tsand friends) build their own snapshots, so they pass whatever a real game sends. That is how the forge'sgametemplate once sentdowninstead ofaliveand every enemy drew as a corpse with 145 tests green (apps/forge#11). This engine is copied into that template, so the next game inherits whatever we write here.Do:
src/engine/define the body shape once (a type plus a small runtime check, e.g.bodyProblems(body): string[]orassertBody(body)), covering every field the renderer and presence/gun code actually read. Derive the list by reading those files, not from this issue.me, through the check. It must fail if val's snapshot drops or renames one of those fields.src/engine/boundary.test.tspassing: nothing in the engine may import the game.Acceptance: renaming
alivein val's snapshot code makes the new test fail (prove it in the pull);bun testgreen; no gameplay or rendering change.