Files
BT411/context/glass-cockpit.md
T
arcattackandClaude Fable 5 6ad1e074cc Glass lever: port the pod-build GAIT DETENT to the PadRIO throttle slew
Human re-test on the fresh build: zero-stop OK, but the lever could PARK inside
the walk/run hysteresis band (walkStrideLength@0x534 .. reverseSpeedMax@0x538)
where the gait SM has no stable state -- walk<->run hunt, EngineShiftFwd/Rev
retriggering ("mixed walk/run mode + repeated acceleration sample").  The
pod-build keyboard lever already snaps out of the band to the NEARER edge at
key-rest (mech4.cpp GAIT DETENT); the PadRIO slew channel lacked it.

Faithful port, not an invention: mech4.cpp publishes the band in lever units
every driven frame (gBTGaitDetentLo/Hi seam, same guards + the same +0.002
engage margin); L4PADRIO Poll() applies the identical nearer-edge snap to the
Throttle channel when the slew rests (no slew key held, no pad slew axis
deflected).  Sweeping through the band while held stays continuous (the
authentic moving lever, one authentic shift).

Verified (DEV.EGG glass, graduated parks each ~0.10 of the sweep,
BT_GAIT_TRACE+BT_MPPR_TRACE): band [0.358026,0.50388) = demand 22.02-30.87;
in-band parks snap both directions (0.4137->lo, 0.465126->hi); no at-rest
sample in the band; exactly ONE walk->run clip (state 10) up and ONE run->walk
(state 14) down across the whole sweep; zero-stop unaffected; pod build
rebuilt + BT_AUTODRIVE smoke clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 10:57:34 -05:00

111 lines
7.9 KiB
Markdown

