Net: Steam lobby (btl4lobby) + launch-mode wiring (Workstream C.2)

Port RP412's RPL4LOBBY to BT: an ISteamMatchmaking room stands in for the
arcade Site-Management screen. Compiled both gates -- stubs without
BT412_STEAM, the full room under it (both configs build + link clean).

Lobby (game/reconstructed/btl4lobby.*):
- Room screen (green-on-black, like the menu), owner = console.
- Member data: FakeIP + fake console/game ports + persona + mech/color/badge
  (ip/cp/gp/nm/vh/cl/bd keys).
- Nonced "go" launch roster -> SteamNetTransport_RegisterPeer for every peer.
- Push/PullRaceResults over lobby data rebuild the shared score sheet.

Front end (btl4fe.*): HOST/JOIN buttons when BTLobby_Available() (Steam
transport up); the menu loop exits on a steam action and BTFrontEnd_Run
routes the lobby outcome -- host builds the egg with every member as a
[pilots] mesh entry (BTFrontEnd_SetHostedPilots), member returns launch
mode 2. Results screen prefers the marshal's collated result names.

Marshal (btl4console.*): add GetResultName / ClearResults / InjectResult so
the lobby owner can refill the sheet from the collated wire scores; Result
gains a name field.

WinMain (btl4main.cpp): install the Steam transport on BT412STEAM env
(before the front end, so the lobby is offered); branch on
BTFrontEnd_LastLaunchMode() -- host owns the marshal clock + joins the mesh,
member enters as a network pod on :1501 (SetNetworkCommonFlatAddress +
gConsoleLossEndsMission); Push (host) / Pull (member) results, then relaunch.

CMake: btl4lobby.cpp joins bt410_l4; that lib gets BT412_STEAM + the
Steamworks include under the gate. build-steam/ gitignored.

