TURNCRAFT/docs/GLOWUP_A_handoff.md
jing 9c668d340c Headshell Workshop + Glow-Up phase: assembly minigame, art pass, review fixes
- 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>
2026-07-14 21:32:07 +10:00

5.5 KiB
Raw Blame History

Glow-Up (Lane A / engine) — Handoff

Brief: docs/briefs/GLOWUP_ART.md Scope done here: G1 (Atlas v2) and G2 (selective LED bloom) — the two engine-owned tasks. G3G5 are NOT started (see "Remaining" below). Status: G1 + G2 complete, browser-verified in the real game, typecheck clean, zero console errors.


What shipped

G1 — Atlas v2 (src/engine/atlas.ts)

  • Tiles 16 → 32 px. NearestFilter chunkiness preserved (fract keeps every sample inside its cell — no bleed, no mip seams).
  • Per-voxel variant system, zero mesher changes. 4 painted variants per block laid out in extra atlas columns (GRID_W = COLS*NVAR = 32). The material shader patch hashes each voxel's baked world position (floor(position - 0.02*normal)) → picks a variant → expands the base cell column. A repeated surface (PCB floor, plywood wall, brushed metal) breaks up instead of tiling like wallpaper. The mesher still writes only the base cell aTile = (id%8, id/8) — its verified winding/AO path is untouched. (This is the brief's "shader-patch variant" fallback, applied to all patterns, not just pcb.)
  • Pattern rewrites: brushed = long directional strokes + scratches (not noise); plywood = long wavy grain, concentric end-grain rings for ply_edge; pcb = 4 variants that tile into routed traces + via dots + silkscreen flecks; grooves = concentric arcs + specular sheen line; led = smooth radial glow.
  • Material polish via roughness only: 0.82 → 0.78 (no env maps, per brief).

G2 — Selective LED bloom (src/engine/renderer.ts)

  • EffectComposer + RenderPass + UnrealBloomPass + OutputPass. Tuned { strength 0.9, radius 0.5, threshold 0.85 } so only emissive LEDs/strobe/lamps cross the threshold — lit plywood/metal stays matte.
  • Lazy: the composer is created only on first setBloom(true), so fast quality never allocates it. render() picks composer-vs-direct internally; callers keep calling render() unchanged.
  • New API on the renderer: setBloom(enabled: boolean). Composer size/pixelRatio re-sync on resize and on quality (pixelRatio) changes.

Wiring (merge points — kept additive)

  • src/main.ts — destructure setBloom; in the Menu onApply: setBloom(s.bloom && s.quality !== 'fast'); added setBloom + setEmissiveBoost to the window.TURNCRAFT dev handle (used for cine screenshots and fps benchmarking). This file is shared with the Workshop brief, which added its own interaction.* / jumpScale lines — the edits are disjoint.
  • src/ui/Menu.tsbloom: boolean in Settings (default true), one checkbox row ("LED bloom (glow — off automatically on Fast)").

Files touched

file task note
src/engine/atlas.ts G1 rewritten — 32px, variants, patterns
src/engine/renderer.ts G2 +bloom composer, setBloom()
src/ui/Menu.ts G2 +bloom setting + checkbox
src/main.ts merge additive: setBloom wiring + dev handle

Merge points: src/main.ts (shared with Workshop brief), src/ui/Menu.ts (one settings row). src/worldgen/buildBooth.ts is listed as a merge point in the brief but G1/G2 did not need to touch it (that's G4).


Verification (ran it in the real game, port 5173)

  • Boot: 739 ms build, 467 chunk meshes (< 600 ✓), zero console errors.
  • Bloom A/B at the mixer (retina 2560×1440): LEDs (knob caps, VU towers, fader-alley pips) glow with a soft halo when ON, flat when OFF; plywood floor, matte-black body, and walls do not glow either way → selective confirmed.
  • PCB Depths: the pcb floor now reads as routed circuitry (traces + vias + silkscreen), not "green wallpaper"; variant hashing tiles it into a connected grid.
  • Deck platter: record shows concentric groove rings; brushed-metal plinth reads brushed; amber spindle lamp + orange strobe rim-pips bloom while the plinth stays matte.
  • fps (real, readPixels-forced GPU sync at 2560×1440, two runs):
    • Bloom OFF: ~234 / ~249 fps
    • Bloom ON: ~174 / ~220 fps (bloom overhead ≈ 1.5 ms/frame)
    • Both comfortably clear the ≥ 100 fps budget. ✓
    • (rAF is throttled in the headless preview pane, so frame-count fps reads 0 there; the synchronous per-frame render timing above is the trustworthy measure.)
  • npm run typecheck: clean (exit 0), including the concurrent Workshop edits.

Remaining Glow-Up work (NOT done — for whichever lane picks it up)

The brief assigns these to the same pass; this session scoped to the engine-owned G1/G2 only. None are started:

  • G3 — screen-print decal system (src/fx/decals.ts + worldgen anchors): CH 14, tick marks, TURNCRAFT-800, deck labels, socket numbers, party flyers. src/fx/decals.ts does not exist yet.
  • G4 — worldgen density pass (src/worldgen/buildBooth.ts, additive only): mushroom knob caps, doubled knob rows, panel seam grooves, PCB IC pagodas, ribbon-cable walls, alley/vent amber pips. Must stay deterministic, build < 800 ms, anchors untouched.
  • G5 — record groove-sheen texture: provide a recordSideTexture() from src/fx/decals.ts for the workshop session to wire into platter.ts (do not edit platter.ts — it is workshop-owned).

The G1 atlas already carries the emissive plumbing G4's LED pips need, and setBloom is live, so G4's new led_* blocks will bloom for free.