TURNCRAFT/docs/GLOWUP_A_handoff.md
jing 74482e5693 Glow-up review fix: concentric groove caps on record tiers
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>
2026-07-16 22:48:32 +10:00

5.8 KiB
Raw Permalink 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 — UPDATE (re-checked after G3/G4 landed)

This session scoped to the engine-owned G1/G2 only. At the time of writing, G3G5 were not started. They have since been implemented by another session — re-verified against the live build:

  • G3 — screen-print decals: landed. src/fx/decals.ts exists; the booth logs screen-print decals: 13 draw calls (budget < 25) on boot. CH 14, tick marks, TURNCRAFT-800, crossfader A/B, PATCH BAY, and wall party flyers all render.
  • G4 — worldgen density: appears landed (denser/mixed knob clusters + lit fader-alley pips visible at the mixer face; build still ~752 ms, 467 chunk meshes).
  • G5 — record groove-sheen: recordSideTexture() is exported from src/fx/decals.ts:348 for the workshop session to wire into platter.ts.

Nothing here changes G1/G2. Confirmed on the integrated build: npm run typecheck clean (exit 0) with the Workshop + decal code merged; booth boots with zero console errors; at the mixer the alley pips / VU towers bloom while plywood and the matte-black body stay matte (selective bloom still correct next to the new decals); Atlas v2's grain/knob detail reads correctly under the new screen-print.

As predicted, G4's led_* pips bloom for free through the existing emissive plumbing.