- Workshop (WORKSHOP_CARTRIDGE): five-stage cartridge assembly at Deck A — seat/square, crimp four tag-wires, torque screws, ride-the-arm counterweight balance, needle-drop diagnostic with per-fault audio + scope. Relay-synced (per-field co-op merge: held screw + carried wire survive remote state). - Glow-Up (G1-G5): 32px atlas with per-voxel variants, selective LED bloom (quality-gated), screen-print decal system + party flyers, mixer/PCB worldgen density pass, record groove-sheen side texture. - 10 confirmed multi-agent review fixes, incl. co-op screw-stomp soft-lock, ride-snap collider-identity (magnet feet / eaten record-fling), workshop SFX exact-match map (rca_seated hijack), beam ride colliders to the head, double-crimp guard, WIRING INCOMPLETE diagnosis mode, skate-abort timer, completedState wiring, per-tick material churn, trackingHeavy platter drag. - Crossfader playtest fix: slew-limited sled (3.4 v/s) + ribbed grip caps with amber index — the sled reads as a heavy handle, not a teleporting wall. - Demo harnesses: machinesDemo hold-key wiring, playerDemo seesaw phase continuity, audioDemo incomplete fault button. - Workshop sync: exact 1.0 screw endpoint gets its own emit signature. Verified: typecheck + vite build clean, live solo quest smoke, two-client co-op relay smoke (simultaneous torque, no rewind, exact convergence). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.5 KiB
Glow-Up (Lane E / fx) — Handoff
Brief: docs/briefs/GLOWUP_ART.md
Scope done here: G3 (screen-print decals) and G5 (record side texture) —
the two src/fx/**-owned tasks. G1/G2 shipped in
GLOWUP_A_handoff.md; G4 in
src/worldgen/HANDOFF.md.
Status: ✅ G3 complete, browser-verified in the real game (port 5212),
typecheck clean, zero console errors. G5 texture generator complete; its
platter wiring is left for Lane D (this lane does not edit platter.ts).
What shipped
G3 — screen-print decal system (src/fx/decals.ts, new)
A DecalSet that bakes text/markings onto CanvasTextures and applies them to
thin plane meshes floating 0.05 proud of the gear faces, with polygonOffset
(factor/units = -4) so there is no z-fighting even at grazing angles.
One canvas per gear piece → 13 plane meshes total (< the brief's 25
draw-call budget; measured live via window.TURNCRAFT.decals).
All positions derive from LAYOUT (src/core/constants.ts) and the worldgen
anchors (MIXER, DECK_A, DECK_B, PATCH, UNDER from
src/worldgen/anchors.ts) — nothing hardcoded, so a booth-layout change
moves the print with it.
Print set (all browser-confirmed legible at play distance):
- Mixer face:
CH 1–4ahead of each fader alley, a tick ladder down each alley, theTURNCRAFT-800wordmark, and crossfaderA ↔ B(A on the deck-A side). - Each deck:
START·STOP,33/45, a pitch+/−scale ladder, and a "Quartz Direct Drive" script along the plinth front. Placed on the plinth ring/corners, clear of the platter radius (no clipping with the spinning record — verified at 33). - Patch bay:
PATCH BAY+01–12socket numbers aligned to the grid (on the alu panel face,backWallZ − 2, not the raw wall behind it). - Fuse box:
FUSE 250Vlegend. - Four procedural party flyers (word-bank names, one accent colour + border each): two flanking the patch bay on the bare back wall, two on the side walls near the front lip.
Orientation detail: on flat (up) faces the plane's canvas-up points to the
booth front, so each glyph is flipped 180° in place (letterforms only —
positions and tick marks stay put) to read from the player's front-edge view.
G5 — record side texture (recordSideTexture() in the same file)
A fine light/dark groove-ring CanvasTexture for the vinyl tier side
cylinders (rings horizontal, RepeatWrapping, NearestFilter). Standalone
generator, no side effects. Left for Lane D to wire into platter.ts —
exact snippet in src/fx/HANDOFF.md (Glow-Up section).
Files touched
| file | task | note |
|---|---|---|
src/fx/decals.ts |
G3+G5 | new — DecalSet, recordSideTexture() |
src/main.ts |
merge | additive: build DecalSet, add .group to scene, dev handle |
src/fx/HANDOFF.md |
docs | API + the recordSideTexture() wiring snippet for Lane D |
Merge points (per the brief):
src/main.ts— shared with the Workshop + Glow-Up-A briefs. My edits are 3 disjoint additive lines (import,new DecalSet()after the machines block, anddecalson thewindow.TURNCRAFThandle).src/worldgen/buildBooth.ts— listed as a merge point, but not needed: G3 reads existing anchors rather than adding worldgen dressing, so buildBooth is untouched.
Verification (real game, port 5212)
npm run typecheck— clean (exit 0), whole tree.- Cine screenshots (
window.TURNCRAFT_CINE): mixer face, deck top, patch bay, side-wall flyer, and a grazing pass across the mixer — every label legible and correctly oriented, no z-fighting, and zero console errors. - Draw calls:
window.TURNCRAFT.decals→ 13 meshes (< 25). Also logged at runtime in theDecalSetconstructor:[turncraft] screen-print decals: 13 draw calls (budget < 25). - Confirmed the decals are additive: toggling
decals.group.visibleremoves only the labels/flyers; the floating+shapes near the patch bay are the pre-existing RCA cable plugs (Lane C), not decals. - No quest regression: decals live in
decals.group(aMeshBasicMaterialplane group) and add zero physics colliders (machines.getColliders()stays 58); interaction is voxel-DDA raycast, not scene-mesh raycast, so the decal planes cannot intercept use/mine rays. Booth build unchanged: 746 ms, 467 chunk meshes (< 600), deterministic (anchors untouched). - fps: synchronous per-frame render timing (rAF is throttled in the preview pane) at the mixer, retina buffer: bloom-off ≈ 440 fps, bloom-on ≈ same order — decals (13 static planes) add no measurable regression; comfortably > 100.
- Sits cleanly alongside G1 (atlas variants), G2 (LED bloom), G4 (dense knobs).
Before/after screenshots (docs/progress-cutoff/)
Captured via window.TURNCRAFT_CINE in the real game (port 5205):
mixer_before.jpg / mixer_after.jpg (flagship before/after), deck_top_after.jpg
(Deck A — START·STOP + plinth script, clear of the platter), pcb_fuse_after.jpg
(FUSE 250V legend over the PCB-trace floor), fullbooth_win.jpg (emissive-lifted
"living booth" — decks, mixer labels + glowing alley pips, patch wall + flyers).
G5 texture fix (post-merge regression)
Lane D found the merged recordSideTexture() had a dark base (#101013),
which as a multiply map blacked out the vinyl (Deck A side measured
~[38,66,152] → ~[10,8,8]). Contradicted this doc's "near-white base" intent —
the other writer's dark version had won the merge. Fixed: inverted to a
near-white base (0.97) with faint dark groove lands (0.60), a soft shoulder
(0.80) and a bright sheen lip (1.0), 16 rings/tile — neutral greys so the
multiply never shifts hue. Re-verified live via readPixels on the actual Deck A
record side (map applied to sideMat at runtime, then reverted): blue channel
41 → 36 (~12% dip, stays clearly blue) vs an all-black test map's 41 → 17
blackout. Signature preserved; rings read as subtle sheen.
Not done / left for others
- G5 platter wiring — Lane D applies
recordSideTexture()to the tier-side material inplatter.ts(snippet insrc/fx/HANDOFF.md); now safe to wire.
Note — concurrent edits
src/fx/decals.ts was refined by another writer mid-session (patch-panel face
offset backWallZ − 2; flyer wall anchors via rimThickness/WORLD_X). Those
changes are correct and were kept; the browser verification above reflects the
merged file.