Playtesters (all on the glass surround) reported the cockpit lighting
sometimes going slow or nonexistent while the 3D view stayed perfectly
smooth. The RIO serial/lamp stack is byte-identical to pod-proven Red
Planet (diffed L4LAMP/L4RIO/L4SERIAL), so the wiring was fine -- the defect
is the glass UPDATE CADENCE:
The lit buttons draw every frame (BTDrawCockpitPanels, reading
PadRIO::GetLampState), but the lamp STATE sweep that fills that store
(LampManager::Update -> AssertNewLampValue -> SetLamp) rides the gauge
renderer's FOREGROUND turn, which fires only once per full gauge cycle
(foreground->background->copy). The cycle can't reach the next foreground
turn until the throttled background gauge sweep drains the ~140-instrument
active list -- and that background task starves under MP load (issue #45,
"instruments freeze while fps stays healthy"). So the lamp sweep ran
~1x/second: buttons froze / flashes stalled while the view (a separate
per-frame foreground render) stayed smooth.
Fix: BTGlassSweepLamps() runs the lamp sweep EVERY frame on the dev/glass
composite path (L4VB16.cpp, in BTDrawGaugeInset), decoupled from the gauge
cycle. It is cheap -- deduped state pushes over ~72 lamps, no raster. The
pod never enters BTDrawGaugeInset (real gauge hardware), so its authentic
bandwidth-paced serial lamp cadence is untouched. BT_GLASS_LAMP_SWEEP=0
restores the authentic once-per-cycle behaviour.
Verified: Release links clean (only the 40 tolerated /FORCE externals);
glass surround boots and runs, lamp sweep pushes state (43 [lamp] pushes,
buttons lit), ~60 fps, no crash. The under-load win is structural (the
sweep is now an unconditional per-frame call); true MP-starvation repro
needs multiple nodes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>