Skip to content

feat(keys_highway_3d): add note-colour palettes and selectable camera angles - #794

Merged
byrongamatos merged 3 commits into
got-feedBack:mainfrom
LegionaryLeader:feat/keys3d-palettes-camera
Jul 6, 2026
Merged

byrongamatos merged 3 commits into
got-feedBack:mainfrom
LegionaryLeader:feat/keys3d-palettes-camera

Conversation

@LegionaryLeader

@LegionaryLeader LegionaryLeader commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

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 customizable from the settings panel without touching code.

Note colors (settings -> Note colors, 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 (colors 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 color/camera helpers are covered by unit tests (node --test).

image

Summary by CodeRabbit

  • New Features
    • Added note color palette options, including a procedural “octaves” scheme, with instant live switching and persistence.
    • Added camera rig presets plus fine-tuning controls for camera height, distance, and tilt.
    • Settings now automatically load and apply saved palette and camera choices.
  • Bug Fixes
    • Improved live rendering updates so note colors, flashes, flames, and camera framing refresh immediately.
    • Refined camera control limits and clamping for consistent behavior.
  • Chores
    • Updated the plugin version to 0.1.2.
    • Expanded documentation with the new camera settings.

… 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>
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2ea75575-a926-43e3-8e3c-58ccc1bbdd87

📥 Commits

Reviewing files that changed from the base of the PR and between 7458e0e and 57a9c92.

📒 Files selected for processing (3)
  • plugins/keys_highway_3d/screen.js
  • plugins/keys_highway_3d/settings.html
  • plugins/keys_highway_3d/tests/fx_settings.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/keys_highway_3d/settings.html
  • plugins/keys_highway_3d/tests/fx_settings.test.js

📝 Walkthrough

Walkthrough

Adds selectable note-color palettes and camera presets to the keys_highway_3d plugin. Introduces persisted palette/camera settings, palette-aware rendering, camera rig calculations, live retinting, settings UI controls, expanded tests, README updates, and a version bump.

Changes

Palette and Camera Feature

Layer / File(s) Summary
Palette data and color resolution
plugins/keys_highway_3d/screen.js
Defines NOTE_PALETTES and the procedural octaves scheme, persists the palette setting, and resolves note colors from the selected palette.
Camera preset and FX range clamping
plugins/keys_highway_3d/screen.js
Adds FX_RANGES for camera fine-tune parameters, persists the camera preset setting, clamps FX values, and computes the effective camera rig from the selected preset and live tilt.
Rendering, material caching, and live retint wiring
plugins/keys_highway_3d/screen.js
Keys note materials and flame textures by resolved color, applies live palette retinting to existing scene objects, refreshes persisted state on init, and handles palette/camera updates through the settings event path.
Settings HTML controls and hydration
plugins/keys_highway_3d/settings.html
Adds the palette dropdown and camera angle/height/distance/tilt controls, with hydration for stored palette and camera values and clamped slider restoration.
Tests, README, and manifest version
plugins/keys_highway_3d/tests/fx_settings.test.js, plugins/keys_highway_3d/README.md, plugins/keys_highway_3d/plugin.json
Adds test coverage for palette tables, palette/camera persistence, FX clamping, camera presets, and octave coloring, updates the README feature list, and bumps the plugin version.

Estimated code review effort: 3 (Moderate) | ~30 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: configurable note-colour palettes and selectable camera angles for keys_highway_3d.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
plugins/keys_highway_3d/screen.js (1)

1247-1249: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the stale camera-default comments.

These comments still describe classic as the default/untouched view, but readCameraSetting() now defaults to overhead and the settings UI also selects Overhead by default.

Suggested wording
-    // Camera-rig presets. 'classic' is the original low, near-telephoto rig
-    // (numerically identical to the historical constants, so an untouched
-    // setting keeps the stock framing). y/z/lookY/lookZ are in pre-K world
+    // Camera-rig presets. 'classic' preserves the original low,
+    // near-telephoto rig numerically, while new/untouched installs default
+    // to the overhead reading view. y/z/lookY/lookZ are in pre-K world
-        // Camera — the default 'classic' preset is a low, near-telephoto rig
+        // Camera — the 'classic' preset preserves the original low, near-telephoto rig

Also applies to: 1662-1664

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/keys_highway_3d/screen.js` around lines 1247 - 1249, Update the stale
camera preset comments in readCameraSetting() and the related Camera-rig preset
docs so they no longer say classic is the default or untouched view; the current
default is overhead, and the settings UI also selects Overhead by default. Keep
the comment wording aligned with the actual behavior in screen.js, especially
around the camera preset definitions and default selection logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/keys_highway_3d/screen.js`:
- Around line 2391-2395: In _applyPalette(), the flame rearm logic is forcing
every active slot to _flameTexture(0), which retints visible flames to the wrong
color after a palette switch. Update the flame spawn path to persist each slot’s
MIDI note on the slot object, then use that stored MIDI when reassigning mat.map
during palette rearming instead of hardcoding 0. Make sure the same fix is
applied anywhere else the flame pool is rearmed so active flames keep their
original note color.

---

Nitpick comments:
In `@plugins/keys_highway_3d/screen.js`:
- Around line 1247-1249: Update the stale camera preset comments in
readCameraSetting() and the related Camera-rig preset docs so they no longer say
classic is the default or untouched view; the current default is overhead, and
the settings UI also selects Overhead by default. Keep the comment wording
aligned with the actual behavior in screen.js, especially around the camera
preset definitions and default selection logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f438553-21d9-4c6b-a3d6-00729bef4b5a

📥 Commits

Reviewing files that changed from the base of the PR and between 612b1f2 and 7458e0e.

📒 Files selected for processing (5)
  • plugins/keys_highway_3d/README.md
  • plugins/keys_highway_3d/plugin.json
  • plugins/keys_highway_3d/screen.js
  • plugins/keys_highway_3d/settings.html
  • plugins/keys_highway_3d/tests/fx_settings.test.js

Comment on lines +2391 to +2395
_clearFlameTextures();
// Re-arm the pool so no slot keeps rendering a disposed texture
// (a flame mid-flight briefly re-tints — next spawn sets its
// true pitch texture).
for (const s of _flamePool) s.mat.map = _flameTexture(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Retint active flames with their actual MIDI note.

_applyPalette() assigns every flame slot _flameTexture(0), so a visible hit flame changes to the C/sub-C1 color after a live palette switch instead of the struck note’s color. Store the slot MIDI on spawn and reuse it during palette rearming.

Proposed fix
-            for (const s of _flamePool) s.mat.map = _flameTexture(0);
+            for (const s of _flamePool) {
+                s.mat.map = _flameTexture(Number.isFinite(s.midi) ? s.midi : 0);
+            }
-                _flamePool.push({ sprite, mat, start: -1, baseY: 0 });
+                _flamePool.push({ sprite, mat, start: -1, baseY: 0, midi: 0 });
             slot.mat.map = _flameTexture(midi);
+            slot.midi = midi;
             slot.start = wallNow;

Also applies to: 2547-2550

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/keys_highway_3d/screen.js` around lines 2391 - 2395, In
_applyPalette(), the flame rearm logic is forcing every active slot to
_flameTexture(0), which retints visible flames to the wrong color after a
palette switch. Update the flame spawn path to persist each slot’s MIDI note on
the slot object, then use that stored MIDI when reassigning mat.map during
palette rearming instead of hardcoding 0. Make sure the same fix is applied
anywhere else the flame pool is rearmed so active flames keep their original
note color.

byrongamatos and others added 2 commits July 6, 2026 10:16
…+ 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>
@byrongamatos
byrongamatos merged commit a20dca2 into got-feedBack:main Jul 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants