# Gauge / display cadence — why the cockpit instruments update slowly (2026-08-04) Operator report: "the rendering of the displays — many seconds between updates" on BTL4REC vs "the original." This file is the evidence chain. All measurements on the dev rig, `pod_render_bgprobe.conf` (no per-frame logs), DOSBox-X `cycles=max`, arena1 self-drive (BT_FORCE_THROTTLE=0.6). ## The mechanism (all verified in source AND the shipped binary) 1. **The manager runs flat-out by design.** `main` passes `GetTicksPerSecond()` to `ApplicationManager(Scalar frame_rate)`, so `frameDuration = 1/ticksPerSecond` — a microscopic frame budget. Verified in the shipped exe: the ctor constant `_DAT_0044f2d8` at file offset 0x4f0d8 of BTL4OPT.EXE is exactly `1.0f` (0x3f800000), i.e. the shipped 4.10 does the same. Consequence: `RunMissions` (@0044f344, structurally identical to the RP donor) finds `Now() >= end_of_frame` after every single background pass — **exactly one background slot per loop frame**, ours and shipped. Measured: `bg=` grows 1001 per 1001-frame period, every period. 2. **The background slot feeds a 7-task round-robin** (`BackgroundTasks::Execute` runs ONE task per call): RoutePacket, ProcessEvent, AudioRenderer, GaugeRenderer, NetworkManager, CompleteCycles, FryDeathRow. The gauge renderer gets 1/7th of slots. 3. **The gauge wheel repaints once per pass.** Each gauge-task slot = `ProcessOneActiveGauge()` = ONE active gauge. When the active list is exhausted the renderer enters its `copy` phase (the changed-line blit to the display — ~10 extra slots) and only then restarts. So per-instrument latency ≈ `7 × (wheel + copy) / loop_fps`. 4. **The wheel is 136 gauges and that is AUTHENTIC.** BT_GAUGE_LOG roster dump: 26 ColorMapperArmor, 12 VertTwoPartBar, 10 LeakGauge, 8 TwoState/PowerSource/HorizTwoPartBar/CoolingLoop, weapon clusters, generator clusters, myomer cluster, pilot list, message board … all real cockpit instruments. A Tesla pod shows every instrument at once; nothing pages out. Do NOT "fix" the roster. So at our measured ~25–33 loop fps: 7 × 146 / 30 ≈ **34 s** worst-case per-instrument latency. That is the operator's symptom, exactly. ## The real defect found: build flags `build410.sh` compiled with `-O2` alone. The authentic release tier (`CODE/BT/OPT.MAK`) is: -O2 -Ot -Oc -Og -O -Ol -Z -Ob -Oe -Oi -Om -Op -Ov (global CSE + global register allocation, invariant code motion, copy propagation, inline intrinsics, redundant-load suppression, loop opts). Adopting the full set (all 234 TUs compile clean, no BC4.52 optimizer ICEs) took the loop from **16.7 → ~30 loop fps wall** on the rig — a ~2× display-cadence improvement for free. `-w` was kept as `-w-`. Note: RP-era MAKE.CFG uses `bcc32i` (BC5 toolchain, RP 4.11+); BT 4.10's OPT.MAK says `BCC = bcc32` — we match 4.10. ## Measurement traps recorded (they cost hours tonight) - **Incremental-build staging:** the link consumes `build410/lib/*.lib`; rebuilding `engine` without `libs` ships STALE members. Also a same-minute mtime tie made the engine step skip freshly patched TUs. When probing: `rm` the target objs, then `engine`, `libs`, `link`. (l4grend's obj dir is `obj/mungal4` — no underscore.) - **Guest tick-delta profiling is unreliable in the emulator.** The SOS clock advances in bursts at trap points, so per-stage `Now()`-bracket sums measure where the burst LANDS, not cost: five timed foreground stages summed 8.7 "ticks/frame" while the whole function measured 17.0, with provably empty code between them. Wall-clock rates (log-line arrival, fifodump growth) are the only trustworthy measure. The tick probes are compile-gated behind `BT_TICK_PROBES` (default OFF); the pure counters (`bg= g= p= c=` on the `[stack]` line, BT_STACK_LOG) stay, they never touch the clock. - **`draw_scene` rate ≠ loop rate.** The board renderer is rate-governed by the RendererManager: 2.9 board-fps while the loop ran 33 fps. `fifofps.py` counts true board frames (action 9 records). ## Where the ours-vs-shipped gap stands fifodump growth mid-mission: shipped ≈ 11.8 KB/s, ours ≈ 4.1 KB/s before the flag fix, ≈ 6.4 KB/s after. Byte rate conflates the render governor with loop rate, so treat as indicative only. Under `cycles=max` wall time is trap-dominated; both exes drive the same VPX/serial/AWE devices. **OPEN QUESTION for the operator:** on THIS RIG, do BTL4OPT's cockpit instruments visibly update faster than BTL4REC's (post-flag-fix)? If yes, the residual is ours-specific guest work and the next tool is a DOSBox-side sampling profiler (we own the fork) — not more guest probes. If no — the rig was always like this and the "original" baseline was the real pod, whose identical architecture ran at real- hardware loop rates. ## Probe inventory (all in source410, cheap, env/compile gated) - `MUNGA/APP.CPP`: counters `bgSlots/bgTaskRuns/gaugeSlices/gaugePasses/ gaugeCopySlices` + `[stack]` print (env BT_STACK_LOG); tick-delta stage/slot timers behind `BT_TICK_PROBES`. - `MUNGA/APPTASK.CPP` (new shadow, from CODE/RP donor): per-ring-task timers behind `BT_TICK_PROBES`. - `MUNGA/GAUGREND.CPP`: wheel slice/pass counters; one-shot `[roster]` dump (env BT_GAUGE_LOG). - `emulator/render-bridge/fifofps.py`: true board-fps from a fifodump. - `emulator/render-bridge/pod_render_bgprobe.conf`: clean probe conf (BT_STACK_LOG + BT_GAUGE_LOG, no per-frame logs).