* feat(keys_highway_3d): add note-colour palettes and selectable camera angles
Give the 3D keys highway player-facing view options and a tuned default
look, so the piano highway is readable out of the box and customisable
from the settings panel without touching code.
Note colours (settings -> Note colours, `keys3d_bg_palette`):
- Octaves (new default): each octave its own hue climbing the rainbow,
darker sharps, so pitch height reads at a glance on any note range.
- Rainbow: the original per-pitch table (colours unchanged).
- Vivid / Pastel: per-pitch variants.
- Emerald / Ice: single-hue two-tone (uniform naturals, darker sharps).
The pick drives the notes, key glow, lane guides and hit flames, live.
Camera (settings -> Camera angle, `keys3d_bg_camera`):
- Classic (the original low rig) / Elevated / Overhead (new default).
- Height, distance and tilt fine-tune sliders nudge the base vantage the
auto-pan/zoom follow-motion orbits; presets apply live.
The new defaults are opinionated for plug-and-play (octaves palette,
overhead camera, tilt -0.6); anyone who prefers the original look can
pick Rainbow + Classic. Settings changes are re-read on init() so they
apply on return from the settings screen, not only after a relaunch.
Scoring, hit-timing and MIDI handling are untouched -- these are purely
visual. Numeric FX keys clamp to declared ranges (FX_RANGES); the pure
colour/camera helpers are covered by unit tests (node --test).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: LegionaryLeader <legionaryleader@gmail.com>
* fix(keys_highway_3d): make Classic camera reproduce the original rig + drop per-frame camera alloc
Review follow-ups on the palettes/camera feature:
- "Classic" preset now reproduces the historical rig exactly. The tuned
plug-and-play downward aim (camTilt -0.6 x CAM_TILT_UNITS = -33) is baked
into CAM_PRESETS.overhead.lookY, and camTilt now defaults to 0 (neutral).
The default overhead look is byte-identical (effective lookY still -33),
but "pick Classic for the original look" is now actually true instead of
leaving a -33 down-tilt applied. settings.html tilt slider defaults to 0.
- _rig() writes into a hoisted reusable object instead of allocating a fresh
{y,z,lookY,lookZ} literal every frame, honoring the module's documented
"no per-frame allocations in draw()" discipline. Callers read it
synchronously and never retain it, so one shared instance is safe.
Tests updated for the neutral camTilt default; adds an invariant test that
the default overhead framing is unchanged and Classic + neutral tilt == the
historical LOOK_Y. Full JS suite green (1069 pass).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Signed-off-by: LegionaryLeader <legionaryleader@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
- BG_STYLES port (off/particles/lights/geometric; lights use the
pitch-class palette) mounted behind the scene; _bgGetAnalyser/
_bgReadBands (stems-first, one-shot #audio fallback, permanent-failure
latch); Ambience intensity + Audio-reactive settings; remounts on
style/intensity change
- Score-FX overlay canvas (drum_highway_3d pattern): +1 pops at the
scored key, ring pulse every 10-combo, milestone bursts at 25/50/100,
red wash on 3+ streak break (wrong notes AND swept misses); cleared
when idle, removed in teardown
- Tests: style id validation + FX defaults (30 total)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- setPixelRatio at last: DPR (cap 2; 1.25 when >1 instance) x host
adaptive bundle.renderScale — HiDPI displays were rendering at CSS
resolution and upscaling (soft/aliased)
- Bloom: port _bloomEnsure/_bloomDispose (UnrealBloomPass 0.65/0.5/0.82,
MSAA HalfFloat target, ACES<->None switch); hit-line, flames and
consume-glow benefit immediately; direct render is the degrade path
- First settings panel: settings.html (graphics category) with a live
Glow (bloom) toggle; FX scaffold (FX_DEFAULTS/readFxSettings/
window.keys3dSetFx, keys3d_bg_* keys, keys3d:settings event)
- Combo/accuracy/best-streak DOM HUD (drum_highway_3d pattern), gated on
a live MIDI session
- tests/fx_settings.test.js (3 tests; vm harness)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>