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

4.7 KiB
Raw Blame History

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/?debugDESTROY.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).