Deferred (untestable here -- needs Steam + multiple machines): the
host->member wire egg-feed marshal (InstallNetworkRace); a member currently
waits for a console connection nothing supplies, so a live host+member race
is blocked on it. The lobby object does not survive the per-mission
relaunch. docs/STEAM-3-MACHINE-TEST.md for BT not yet authored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-16 23:18:36 -05:00
co-authored by Claude Opus 4.8
parent 2f5870e486
commit a2949166ea
12 changed files with 769 additions and 31 deletions
+40 -9
View File
@@ -129,7 +129,8 @@ Verified after merge: clean build; solo front-end mode; loopback MP through the
`NetTransport_Get()`); (2) `BT412_STEAM=ON` config + build (compile-check of the
Steam transport TU against the vendored SDK; a live Steam session needs the Phase 6
lobby + 3 machines).
- **Phase 5 (front end) — FOUNDATION DONE 2026-07-14; marshal/menu/results IN PROGRESS.**
- **Phase 5 (front end) — DONE 2026-07-16 (5a5d).** Interactive menu + local egg builder
+ in-process marshal + results + single-binary loop all landed and boot-verified.
Landed the local **mission-egg builder** — the core "single-player without the
operator console" capability:
- `game/reconstructed/btl4fe.{hpp,cpp}`: catalogs (8 maps, 8 mechs + variants,
@@ -146,14 +147,44 @@ Verified after merge: clean build; solo front-end mode; loopback MP through the
Verified: zero-argument launch → `[frontend] built frontend.egg` → mission loads and
runs (ticks, gait, targeting); the generated egg is structurally identical to MP.EGG
(32×32/16×16 name bitmaps with real glyph pixels, all sections present).
**Remaining in Phase 5** (each substantial, deferred): interactive on-screen catalog
menu (RP412 `RPL4FE` is 1536 lines of render-loop UI); the in-process **LocalConsole
marshal** thread (mission clock + `StopMissionMessage` at expiry + single-binary
menu→race→results→menu loop); and the **score-intake + results screen**, which is
genuinely NEW for BT — BT has no working mission-end flow (mission-review msgID 0x18
is a stub, `scoreAward=0`); v1 should collect kills/deaths from the live Comm-MFD
`pilotList` tally at stop (see [[gauges-hud]], [[multiplayer]]).
- Phases 67: Steam lobby (`btl4lobby`) + packaging remain.
**Completed since (2026-07-16):**
- Interactive on-screen catalog **menu** (green-on-black GDI, `btl4fe.cpp`): map / mech /
color / time / weather / length groups + pilot-name edit, framed LAUNCH (and, under
Steam, HOST / JOIN) buttons. Zero-arg launch shows it; a chosen LAUNCH builds the egg.
- In-process **LocalConsole marshal** (`btl4console.{hpp,cpp}`): NOT a thread — it runs on
the engine's per-frame hook (`gPerFrameHook`, added to `engine/MUNGA/APPMGR.*`, called on
the game thread in `RunMissions`), so its `application->Dispatch(StopMissionMessage)` is
safe. Owns the mission clock and stops the race at the chosen `length=`; snapshots
per-pilot kills/deaths at the stop (`BTResolveRosterPilot`/`BTPilotKills`/`BTPilotDeaths`).
- **Score intake + results screen**: BT's own kills/deaths model (no `gConsoleScoreSink`
that is RP-layer; BT has no working mission-end wire flow, msgID 0x18 stays a stub). A
GDI "MISSION COMPLETE" scoreboard (`BTFrontEnd_ShowResults`) reads the marshal snapshot
(`BTLocalConsole_GetResult`/`GetResultName`).
- **Single-binary loop** = RELAUNCH per mission (`CreateProcessW` after the marshal stop),
NOT an in-process `for(;;)` — in-process re-init crashes on the stale reconstructed
`gBT*` globals (cdb-traced to `BTL4VideoRenderer::MakeEntityRenderables`
`gBTTerrainEntity`). Verified: 3 distinct PIDs across the menu→race→results→menu cycle.
- WinMain launch-mode branch (`BTFrontEnd_LastLaunchMode()`): 0 solo, 1 lobby host, 2
lobby member (see Phase 6).
- **Phase 6 (Steam lobby) — CODE LANDED 2026-07-16; live 3-machine test DEFERRED.**
`game/reconstructed/btl4lobby.{hpp,cpp}` (ported from RP412 `RPL4LOBBY`) builds both gates
— stubs without `BT412_STEAM`, full `ISteamMatchmaking` room under it (both configs
link clean). What works: the room screen; member data (`ip`/`cp`/`gp`/`nm`/`vh`/`cl`/`bd` =
FakeIP + fake console/game ports + persona + mech/color/badge); the nonced `go` launch
roster → `SteamNetTransport_RegisterPeer` for every peer; `Push`/`PullRaceResults` over
lobby data (`res` key) rebuilding the shared score sheet via `BTLocalConsole_ClearResults`/
`InjectResult`. The menu offers HOST/JOIN when `BTLobby_Available()` (Steam transport up,
installed by WinMain on `BT412STEAM` env). A host launch bakes every member into the egg's
`[pilots]` (mesh `FakeIP:1502` addresses, round-robin drop zones) via
`BTFrontEnd_SetHostedPilots`; a member enters as a network pod on `:1501`
(`SetNetworkCommonFlatAddress` + `gConsoleLossEndsMission=True`).
**Deferred / not built:** the host→member **wire egg-feed marshal** (`InstallNetworkRace`
the owner streaming eggs + RunMission to remote pods, as `tools/btconsole.py` does). Without
it a member waits for a console connection nothing supplies, so a live host+member race
is blocked on it. The lobby object does NOT survive the per-mission relaunch (the
single-binary limitation — everyone returns to a fresh menu, not the room).
`docs/STEAM-3-MACHINE-TEST.md` for BT is not yet authored.
- Phase 7: packaging (`pack-dist.ps1`), KeyLight, release — remain.
## The seams (what plugs in where) [T0 unless noted]