---
id: glass-cockpit
title: "Glass Cockpit — the desktop developer layer (BT_GLASS / BT_STEAM)"
status: living
source_sections: "plan 2026-07-17; CMakeLists.txt gates; BT412 prior art (reference only)"
related_topics: [pod-hardware, build-and-run, multiplayer, gauges-hud]
key_terms: [PadRIO, miniconsole, glass-cockpit]
open_questions: []
---
# Glass Cockpit — the desktop developer layer
**Purpose:** developer tooling so game developers can test their work WITHOUT booting a Tesla II
pod — and stay far enough out of the game that nothing a real pod requires can break. NOT a
consumer product (GDI-grade UI is the ceiling). Pod fidelity outranks desktop convenience in
every trade-off.
## The compile gates (the ONLY compile-time feature gates in the tree)
| Gate | Default | Adds |
|---|---|---|
| `BT_GLASS` | OFF | PadRIO input (XInput+keyboard), on-screen cockpit button panel, desktop plasma window, `glass` platform preset, miniconsole mission launcher |
| `BT_STEAM` | OFF (requires `BT_GLASS`) | Steam transport (`ISteamNetworkingSockets`) + `ISteamMatchmaking` lobby |
- A **no-flags configure is the pure pod game** — the build of record. `cmake` options are
cached, so a developer configures a `build/` with `-DBT_GLASS=ON` once.
- Build dirs: `build-pod/` (defaults, purity), `build/` (dev, glass ON), `build-steam/` (ON/ON).
- **Convention:** `BT_GLASS`/`BT_STEAM` are compile gates; every other `BT_*` name is a RUNTIME
env gate (`BTEnvOn`) — do not add compile gates without updating this file.
- No weak-linkage/optional symbols — `/FORCE` turns unresolved externals into runtime AVs
([[reconstruction-gotchas]]); gated calls must be structurally present-or-absent at compile time.
## Plan of record (2026-07-17)
Working branch `glass-cockpit` (from master `e2c21c4`). Steps: (1) gates+scaffolding [THIS],
(2) PadRIO glass cockpit, (3) miniconsole self-launch, (4) Steam transport+lobby. Full plan:
the approved plan file; running detail: `docs/GLASS_COCKPIT.md`. The retired BT412 trees
(`C:\VWE\BT412`; local branch `local-abandoned-20260717`) are read-only reference — no code is
copied from them.
## Status
- **Step 1 (gates + scaffolding): DONE 2026-07-17.** CMake options + defines; 3-config
configure matrix + negative test + defaults build verified.
- **Step 2a (.CTL id audit): DONE 2026-07-17 [T2].** The streamed `.CTL` positional ids landed
every `MechControlsMapper` record ONE MEMBER LATE (our chain starts at 2, the binary's at 3)
— a latent REAL-POD bug (RIO throttle would drive pedalsPosition), masked on dev boxes by the
keyboard bridge. Fixed ungated: ids pinned to binary numbering + id-2 pad + static_assert
locks (`mechmppr.hpp/.cpp`); torso/weapon chains were already aligned. Permanent env-gated
diagnostic: `BT_CTRLMAP_LOG=1` dumps every streamed record's resolved member offset
(`L4CTRL.cpp CreateStreamedMappings`). Full evidence: `docs/GLASS_COCKPIT.md` §2a.
- **Step 2 (PadRIO glass cockpit): DONE 2026-07-17 [T2].** `RIOBase` seam (`L4RIO.h`,
unconditional) + gated `L4CONTROLS=PAD``PadRIO` (`L4PADRIO.*` XInput+keyboard,
`L4PADBINDINGS.*` `content\bindings.txt`); bridge stand-downs auto-yield to a live device
(`BTRIODevicePresent`, `BT_KEY_BRIDGE` unset=auto/0=off/1=on); on-screen panel `L4PADPANEL.*`
follows **vRIO** (`C:\VWE\vrio` CockpitLayout/PanelCanvas — 104 controls incl. the two hex
keypads → real KeyEvents; right-click latch); desktop plasma `L4PLASMAWIN.*`
(`L4PLASMA=SCREEN`, buffer is top-down); `-platform glass` preset + run.cmd token. Secondary
displays reuse the EXISTING dev-gauge modes (dock / `BT_DEV_GAUGES_WINDOW=1` window /
`_DOCK=1` overlay — [[gauges-hud]]); no new MFD code, no `L4VB16.cpp` exposure.
**Button-trap guard:** base `ConfigureMappableMessageHandler` no longer `abort()`s by default
(`BT_BUTTON_TRAP=1` restores) — each `[FAIL]` log = a missing L4 override to reconstruct.
Verified: authentic-path input (engine push → streamed `.CTL` → mapper), panel-click
survival, 2-node loopback MP un-regressed on the pod build. Detail: `docs/GLASS_COCKPIT.md`.
- **Step 3 (miniconsole): DONE 2026-07-17 [T2].** `game/glass/btl4fe.*` (menu + console-shape
egg writer, golden-tested vs MP.EGG) + `btl4console.*` (the marshal: a worker-thread console
CLIENT speaking the btconsole.py wire verbatim; `content\marshal.log`). ZERO engine hooks —
the engine runs the stock console ladder. Per-mission process relaunch; `BT_FE_*` env arms the
marshal (menu relaunches clear it). Verified: solo cycle (menu→mission→60s clock→stop→menu)
and menu-hosted 2-node LAN.
- **Step 4 (Steam): CODE COMPLETE 2026-07-18 [T2 single-machine].** See [[steam-networking]] —
the wire seam + `L4STEAMNET` identity-token transport + `btl4lobby`. Live 2-account
cross-machine session pending (`docs/STEAM_TEST.md`).
- **Input-coverage audit + keyboard reconciliation: DONE 2026-07-20 [T2].** Root cause of the
dead panel: `MechRIOMapper`'s message ids were chained one enum too high (0x19-0x2a) — the
binary RIO table @0051dd30 re-registers the BASE aux/zoom ids 3..0x13 (Hotbox 0x1a); fixed
ungated + static_assert-locked (`btl4mppr.hpp`) → all 24 MFD-bank + 2 zoom buttons live
(52/72 panel buttons now work; 8 dead await handler reconstruction — Gitea backlog issue;
12 have no streamed mapping authored, authentically inert). **Keyboard = the ~20 core
gameplay actions on the CONTROLS.MAP keys; the PANEL covers every pod address by click**
(right-click = hold latch) — the merged default profile lives in `L4PADBINDINGS.cpp`
(auto-writes `content\bindings.txt`; W/S/A/D/Q/E/R/F/X drive, 1-4/Space/Ctrl fire, M/N/H/C =
pod buttons 0x18/0x15/0x2C/0x2F, `/V view toggle + J/K/L preset cycles hardcoded in PadRIO).
Bound keys are SUPPRESSED from the typed 1995 channel (`PadRIO::SuppressKey`, the btinput
pattern — ended the glass double-dispatch: 'w'=pilot-select, numpad/F-key key-up aliases);
unbound keys keep their authentic meanings (5/z presets, t-o pilot select, +/- zoom).
In BAS control mode the pod turns with the STICK (Q/E) and pedals are inactive — authentic;
A/D turn in MID/ADV. Arrow keys mirror the drive cluster (UP/DOWN = the W/S throttle lever,
LEFT/RIGHT = the A/D pedals). Full audit + census: `docs/GLASS_COCKPIT.md` §2026-07-20.
- **2026-07-20 live "keymap regression" report: STALE EXE [T2].** The human-reported glass
regressions (arrows/lever/detent dead, V/J/K/L/N inert, ground-fire) were a
`build-glass/Release/btl4.exe` built BEFORE 5dd3536 landed — relaunched without rebuilding.
No input-code change was needed; a clean rebuild + full SendInput re-verification (lever
holds + zero stop, MID turns, V toggle shot-pair, level boresight, pod smoke) closed every
symptom, and V's edge is now [T2]. `BT_MPPR_TRACE` now prints mode/pedals/stick/turn/elev.
Procedural rule: rebuild every live build dir after landing an input/engine commit.
Detail: `docs/GLASS_COCKPIT.md` §2026-07-20 (later).
- **2026-07-20 human re-test: GAIT DETENT ported to the PadRIO lever [T2].** The remaining
"our detent is missing" (mixed walk/run mode + repeated accel sample) was the gait DEAD BAND
([[locomotion]]): the pod-build keyboard lever snaps out of the walk/run hysteresis band at
key-rest (mech4.cpp GAIT DETENT), and the PadRIO throttle slew lacked it. Ported faithfully:
mech4.cpp publishes the band in lever units (`gBTGaitDetentLo/Hi` seam, +0.002 engage
margin), `L4PADRIO.cpp` applies the identical nearer-edge snap when no throttle slew key/pad
axis is active. Verified: parks at 0.414/0.465 snap to 0.358/0.504 (band = demand
22.02-30.87), no at-rest sample in-band, exactly ONE up-shift + ONE down-shift clip across a
full graduated sweep, zero-stop + pod build unaffected. Detail: `docs/GLASS_COCKPIT.md`
§2026-07-20 (later still).
## Key Relationships
- Extends: [[pod-hardware]] (RIO input path) · Uses: [[gauges-hud]] dev-gauge modes ·
Feeds: [[multiplayer]] (miniconsole hosting, Steam transport) · Build: [[build-and-run]]