The systems were all there but the opening experience sagged: a new player
spawned into a dark, silent booth with no idea they're tiny or that
anything is broken. Five fixes, all verified live:
- The dying booth has a HEARTBEAT: a slow muffled lub-dub (~55bpm sine
thumps, lowpassed, positional from inside the mixer) while zero repairs
are done. First repair silences it with real music; a reset revives it.
- Broken quest nodes SPARK: intermittent blue-white electric crackles at
each unrepaired fixture (FxSystem.setBeacons, anchored from QUEST_POS) -
diegetic breadcrumbs visible across the booth.
- First-visit FLYTHROUGH: 9 skippable seconds - wide booth reveal, sweep
over the mixer, dive to spawn - riding the existing cine override.
Teaches 'you are tiny in a DJ booth' better than any text.
- Mining JUICE: new 'block:mining' bus event (~8Hz while held) drives
grey chip particles + rising-pitch ticks; throttle resets per target.
- og/twitter meta tags + public/preview.jpg so sharing the link unfurls
with the hero shot.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Built by the Opus session per docs/briefs/SOCIAL_RESET.md; integrated and
verified by Fable (typecheck clean, relay validation reviewed, 3D avatar
gear/face pixel-confirmed live — the one item the build session couldn't
capture in its frozen preview pane).
- Avatars: hue/gear/face enums in src/net/avatarLook.ts shared by the 3D
build and the Menu AVATAR tab's 2D mirror; live sync with client-side
coalescing (two-tab testing caught the relay rate limit permanently
desyncing rapid editors - trailing send fixes convergence).
- Emotes Z/X/C/V: wave, beat-synced nod, point, rate-limited airhorn
(detuned saws + confetti), server + client caps.
- Reset ritual: after a win the fuse takes a deliberate 5s hold (reuses
the workshop radial meter as the warning dial) -> server-authoritative
reset with 10-min cooldown; music brakes to silence, lights die over 3s,
workshop resets to wires-off with a SERVER-generated random weight notch
(both tabs land identical), player builds survive, quest replayable.
- Roster: hold Tab for who's-in-the-booth with hue swatches.
- interact/ addition (flagged friction): additive setBreakGuard hook so
interaction.ts never learns what a fuse is.
- launch.json: main dev config uses autoPort (5173 collisions with
parallel sessions).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Avatar customization: hue/headgear/face enums, Menu AVATAR tab with 2D
preview, live sync via extended hi + new avatar message (no moderation
surface - palettes only, no free-form content).
- Emotes on Z X C V: wave, beat-synced head-nod, point, rate-limited
airhorn with positional synth + confetti.
- Reset ritual: after a win the glass fuse becomes hold-breakable (5s,
warned); server-authoritative reset with 10-min cooldown - music
power-downs, lights die, workshop resets to wires-off, block edits
survive, quest replayable. Needs Quest.reset() + 'quest:reset' bus event.
- Tab-hold player list.
Protocol validation/rate-limit requirements spelled out for ship-check.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fresh-eyes review of the glow-up found the G5 side-ring texture applied to
whole tier cylinders - linear UVs on the caps rendered as diagonal stripes
across the disc. CylinderGeometry takes [side, top, bottom] materials: sides
keep Lane E's ring texture, caps get a new radial recordCapGrooveTexture()
(machines/util.ts) with ring count scaled per tier radius so groove pitch
stays constant. Also lands the three handoff-doc updates from the phase.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fresh-eyes review outcomes as two parallel-safe Opus briefs:
- WORKSHOP_CARTRIDGE.md: the stylus node becomes a five-stage cartridge
assembly - seat/rotate the cart, crimp four color-coded wires onto
stubborn pins (catenary carry, continuity lamp), torque screws evenly
(tilt = azimuth error), balance the counterweight while RIDING the
seesawing tonearm, then a needle-drop test where every mistake is
audible + drawn on a diegetic scope. Multiplayer-shared state.
- GLOWUP_ART.md: atlas v2 (32px, tile variants), selective LED bloom,
screen-print decals + party flyers, mixer-face density, PCB pagodas.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- server/relay.mjs: WebSocket room (ws, 127.0.0.1:8433 behind a proxy).
Relays positions/edits/repairs/platter states; keeps the authoritative
world diff + quest state for late joiners; persists to booth-state.json.
Hardened: origin allowlist, 24-peer cap, 2KB frames, 40 msg/s budget,
bounds+type validation on every message, ping/terminate dead sockets.
- src/net/NetClient.ts: offline-tolerant client — mirrors bus events out,
applies remote events with an echo guard (quest.repair/platter setters
are idempotent/deduped so replication can't loop). 10Hz delta'd positions.
- src/net/Avatars.ts: voxel-person avatars with headphones + name tags,
lerped to network updates.
- Menu: DJ name setting (auto-generated default); help page multiplayer note.
- main.ts: wires avatars + status chip ('online - N other DJs in the booth').
Verified with two live tabs: mutual avatars, block edit + quest repair
replicate both ways, late-joiner gets full state replay, non-gameplay
setBlock correctly does NOT sync, zero console errors, relay log clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- src/ui/Menu.ts: overlay with HOW TO PLAY (controls, the five repairs,
tips) and SETTINGS (master volume, mouse sensitivity, view bob, render
quality); persists to localStorage, auto-opens on first visit, corner
badge + H toggles it.
- View bob now defaults OFF (playtest: reads as screen rumble to
non-Minecraft players); re-enable in settings.
- New hooks: PlayerController.setSensitivity, InputController.setSensitivity,
AudioEngine.setMasterVolume (safe pre-init), quality -> pixelRatio in main.
- Pause overlay suppressed while the menu is open; closing re-locks pointer.
Verified: menu renders over splash, both tabs, quality rescales the
framebuffer 2->1, settings persist, zero console errors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 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>
Lanes A (engine), B (player), C (worldgen), D (machines/quest),
E (audio/fx/ui) as landed, each with HANDOFF.md + update docs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>