Field 2026-07-23 (second night): a player's join.bat failed 3x in a row
with a 0-byte join.log -- indistinguishable from 'never ran'. Two
causes of evidence loss fixed:
1. The first flushed log line now happens the INSTANT the log opens
(version, pid, args, first-process vs relaunched-generation). An
empty log after this build means the exe was killed before WinMain
-- an external cause (antivirus/loader), not ours.
2. The menu->game relaunch chain truncated join.log each generation
(BT_LOG_APPEND was unset in the player bats): the crashed
generation's evidence was erased by the next attempt. The bats now
delete the log once per bat run and append across generations.
Also explains the confusing 'The game has exited' bat message on
SUCCESSFUL launches (the menu process exits after relaunching the game
detached) -- the log now records the whole chain.
The steam bat missed the two client flags the join bats set -- steam-launched
missions booted 3rd-person (the same field bug fixed for join.bat earlier).
Env inherits through the menu's mission relaunch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
Zero-mission-arg launch of the build-steam exe -> lands in the glass FE
menu, where Steam sessions actually form (host or join an ISteamMatchmaking
lobby; there is no address to dial, so this is a LAUNCHER not a joiner --
unlike join.bat/join_lan.bat). Sets BT_PLATFORM=glass + BT_STEAM_NET=1,
logs to content\steam.log. Guarded like the sibling bats, with the two
failure modes spelled out (zip without build-steam\; Steam client not
running = menu works, no lobbies).
Requires distributing the build-steam variant (BT_GLASS+BT_STEAM) alongside
content\ -- a different zip shape; the pod-build zips are unaffected. For
dev testers to exercise the Steam path further (prior tests were buggy);
NOT for general players yet: the live 2-machine exit criterion
(docs/STEAM_TEST.md) is still open and the AppID is the 480 test id.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>