- src/main.ts: full wiring per docs/INTEGRATION.md (renderer/world/booth/ chunks/machines/player/interaction/audio/fx/hud + fixed-step loop), QuestPositions adapter (Lane C nested -> Lane D flat), attachPlayer step, pointer-lock-gated input, debug handle for smoke tests. - core/constants: Y_RECORD_TOP 85 -> 81 (record was an unclimbable 5-voxel cliff; now 1 proud of the plinth, auto-steppable) + PLATTER.wellDepth. - machines/platter: body + collider now fill Lane C's well down to y=74. - fx/layout: VU sprites aligned to Lane C's physical LED towers. - interact: per-material break times (dust 0.12s) so the crossfader jam isn't a 96-second mine. - docs/INTEGRATION_NOTES.md: every glue decision + live verification results (120 fps, ride/mine/quest/win all green, zero console errors). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.7 KiB
4.7 KiB
TURNCRAFT — Integration Notes (what the integrator changed and why)
Integration performed per INTEGRATION.md after all five lanes landed. Every cross-lane glue decision is listed here.
Contract changes (core is integrator-owned)
Y_RECORD_TOP: 85 → 81 (src/core/constants.ts). At 85 the vinyl surface was a 5-voxel cliff above the plinth (jump height ≈ 1.3 — the record was unreachable), and Lane D's platter stack floated on the plinth top, ignoring the 6-deep well Lane C carved. Now the record sits 1 proud of the plinth (auto-steppable, like a real 1200) and the platter body fills the well. Everything downstream (tonearm heights, audio panner positions, FX rim sparkle, D's quest defaults) derives from the constant and moved automatically. AddedPLATTER.wellDepth = 6alongside.- Lane B's requested
velocityAtout-param overload was NOT taken: Lane D already returns a reused per-collider scratch array (no allocation), which satisfies the hot-path concern with no contract change.
Cross-lane glue (in src/main.ts)
- QuestPositions adapter: Lane C's nested
QUEST_POSis mapped to Lane D's flatQuestPositions; the crossfader slot span is derived from C'sMIXERanchors (centerX ± halfLen, faceTopY−depth+1 … faceTopY−1, z −1…+2) so D's slide gate covers exactly the tram volume C carved. machines.attachPlayer(player)called after the player is built (Lane D's added step "6.5") — enables walk-push faders and walk-press plates.- Hotbar: D's
Hotbarstructurally satisfies E'sHotbarModel; passed directly asgetHotbar, withhotbar.onChange(() => hud.refreshHotbar()). - Input wiring: LMB hold = mine, RMB = place, E = use, 1–9/wheel = hotbar,
all gated on pointer lock (matching Lane B's own key gating). Start splash
click →
audio.init()+ pointer lock; resume click → re-lock only. - Fixed-step loop: machines → player → interaction → fx at
FIXED_DT, withMAX_SUBSTEPScatch-up and an accumulator clamp so a backgrounded tab doesn't spiral;audio.updateListener+chunks.update()+ render per frame. - Debug handle
window.TURNCRAFT(world/player/machines/quest/hotbar/audio/ fx/hud/chunks/interaction) — used by the smoke tests, harmless in play.
Lane-file adjustments (documented per CONTRACTS "integrator resolves")
src/machines/platter.ts— platter body now spans the well floor to 1 below the vinyl (visuals) and its collider spans well floor →Y_RECORD_TOPso the spinning body also pushes the player out of the well's 2-voxel gap ring (which is now a real, intentional fall-in hazard).src/fx/layout.ts— VU overlay sprites aligned to Lane C's physical LED towers (x = mixer minX+18 / maxX−18, 12 segments, in front of the open casing face) per Lane E's friction note #5.src/interact/interaction.ts— per-material break times (soft 0.12 s, glass 0.25 s, default 0.4 s). The crossfader jam is ~240 dust blocks; at a flat 0.4 s it was a 96-second chore.docs/DESIGN.md— elevation table updated for the Y_RECORD_TOP change.
Deviations accepted as-is
- 45 speed available pre-win (D's reading; DESIGN's "45 unlocked at win"
treated as flavor).
Platter.unlocked45exists if we ever gate it. fader_crossdoes not drive audio (E maps pitch + channel digits only); crossfader is quest/physical-only in v1.- Both deck pitch faders drive the one global mix pitch (E has a single transport; fine until per-deck stems exist).
- Tonearm pedestal (C's voxels) vs D's arm pivot are ~11 voxels apart — cosmetic misalignment, queued for polish, gameplay unaffected.
Verified at integration (live browser, real code paths)
- Boot: booth builds + meshes in ~670 ms dev / 46 modules build in 0.5 s; fillBox fast path ENABLED; 120 fps; zero console errors all session.
- Ride: standing on the record at 33 → clean circle, r drift 20.00→20.02 over 4 s, y = 81 exactly, spin-up ramp visible; at 45 near the rim → 10.7 v/s (= ω×r), jump lands back on the moving disc.
- Mining: real DDA aim → dust breaks into hotbar; crossfader stays gated while dust remains.
- Quest chain: stems stack 0→5 per
signal:repair, power switch arms exactly after the 4th repair, real button press →game:winonce, both platters auto-start, HUD banner + tracker 5/5, AudioContext running. - The platter-well gap ring behaves as a trench (collider pushes, no clipping).
Not yet done (deploy phase)
Run /ship-check before exposing anything publicly; deploy per deploy-map
conventions (static dist/ — 156 KB gzipped). Cloudflare/host wiring is a
separate step, to be done with the token holder present.