Three records in the under-table crate are pressed with whole scenes. E beside
one dives you into its pocket above the booth walls; complete its sound-first
quest to press a STAMP; all three raise the golden slipmat + a permanent bonus
percussion stem. Dust bunnies move in under the table.
- Worlds (Lane W): ACID WAREHOUSE / DUB CHAMBER / DISCO LOFT — sealed themed
pockets, portal rings, exit pads; deterministic, zero light leaks (incl. the
flythrough path), meshes unchanged at 469, build ~760 ms.
- Machines (Lane M): portal dive/exit/safety (membership-based escape catch),
tune-the-303 hold-sweep pedestals, carry-the-charge wobbling spring bridge,
beat-Simon dance floor with glow tiles; stamps store + relay {t:'stamp'}
(default-closed, persisted, join snapshot, fuzzed); golden slipmat; stamps
survive the reset ritual.
- Ambience (Lane S): dust bunnies (wander/flee, zero steady-state allocs),
vinyl-warp portal iris, HUD stamp tray, stamp confetti + golden shimmer.
- Audio (Lane E2): per-world grooves (acid 303 w/ fader-driven bands, dub
feedback-echo + spring, disco pentatonic tiles) over a boothGain
duck-and-handback that can never restore stale state; portal/stamp/golden
SFX; bonus stem.
Post-integration review (2 seam finders, 10 findings, all fixed + verified):
stamp events carry origin (local/remote/replay) so consumers celebrate
proportionately instead of wall-clock guessing — kills phantom join
celebrations, first-person confetti for peers' wins, and audio/visual grace
mismatches; reconnect re-uploads locally-won stamps the server missed;
relay saveState survives disk errors; pocket escape via mined floor counts as
a real exit at any altitude; exit-pad speed gate + dwell stops mid-quest
yank-outs; dive cooldown stops exit/re-dive ping-pong; locked acid bands
need deliberate holds (tap-spam dead); disco foot band excludes jump apex.
Verified: whole-tree typecheck + build clean; per-lane live verification
(27/27 worldgen assertions, relay fuzz, 18-phase audio matrix, fps unchanged);
integrated smoke: dive/exit/safety/stamps/golden + all origin paths live.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9.5 KiB
SIDE B — Lane W handoff (worlds)
Status: complete. Whole-tree npm run typecheck exits 0. All demo
validation green (27/27 lines incl. the new pocket assertions). Verified live
on port 5212 (launch config turncraft-laneC-verify) in both the demo page
and the real game via the cine camera.
Files touched
src/worldgen/worlds/(new) —index.ts(buildWorlds(w, seed)),common.ts(skin/lining/exit-pad toolkit + accent-led map),portalDressing.ts(W1),acid.ts,dub.ts,disco.tssrc/worldgen/buildBooth.ts— additive only: one import + onebuildWorlds(w, WORLD_SEED)call at the end ofbuildBoothsrc/demo/worldgenDemo.ts— pocket assertions, three "Pocket:" exterior view buttons, header notesdocs/SIDEB_W_handoff.md— this file
Nothing else. No src/core/** edits, no other lane's directory, no existing
anchor moved, no new block ids (31 still reserved). Portal-ring code lives in
worlds/portalDressing.ts and is invoked via buildWorlds so the buildBooth
diff stays two lines.
Determinism & budgets
- Deterministic: two full builds byte-identical (asserted headless AND as
a standing demo validation line). All pocket randomness comes from
mulberry32(WORLD_SEED ^ k)streams private to this lane — the main buildBooth rng is never consumed, so every pre-existing booth zone is byte-identical to before this phase. acid/disco/portal dressing are fully index-patterned (zero rng); only dub's embers draw randoms. - Build time: buildBooth alone 19–29 ms in the array-mock (pockets add
~5 ms; 66,834 pocket voxels). Real game boot log across five boots:
booth built+meshed in 760 / 769 / 783 / 913 ms— the 913 outlier was a vite-reload storm in a background-throttled pane while three other lane sessions shared the relay; steady state ~760–780 ms. Budget < 900 ms. ✓ - Chunk meshes: 469 (was 469 pre-SIDE B — the pockets live in ceiling chunks that already existed, so the count is unchanged; disco's glass adds transparent geometry to already-counted chunks). Budget < 700. ✓
- Console: zero errors attributable to worldgen. The only error all
session is a
WrongDocumentErrorpointer-lock rejection fired by the browser-pane sandbox when the start splash is clicked (pre-existing main.tsrequestPointerLockbehaviour inside an embedded pane; does not occur in a normal tab).
W1 — portal dressing at the crate
Per world (accent leds: acid=led_green, dub=led_amber, disco=led_blue):
- Floor ring: flush 1-voxel ring inlaid in the crate floor (y=2, i.e.
portalStand.y − 1) around eachportalStand, radius 3 (16 voxels,d² ∈ [7,11]). Stands: acid (31,3,36), dub (46,3,36), disco (61,3,36). Matches Lane S's bunny keep-out (portalStand ±6). - Disc marquee: 3 accent-led pips riding each portal disc's top rim, at
(discX, 28, 31),(discX, 27, 27),(discX, 27, 35)for discX 31/46/61.
Verified glowing in-game (screenshot: three rings green/amber/blue across the dim crate). No record geometry moved.
W2 — pocket geometry (everything Lane M needs colliders/anchors for)
Common to all three (contract src/core/worlds.ts):
- Shell: 1-voxel
matte_blackskin on all six faces ofpocketMin..pocketMax(y 142 base, y 158 roof). Fully sealed — entry/exit is teleport-only. Interior air y 144..157 (≈14 high). - Themed floor lining at y=143 (=
exitPad.y); feet stand at 144 (=entry.y). Entry voxels verified solid-below + 2-high headroom. - Exit pad: 3×3
rca_goldflush at y=143 centred onexitPad(x±1, z 77..79), centre voxel is the world's accent led. 2-high air above all 9 columns.
ACID WAREHOUSE (x 20..84, z 20..84)
- Knob pedestals (quest M2): three 3×3×3
matte_blackplinths, centres x=52, z=44/52/60 — footprints x 51..53, y 144..146, z {43..45, 51..53, 59..61}; top face y=147; 1-voxelled_greenpip at (52,147,z). Exported:ACID_PEDESTAL_X/Z/TOP_Yfromsrc/worldgen/worlds. - Floor: steel/alu slab concrete with flush rubber seams. Walls:
ply_edgebreeze-blocks with shadow slots. 4 pillars 2×2 at x{33,69}×z{35,67}, floor to ceiling.led_greencable runs: wall drops at x=21, z=38/46/62 (y 144..149) + flush floor inlays snaking to each plinth base (all inlays are walkable floor, no bumps). Strobe rail:strobe_dotat (52,157,z) for z=28..76 step 3.
DUB CHAMBER (x 192..256, z 20..84)
- Reading of "floor drops 4 at x 210..238": the x-flanks are raised shelves (x 193..209 and 239..255, solid y 144..147, top face 148); the centre band x 210..238 stays at floor 144 → a sunken canyon 4 below the shelves, holding entry, bridge, and exit on the x=224 axis. (The shell floor at 142 is inviolable, so the drop is made by raising the sides — entry/exitPad y-values pin the canyon floor to 143/144.)
- Tank pit: floor lining carved to the shell over x 212..236, z 41..62 — pit walk surface y=143, one step below the canyon (always escapable), four below the bridge deck. Two chrome reverb-spring coils inside (helices around (x=217,y=145) and (x=231,y=145), z 43..61, radius 2 — clear of the bridge's x 223..225). Gold catch pad x 223..225, y=143, z 51..53.
- Bridge (your moving deck overlays this): static chrome deck
x 223..225, y=146 (walk surface 147), z 40..63 (3×24 exactly), with a
rca_goldmouth inlay at (224,146,52) — the "feed the spring" E-drop spot, directly over the catch pad. End legs at z=40/63 (y 144..145). Stairs, 1-voxel steps (auto-step): near z=37 (y144), z=38 (y144..145), z=39 (y144..146); far z=64 (y144..145), z=65 (y144). Exported:DUB_BRIDGE,DUB_PIT. - Horn: stacked
speaker_meshrings on the back wall, centre (232, 151) — throat plate flush at z=83, rings flaring at z=82/81/80 to r6;led_amberember at (232,151,82). Exported:DUB_HORN. Deliberately mounted EAST of the exit axis: the exit pad (x 223..225, z 77..79) would otherwise sit between the room and the horn. With the horn at x=232, a charge anchor near (232, 147, 79) is reachable and carryable to the bridge without ever crossing the pad — safe even if you make exit walk-on. If you'd rather the player never gets close, anchor at (232,147,75). - Dressing: vinyl_black everything, ~35
led_amberembers in walls/risers, 2 speaker-mesh stacks per shelf (3×3×3 at x 200..202 & 246..248 tops 150).
DISCO LOFT (x 364..428, z 20..84)
- Dance tiles (quest M2, your standing-on colliders): 4×4 grid of 5×5
flush tiles at y=143, tile centres x {384, 392, 400, 408} ×
z {52, 60, 68, 76} (pitch 8; each tile spans centre±2; 3-voxel parquet
gaps between tiles). Border ring alternates
label_cream/rubberper tile (checker), field is the opposite, centre voxel led_red/led_blue (Lane S lights ondisco_cue). Exported:DISCO_TILE_CX/CZ/Y. The exit pad (x 395..397, z 77..79) sits in the x-gap between tile columns — no overlap. - Mirrorball: chrome/glass checker sphere r≈3 centred (396,152,64) (over the tile grid), chrome chain at (396,156..157,64). Bottom voxel y=149 — 5 clear above heads.
- Dressing: plywood/ply_edge herringbone parquet, plywood walls + ply_edge skirting, 16 vertical wall-wash strips (led_red/led_blue, y 146..151) on all four walls.
Verification performed (all live, port 5212)
Demo (/demo-worldgen.html) — validation 27/27 green, incl. per-world: skin
sealed matte_black (0 breaches — which also proves no emissive/transparent
block anywhere on the skin), entry floor+headroom, exit pad + pip + clear
above, portal ring 16/16 + marquee 3/3, pedestals/bridge/tiles present,
"nothing above y141 outside the pockets (0)", determinism. Build 28.7 ms in
the mock, 0 OOB writes, zero console errors.
Real game (/) screenshots via window.TURNCRAFT_CINE:
- Flythrough keyframes from commit
caac3da— K1 (224,132,26)→(224,60,128), K2 (330,100,60)→(224,66,100), K3 (140,96,60)→(80,81,96): ceiling in frame in K2/K3, zero pocket visibility, zero glow. - Under-pocket ceiling shots (below acid and dub, lights-off angles): pure dark ceiling, no leaks.
- Exterior night, high over the roof from the front: all three pockets read as faint matte-black slabs, zero emission (two angles).
- Interiors of all three pockets (front wall → room): every listed feature visible and correct.
- Crate: the three accent rings glowing round the portal stands.
Notes / friction for the integrator
matte_blackisbreakable: truein the contract registry, so a player could in principle mine a hole in a pocket skin (same as the mixer body). Lane M's out-of-pocket safety teleport (M1) is the net; if we ever want skins unmineable that's a contract decision, not mine.- Dub's "floor drops 4" is implemented as raised side shelves (see above) — the contract's entry/exitPad y-values make a literal 4-deep dig impossible without piercing the shell. Flagging per CONTRACTS §1 rather than bending the contract.
- The pocket skins rest directly on the booth ceiling slab (y 140..141), so they are strictly invisible from inside the booth; the exterior view only exists for cine/debug cameras.
worldgen/index.tswas NOT edited (not in this phase's sanctioned list);buildWorldsis internal tobuildBooth. Demo imports feature anchors fromsrc/worldgen/worldsdirectly.- Verified while three other lane sessions were live on the same tree/relay (their WIP caused periodic vite reloads; boot numbers above include that noise). One environmental console error only — see Budgets.