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
+31 -1
View File
@@ -9,6 +9,8 @@
#include <bt.hpp> // Application, application, DEBUG_STREAM
#pragma hdrstop
#include <string.h> // strncpy (result names from the wire)
#include "appmsg.hpp" // full Application::StopMissionMessage definition
#include "appmgr.hpp" // gPerFrameHook
#include "btl4console.hpp"
@@ -31,7 +33,7 @@ namespace
// Final scores snapshotted at the stop (roster order; slot 0 = local).
enum { maxResults = 8 };
struct Result { int kills, deaths; };
struct Result { int kills, deaths; char name[24]; };
Result gResults[maxResults];
int gResultCount = 0;
@@ -45,6 +47,7 @@ namespace
break; // past the last occupied roster slot
gResults[gResultCount].kills = BTPilotKills(pilot);
gResults[gResultCount].deaths = BTPilotDeaths(pilot);
gResults[gResultCount].name[0] = 0; // filled by the lobby (owner) if networked
++gResultCount;
}
DEBUG_STREAM << "[marshal] snapshot " << gResultCount << " pilot score(s)\n" << std::flush;
@@ -136,6 +139,33 @@ int BTLocalConsole_GetResult(int index, int *kills, int *deaths)
return 1;
}
const char *BTLocalConsole_GetResultName(int index)
{
if (index < 0 || index >= gResultCount)
return "";
return gResults[index].name;
}
// The lobby rebuilds the sheet from wire data (owner collates every pod's
// scores) before showing the shared results, so it needs to clear + refill.
void BTLocalConsole_ClearResults()
{
gResultCount = 0;
}
void BTLocalConsole_InjectResult(int slot, int kills, int deaths, const char *name)
{
if (slot < 0 || slot >= maxResults)
return;
gResults[slot].kills = kills;
gResults[slot].deaths = deaths;
gResults[slot].name[0] = 0;
if (name) { strncpy(gResults[slot].name, name, sizeof(gResults[slot].name) - 1);
gResults[slot].name[sizeof(gResults[slot].name) - 1] = 0; }
if (slot >= gResultCount)
gResultCount = slot + 1;
}
void BTLocalConsole_Uninstall()
{
gPerFrameHook = 0;