UNIFY: one exe -- retire the pod/glass/steam compile split

The three build dirs (build\ pod, build-glass\, build-steam\) were compile-
time splits of the same game; the tax was real: a stale steam exe shipped 2
days behind, the felt keymap flipped with the boot flavor, and cockpit
clicks were silently dead in the pod build (the trigger-config incident).

Now everything compiles into the single build\ exe:
- CMakeLists: BT_GLASS/BT_STEAM options removed; the glass TUs (PadRIO,
  bindings, panel, glass windows, plasma) + FE/console + Steam transport
  compile unconditionally; both macros always defined (seam markers).
- Steam: steam_api.lib linked with /DELAYLOAD:steam_api.dll + delayimp --
  the DLL maps only when SteamAPI is first called, and every call site
  gates on BT_STEAM_NET=1 (BTSteamNet_* short-circuit on steamActive), so
  machines without the DLL run everything but Steam sessions.
- CABINET GUARD (btl4main): the miniconsole menu previously claimed any
  zero-arg launch -- unified, that would hijack the pod cabinet's boot
  shape.  The menu now requires BT_PLATFORM=glass (or BT_FE_MENU=1);
  platform parse moved above the fe_menu_mode computation.  A bare boot
  behaves exactly like the old pod build (DEV profile, wait for egg).
- Bats (play_solo/join/join_lan/play_steam) + the btoperator.py template:
  single build\ path + BT_PLATFORM=glass.  mkdist: one exe (+DLL scan
  picks up OpenAL32 + steam_api).  build-glass\/build-steam\/build-glass2\
  (a stale Jul-20 cache) deleted.

Verified matrix on the unified exe:
  bare zero-arg boot == old pod exe (same DEV profile + egg-load path;
    the segfault on a missing egg is pre-existing, baselined vs the zip exe)
  glass + BT_BTNTEST scripted click -> [cfgmap] ENTER/EXIT (trigger config)
  runs with steam_api.dll ABSENT (delay-load proven)
  glass zero-arg -> miniconsole menu
  2-node loopback MP: 145 ticks each, cross-connected
  BT_STEAM_NET=1 without Steam client -> "staying on Winsock", game runs

KB: context/glass-cockpit.md compile-gates section rewritten for the
unified model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-21 10:28:51 -05:00
co-authored by Claude Opus 4.8
parent d89ae71db5
commit 10ed66bd7c
9 changed files with 117 additions and 147 deletions
+25 -11
View File
@@ -14,20 +14,34 @@ pod — and stay far enough out of the game that nothing a real pod requires can
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)
## ONE unified build (2026-07-21; the compile-gate split is RETIRED)
| Gate | Default | Adds |
|---|---|---|
| `BT_GLASS` | OFF | PadRIO input (XInput+keyboard), per-display cockpit windows (or the legacy single button panel), desktop plasma window, `glass` platform preset, miniconsole mission launcher |
| `BT_STEAM` | OFF (requires `BT_GLASS`) | Steam transport (`ISteamNetworkingSockets`) + `ISteamMatchmaking` lobby |
The pod/glass/steam **compile** split (three build dirs, three exes) is gone — it caused
version skew (a stale steam exe shipped 2 days behind), tripled build time, and the
"clicks silently dead in the wrong build" incident. Now **everything compiles into the one
`build/` exe** and behavior is selected at RUNTIME:
- 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.
| Runtime gate | Arms |
|---|---|
| `BT_PLATFORM=glass` | the desktop-cockpit profile: `L4CONTROLS=PAD` → PadRIO (clickable cockpit buttons, bindings.txt keymap), plasma window, and the miniconsole menu on a zero-arg launch |
| `BT_STEAM_NET=1` | the Steam transport (FakeIP/SDR; degrades to Winsock without the Steam client). `steam_api.dll` is **DELAY-LOADED** (`/DELAYLOAD` + delayimp) — machines without the DLL run everything else |
| (nothing) | the old pod-build behavior byte-for-byte: DEV profile, no menu, waits for the console egg — **the cabinet default is unchanged** |
- The `BT_GLASS`/`BT_STEAM` macros are now ALWAYS defined (seam markers only — the `#ifdef`
sites remain as documentation of the layer boundaries). Every gated code path was audited:
all are instance-guarded (`PadRIO::activeInstance`, `steamActive`) or env-gated at runtime.
- **Menu guard (cabinet protection):** the miniconsole previously claimed any zero-arg launch;
unified, it requires `BT_PLATFORM=glass` (or `BT_FE_MENU=1`) — a bare cabinet boot can never
land in the menu (btl4main.cpp, platform parse moved above the fe_menu_mode computation).
- Verified matrix (2026-07-21): bare boot ≡ old pod exe (same DEV profile, same egg-load path);
glass + scripted click → ConfigureMappables end-to-end; exe runs WITHOUT steam_api.dll
present; glass zero-arg → menu; 2-node loopback MP (145 ticks each); `BT_STEAM_NET=1`
without Steam → "staying on Winsock" + game runs.
- **Convention:** every `BT_*` name is a RUNTIME env gate (`BTEnvOn`); there are NO compile
feature gates anymore — do not add one 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.
([[reconstruction-gotchas]]); everything links always, so this class of trap no longer varies
by build flavor.
## Plan of record (2026-07-17)