# Lane C — World Builder · HANDOFF **Status: complete.** `npm run typecheck` clean, demo runs with no console errors, build is deterministic and fully validated (see below). --- ## Glow-Up G4 — worldgen density pass (2026-07-14) Implemented the `src/worldgen/**` slice of `docs/briefs/GLOWUP_ART.md` (task G4). The atlas (G1), bloom (G2), decals (G3) and record texture (G5) are engine/fx work and are NOT in this lane — left for their sessions. **Files touched (this pass):** `src/worldgen/buildBooth.ts`, `src/demo/worldgenDemo.ts`. Nothing else. **Merge points (shared with the Workshop session):** only `src/worldgen/buildBooth.ts` (main.ts is untouched here). My edits are confined to `buildMixer`, `buildUnderTable` (+ new `pagoda`/`buildPcbDetail`), and the deck-vent loop — all disjoint from the Workshop brief's *Deck A pedestal* "workbench dressing", so a merge is clean. **What it adds (additive; every pre-existing zone stays byte-identical):** - **Mixer face** — dense mushroom knobs (1×1 stem + 2×2 cap, mixed heights, 6 rows × 3 cols × 4 channels, club-mixer palette) replacing the sparse specks; flush rubber **panel-seam grooves** sectioning the four channels; amber/green **LED depth pips** at each fader-alley floor and flanking; an amber glow behind each speaker-mesh vent. - **PCB Depths** — walk-under **IC-chip pagodas** (matte_black slabs on solder pin-legs, stacked tiers, copper pin-1 dot, green status LED), **ribbon-cable walls** (deck rooms), extra copper trace inlays. Kept ≥15 voxels clear of every quest pickup. - **Deck vents** — an amber pip at each shaft bottom so the drop reads as deep. **Determinism:** the mixer detail is index-based (no `rng()`), and `buildPcbDetail` uses its OWN seed (`WORLD_SEED ^ 0x9e3779b1`), so the main PRNG stream is untouched and all other zones are identical. Two full builds are byte-identical (verified headless). **Anchors:** no `LAYOUT`/`QUEST_POS` value moved. All 8 quest anchors still land on the correct block (re-verified). Build 21–30 ms (« 800 ms budget). Chunk count unchanged. **One demo fix:** the concept-art pass added an intentional shallow well step-ring (outside `PLATTER.radius`); my old "well empty" assertion checked the full well and went red. Retitled to **"platter footprint clear"** and scoped to `PLATTER.radius` — the region Lane D's platter actually needs. Green again. **Note (not mine to fix):** at this checkpoint the shared tree briefly failed global `tsc` on the Workshop session's in-progress `src/audio/testSignal.ts` (a `Float32Array` generic mismatch); it cleared on their next save. My files typecheck clean in isolation. --- ## Public API surface (import from `src/worldgen`) ```ts buildBooth(world: IVoxelWorld): void // writes the ENTIRE static diorama buildShell, buildDeckA, buildDeckB, buildMixer, buildCableCanyon, buildPatchBay, buildUnderTable // individually testable sub-builders SPAWN: Vec3 // deck A plinth top, faces the mixer SPAWN_LOOK: Vec3 // suggested look-at (mixer face centre) WORLD_SEED = 1210 // fixed seed → identical booth every run QUEST_POS: QuestPositions // {stylus,rca,crossfader,fuse,power} for Lane D QUEST_REACH_POINTS, hasAdjacentAir(w, p) // reachability helpers (used by the demo) DECK_A, DECK_B, MIXER, UNDER, PATCH, RCA_SOCKET, RCA_PLUG // LAYOUT-derived anchors ``` ## What's done Every zone in DESIGN §4 is built and visually confirmed in `demo-worldgen.html`: shell + tabletop (front lip, vent slots, crate hatch + stair), both steel-grey plinths (feet, alu border, **empty platter well** + chrome spindle stub, start/stop + 33/45 recesses, pitch canyon w/ green detent, tonearm base pedestal, strobe lamp), Deck B dust drifts + half-open glass dust cover, the mixer massif (body, speaker-mesh climb vents, 4 channel strips = knob-stem grids + **empty fader alleys**, crossfader tram with the dust-jam plug, two VU towers, power-switch recess, fuse chimney), the cable canyon (5 splined RCA/power cables to the patch bay + the quest cable ending short with a loose gold plug + power strip), the patch-bay wall (alu panel, 2×6 gold socket grid, the **empty quest socket** with red blink, two doorway rooms w/ copper busbars + blue glow), and the PCB Depths (green board floors, copper traces, capacitor pillars, solder stalagmites, sparse LEDs, the fuse box with a blown fuse, the parts bin holding the fresh-fuse + stylus pickups, and the record crate of blue/black vinyl slabs on edge with a leaning-slab ramp). ## What's intentionally NOT built (yours, Lane D) The moving parts sit in the sockets I left for them: the **rotating platter/record** (the empty circular well, radius `PLATTER.radius+2`, 6 deep, spindle stub at bottom), the **tonearm arm + headshell** (base pedestal + empty socket anchor), the **fader caps/sleds** (empty alley slots + crossfader tram), and the **buttons/switches** (start/stop, 33/45, power — all left as recesses). Read `QUEST_POS` for exact voxels. ## Quest anchor convention (important for Lane D) Each `QUEST_POS` voxel is a **reachable interaction anchor** (has an adjacent air voxel — validated). Semantics per node: - `stylus.socket` — empty voxel on the Deck A tonearm pedestal; drop the stylus here. - `stylus.pickup` — the chrome stylus block in the parts bin (blue-spotlit). - `rca.socket` — empty gold ring on the patch-bay wall face (air; push the plug in). - `rca.plug` — the loose gold plug lying on the canyon floor (top is open air). - `crossfader.jam` — **top-centre** of the dust plug in the tram (mine downward). - `fuse.box` — the blown fuse (rubber block, chrome caps) in the wall fuse box. - `fuse.pickup` — the fresh fuse (glass + chrome caps) in the parts bin. - `power.switch` — recess on the mixer rear top (dark until the other four are done). ## Validation (headless + in-demo + cross-lane, all green) build 14 ms (< 500) · deterministic (two runs byte-identical) · **0** OOB writes · both platter wells empty · spawn on solid steel with headroom · **8/8** quest points reachable · fuse/stylus anchors land on the intended block · record crate populated · 29/30 non-air block types · ~4.5 M non-air voxels (24.6% fill). **Cross-lane smoke test** (buildBooth against Lane A's real `VoxelWorld`, not a mock): `fillBox` fast path ENABLED · 30.7 ms build · all acceptance checks still pass. ## Post-review fixes (adversarial multi-agent pass, all verified) - **[HIGH]** record crate placed **zero** vinyl slabs (footprint collapsed to ~2 voxels because it was bounded by `deckA.minX`); re-anchored to the open under-ledge volume in front of Deck A — now 8–9 records on edge. Added a regression guard. - **[MED]** `QUEST_POS.fuse.box` pointed at the alu frame, one voxel off the fuse; the blown fuse now sits **exactly** at that anchor (frame moved behind). Guarded. - **[MED]** VU-tower LED ladders were sealed inside a closed casing; the front (DJ-facing) face is now open so the meters read. - **[LOW]** added the "resistor beams" the brief lists for the PCB rooms. - **[LOW]** the demo's "Record Crate" teleport aimed at `x=12` (inside the left plywood wall) and at the crate's old location; re-aimed at the crate's real centre. - (A `fillBox` doc-comment nit was a false positive; tightened it regardless.) ## Contract friction / notes for the integrator 1. **Mixer height.** The brief says "tabletop → `topY`+40", but `constants.ts` (`mixer.topY = 67`, "27 voxels tall") and DESIGN §3 both put the mixer face plate TOP surface at `topY = 67`. I built to **face-plate-top = 67** (body 40–66) with a raised rear ridge + 12-tall VU towers for the "tallest mesa" silhouette. If the design truly wanted a 107-tall mixer, that's a one-line change in `buildMixer`. 2. **`fillBox` fast path — RESOLVED.** `tools.box()` uses `world.fillBox(x0,y0,z0,x1,y1,z1,id)` (INCLUSIVE bounds) if present, else a `setBlock` loop. Confirmed against Lane A's shipped `src/engine/VoxelWorld.ts:117`: the signature and inclusive-clamp semantics **match exactly**, so the fast path engages at integration (verified — see cross-lane smoke test above). No action needed. 3. **Elevation model.** A `Y_*` constant is the TOP-SURFACE PLANE: the topmost solid block of that stratum is at index `Y_*-1`; blocks placed on the surface sit at `Y_*`. Documented in `anchors.ts`. Platter well is carved 6 down from `Y_PLINTH_TOP` so Lane D's platter (top at `Y_RECORD_TOP=85`) rises cleanly out of it. 4. **No duplicated coords.** Every spindle/mixer/patch-bay position derives from `LAYOUT` via `anchors.ts` (single source). Lane D should read positions from `QUEST_POS` / the exported anchors, never re-hardcode. 5. **Structural blocks are `breakable:false`** already in `blocks.ts` (plywood, cables) — the booth keeps its shape; nothing here relies on that beyond honoring it.