destroyulator/LANES/LANE4-integration.md
Monster Robot Party 1d282d4b3b LANE4 spec: integrate Lane 2's fractured props into game/ + web/, pointer-lock fallback
Review of the three lanes (2026-07-14): all shipped and verified — Lane 1 smoke test
clean, Lane 2's 16 props (intact+fractured) live on 3GOD with the chunk_* contract,
Lane 3 play-tested via its ?debug handle (smash, rack cascade, record ritual, debris
pool all work). LANE4 closes the integration gap the parallel run left open, plus two
review findings: record.fractured.glb 404 spam and no pointer-lock fallback in
embedded browsers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 21:48:17 +10:00

72 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LANE 4 — Integration: Lane 2's fractured props into both front doors
**Owns:** `game/` AND `web/` (run as ONE session, after Lanes 13 are merged — they are).
**For:** an Opus 4.8 session. **Context:** all three original lanes shipped and were
review-verified 2026-07-14 (Fable). This lane closes the loop they couldn't: Lanes 1 & 3
finished before Lane 2's batch landed, so neither consumer uses the new assets yet.
## What Lane 2 delivered (live now)
All 16 Destroyulator props on the 3GOD shelf as `<slug>.glb` + `<slug>.fractured.glb`
(32 files, verified `chunk_00…chunk_NN` contract): office-printer (the boss), office-desk,
crt-monitor, desk-phone, filing-cabinet, water-cooler, office-chair, fluorescent-light,
coffee-mug, potted-plant, wall-clock, cardboard-box, turntable, amp-speaker, cash-register,
wall-shelf. Fetch: `https://digalot.fyi/3god/a/<file>` (read is public; never write from
game/web code). Local copies also in `~/Documents/meshgod/assets3d/destroyulator/`
(content-hashed names — the depot names are the clean slugs).
## Deliverables
### A. Godot (`game/`) — fractured shatter + the printer boss
1. Pull chosen GLBs into `game/assets/store/` yourself (scope rule: this lane copies, e.g.
`curl -O https://digalot.fyi/3god/a/office-printer.glb` + its `.fractured.glb`). Start
with: office-printer, crt-monitor, filing-cabinet, water-cooler, cardboard-box, turntable.
2. Extend `Smashable.shatter()` to prefer a pre-fractured sibling: if the piece was built
from `<name>.glb` and `<name>.fractured.glb` exists, on smash hide/free the intact body
and spawn each `chunk_*` as a `RigidBody3D` (vinyl/glass brittle rules still apply) that
inherits the parent's velocity + gets the impulse. Keep chunks in `debris` group so HUD +
`Juice` keep working; despawn like existing shards. Fall back to the current primitive
shards when no fractured sibling exists.
3. Place the new props in `Main` — the **printer on a desk as the level boss** (bigger
health/impulse threshold, extra juice on death), others scattered as furniture.
4. **Remember the class-cache gotcha:** after adding any `class_name` script run
`--editor --quit` once before the headless test.
### B. Web (`web/`) — catalog the batch + kill the 404 spam
1. Add all 16 slugs to `props.js` CATALOG (`depot: '<slug>.glb'`, material/kind per prop —
printer/filing-cabinet/water-cooler = steel-ish, desk/turntable/wall-shelf = wood,
crt-monitor = glass, cardboard-box = cardboard, coffee-mug = glass/ceramic voice,
potted-plant = wood/soft). `loadFractured()` already handles the `.fractured.glb` swap —
catalog entries are all it needs.
2. Mirror the printer + 23 heroes into `web/assets/` (offline fallback like the others).
3. Place the printer in the room as the web boss too; a couple of desks/monitors for set
dressing. Keep total bodies modest — check it still holds ~60fps.
4. `record.fractured.glb` currently 404s on every record spawn (fetch not cached).
Fix both ends: cache the negative result in `loadFractured()` (one miss per id, not per
spawn), AND generate the real thing — run meshgod's fracture CLI on the existing store
GLBs (`python3 -m meshgod.fracture <in.glb> --chunks 8 --out …` from `~/Documents/meshgod`,
no meshgod code changes) for record/crate/rack, push to 3GOD via `scripts/push_3god.py`
(tailnet origin, see that script's header), and mirror into `web/assets/` + `game/assets/store/`.
### C. Web — pointer-lock fallback (shareability bug, found in review)
In embedded/iframe contexts the Pointer Lock API is unavailable
(`THREE.PointerLockControls: Unable to use Pointer Lock API`) and the toy dead-ends on the
title overlay. Add a fallback: if the lock request fails, enter a **drag-to-look** mode
(mousedown+move rotates, click still smashes, overlay dismisses anyway). The `?debug`
handle in `main.js` already proves the sim runs fine without lock — this is just input.
## Acceptance
- Godot: headless smoke test still clean (`--quit-after 180`, zero SCRIPT ERROR/Parse Error,
the two "material is null" lines are benign). In-scene: smashing the printer spawns its
16 GLB chunks, not primitive shards.
- Web: `http://localhost:8099/?debug``DESTROY.unpause()`, teleport to the printer,
`aimSmash()` returns its kind, chunks (not generative shards) spawn, `counts()` shows
debris then drains. No `record.fractured.glb` 404s after first load. Drag-look works with
pointer lock unavailable.
- Commit + push per existing conventions (monorepo `origin main`; any meshgod-side fracture
outputs need no meshgod commit unless a manifest changed).
## Out of scope
- 3GOD hardening (open-mode + `/api/fetch` SSRF) — still the owner's call, tracked in PLAN.md.
- New game modes / balance (combo counting is intentionally generous for now).