Terminology: BattleTech missions, not races
"Race" is Red Planet's term (it's a racing game) and rode in with the
RPL4LOBBY port. In BattleTech the gameplay unit is a MISSION. Sweep it out
of the front-end / lobby / marshal code + the roadmap and steamification
digest: rename the public API BTLobby_Push/PullRaceResults ->
Push/PullMissionResults, the internal PrimeHostedRace -> PrimeHostedMission,
the deferred marshal InstallNetworkRace -> InstallNetworkMission, and the
user-facing strings ("STEAM MISSION LOBBY", "L A U N C H M I S S I O N",
"HOST/JOIN STEAM MISSION"). Comments follow. No behavior change; both gates
(default + BT412_STEAM) still build + link clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -154,7 +154,7 @@ Verified after merge: clean build; solo front-end mode; loopback MP through the
|
||||
- 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
|
||||
safe. Owns the mission clock and stops it 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
|
||||
@@ -163,7 +163,7 @@ Verified after merge: clean build; solo front-end mode; loopback MP through the
|
||||
- **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.
|
||||
`gBTTerrainEntity`). Verified: 3 distinct PIDs across the menu→mission→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.**
|
||||
@@ -171,16 +171,16 @@ Verified after merge: clean build; solo front-end mode; loopback MP through the
|
||||
— 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
|
||||
roster → `SteamNetTransport_RegisterPeer` for every peer; `Push`/`PullMissionResults` 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` —
|
||||
**Deferred / not built:** the host→member **wire egg-feed marshal** (`InstallNetworkMission` —
|
||||
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
|
||||
it a member waits for a console connection nothing supplies, so a live host+member mission
|
||||
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.
|
||||
|
||||
@@ -139,7 +139,7 @@ identical-to-baseline → take RP412's file verbatim, diverged → hand-apply th
|
||||
console on its own thread over NetTransport — egg chunks + ACK, RunMission ×2
|
||||
(mirror btconsole.py), stays connected (fixes the console-loss listener bug for
|
||||
solo), owns the mission clock, StopMission at `length=` expiry, launcher-role loop,
|
||||
`InstallNetworkRace` marshal for remote pods.
|
||||
`InstallNetworkMission` marshal for remote pods.
|
||||
- **5c Score intake — genuinely new for BT** (no mission-end flow exists): a
|
||||
`gConsoleScoreSink` equivalent through `BTPlayer`; v1 results screen = kills/deaths
|
||||
per pilot from the Comm-MFD `pilotList` tally at stop.
|
||||
@@ -160,7 +160,7 @@ identical-to-baseline → take RP412's file verbatim, diverged → hand-apply th
|
||||
> `Application::StopMissionMessage` at the chosen length; it snapshots per-pilot
|
||||
> kills/deaths at the stop (BT's own score model — msgID 0x18 stays a stub). The
|
||||
> single-binary loop is a RELAUNCH per mission (`CreateProcessW`; avoids the stale
|
||||
> `gBT*`-global re-init crash), showing a GDI "MISSION COMPLETE" scoreboard between races.
|
||||
> `gBT*`-global re-init crash), showing a GDI "MISSION COMPLETE" scoreboard between missions.
|
||||
> WinMain (`game/btl4main.cpp`) wires front-end-mode detection, the marshal arm, the
|
||||
> results screen + relaunch, and the launch-mode branch (solo/host/member). Details in
|
||||
> `context/steamification.md`.
|
||||
@@ -170,7 +170,7 @@ identical-to-baseline → take RP412's file verbatim, diverged → hand-apply th
|
||||
- **`game/reconstructed/btl4lobby.cpp`** (skeleton: `RPL4LOBBY.cpp` — mechanics
|
||||
generic): lobby owner = console; member data = FakeIP + fake console/game ports +
|
||||
persona + loadout (**mech**/color/badge); nonced launch roster → `RegisterPeer` all →
|
||||
owner hosts via egg+marshal, members join as network pods; Push/PullRaceResults
|
||||
owner hosts via egg+marshal, members join as network pods; Push/PullMissionResults
|
||||
distribute the score sheet. FE gains HOST/JOIN screens.
|
||||
- Author `docs/STEAM-3-MACHINE-TEST.md` for BT (adapt RP412's; keep its gotchas:
|
||||
disable Steam Input on 480, one Steam account per machine, abort key).
|
||||
@@ -183,14 +183,14 @@ identical-to-baseline → take RP412's file verbatim, diverged → hand-apply th
|
||||
> `BT412_STEAM`, full ISteamMatchmaking room under it). Built: the room screen (green-on-black,
|
||||
> like the menu), member data exchange (FakeIP + fake console/game ports + persona +
|
||||
> mech/color/badge), the nonced "go" launch roster → `SteamNetTransport_RegisterPeer` all peers,
|
||||
> and Push/PullRaceResults over lobby data. The menu shows HOST/JOIN when `BTLobby_Available()`
|
||||
> and Push/PullMissionResults over lobby data. The menu shows HOST/JOIN when `BTLobby_Available()`
|
||||
> (Steam transport up); a launch routes through `BTFrontEnd_LastLaunchMode()`: **host** builds the
|
||||
> egg with every member as a `[pilots]` entry + owns the marshal clock, **member** enters as a
|
||||
> network pod on `:1501` (`SetNetworkCommonFlatAddress` + `gConsoleLossEndsMission`). WinMain
|
||||
> installs the Steam transport on `BT412STEAM` env. **Remaining / deferred:** the host→member
|
||||
> **wire egg-feed marshal** (`InstallNetworkRace` — the owner streaming eggs to remote pods) is
|
||||
> **wire egg-feed marshal** (`InstallNetworkMission` — the owner streaming eggs to remote pods) is
|
||||
> NOT built; a member currently waits for a console connection that only that marshal provides, so
|
||||
> a live host+member race needs it. The lobby OBJECT does not survive the per-mission relaunch
|
||||
> a live host+member mission needs it. The lobby OBJECT does not survive the per-mission relaunch
|
||||
> (documented single-binary limitation — everyone lands on a fresh menu, not back in the room).
|
||||
> `docs/STEAM-3-MACHINE-TEST.md` for BT is not yet authored. Details in `context/steamification.md`.
|
||||
|
||||
|
||||
+7
-7
@@ -370,7 +370,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
|
||||
// STEAM NETWORKING (BT412_STEAM build + BT412STEAM env): bring the Steam
|
||||
// transport up BEFORE the front end so the lobby is available (its HOST/JOIN
|
||||
// buttons appear only when a FakeIP was allocated) and the race mesh routes
|
||||
// buttons appear only when a FakeIP was allocated) and the mission mesh routes
|
||||
// over SDR/FakeIP. Any failure silently leaves the process on Winsock TCP.
|
||||
#ifdef BT412_STEAM
|
||||
if (getenv("BT412STEAM") != NULL && atoi(getenv("BT412STEAM")) != 0)
|
||||
@@ -549,8 +549,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
extern void BTFrontEnd_ShowResults();
|
||||
extern void BTLocalConsole_Install(int mission_seconds);
|
||||
extern int BTLocalConsole_MissionCompleted();
|
||||
extern void BTLobby_PushRaceResults();
|
||||
extern void BTLobby_PullRaceResults();
|
||||
extern void BTLobby_PushMissionResults();
|
||||
extern void BTLobby_PullMissionResults();
|
||||
|
||||
int launch_mode = 0; // 0 solo, 1 lobby host, 2 lobby member
|
||||
if (front_end_mode)
|
||||
@@ -649,15 +649,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
// The mission ran (not the menu-closed early return) if we front-end-moded
|
||||
// and the window still lives (a user window-close destroys hWnd -> quit, no
|
||||
// relaunch). Solo/host end via the local marshal; a member ends when the
|
||||
// host stops the race (console-loss), so it has no local completion flag.
|
||||
// host stops the mission (console-loss), so it has no local completion flag.
|
||||
bool mission_ran = front_end_mode && IsWindow(hWnd)
|
||||
&& (launch_mode == 2 || BTLocalConsole_MissionCompleted());
|
||||
if (mission_ran)
|
||||
{
|
||||
// Distribute (host) or collect (member) the shared score sheet over the
|
||||
// lobby so every pod shows the same board; solo needs neither.
|
||||
if (launch_mode == 1) BTLobby_PushRaceResults();
|
||||
else if (launch_mode == 2) BTLobby_PullRaceResults();
|
||||
if (launch_mode == 1) BTLobby_PushMissionResults();
|
||||
else if (launch_mode == 2) BTLobby_PullMissionResults();
|
||||
|
||||
// Scoreboard first (kills/deaths snapshotted at the stop), then relaunch.
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
@@ -672,7 +672,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
{
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
std::cout << "[launcher] mission ended -- relaunched for the next race"
|
||||
std::cout << "[launcher] mission ended -- relaunched for the next mission"
|
||||
<< std::endl << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace
|
||||
(GetTickCount() - gStartTick) >= (unsigned long)(gMissionSeconds * 1000))
|
||||
{
|
||||
// The console clock expired: snapshot the final scores (the
|
||||
// game state is still live here), then stop the race exactly
|
||||
// game state is still live here), then stop the mission exactly
|
||||
// as the arcade console did (StopMissionMessage on our pod).
|
||||
DEBUG_STREAM << "[marshal] time expired -- stopping mission\n" << std::flush;
|
||||
SnapshotResults();
|
||||
@@ -114,7 +114,7 @@ void BTLocalConsole_Install(int mission_seconds)
|
||||
gStartTick = 0;
|
||||
gWatched = 0;
|
||||
// Marshaled: the in-process console owns the clock, so a console-loss
|
||||
// (there is none locally) would end the race -- harmless for solo.
|
||||
// (there is none locally) would end the mission -- harmless for solo.
|
||||
gConsoleLossEndsMission = True;
|
||||
gPerFrameHook = &ConsoleTick;
|
||||
DEBUG_STREAM << "[marshal] installed (length " << mission_seconds << "s)\n" << std::flush;
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// Defaults: a solo race on grass, one local pilot in a Black Hawk.
|
||||
// Defaults: a solo mission on grass, one local pilot in a Black Hawk.
|
||||
//---------------------------------------------------------------------------//
|
||||
void BTFeMission_Default(BTFeMission *mission)
|
||||
{
|
||||
@@ -369,7 +369,7 @@ int BTFeMission_WriteEgg(const BTFeMission *mission, const char *path)
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
// THE MINICONSOLE MENU -- the in-game race setup that replaces the operator
|
||||
// THE MINICONSOLE MENU -- the in-game mission setup that replaces the operator
|
||||
// console. A GDI-painted green-on-black terminal (RP412 RPL4FE pattern): the
|
||||
// catalogs render as clickable columns, a pilot-name edit box, and a LAUNCH
|
||||
// button; clicking LAUNCH fills a BTFeMission from the selections and writes
|
||||
@@ -424,8 +424,8 @@ const char *ItemName(int g, int i) {
|
||||
case GColor: return kMenuColors[i].name; case GTime: return kMenuTimes[i].name;
|
||||
case GWeather: return kMenuWeather[i].name; case GLength: return kMenuLengths[i].name;
|
||||
case GLaunch: return "L A U N C H";
|
||||
case GHost: return "HOST STEAM RACE";
|
||||
case GJoin: return "JOIN STEAM RACE";
|
||||
case GHost: return "HOST STEAM MISSION";
|
||||
case GJoin: return "JOIN STEAM MISSION";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//===========================================================================//
|
||||
// btl4fe.hpp -- BT412 in-game front end: local mission-egg builder.
|
||||
//
|
||||
// Replaces the external operator console for solo / host play: a race is
|
||||
// Replaces the external operator console for solo / host play: a mission is
|
||||
// configured from an in-process catalog and the mission egg is built LOCALLY
|
||||
// (the exact NotationFile the console used to stream), then fed through the
|
||||
// standard -egg load path (L4Application::SetEggNotationFileName).
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Ported from RP412 RPL4LOBBY: the ISteamMatchmaking room, member loadout
|
||||
// exchange (FakeIP + ports + persona + mech/color/badge), the launch roster,
|
||||
// and the post-race score sheet. Compiled to stubs without BT412_STEAM.
|
||||
// and the post-mission score sheet. Compiled to stubs without BT412_STEAM.
|
||||
//===========================================================================//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _WIN32_WINNT 0x0500
|
||||
@@ -23,8 +23,8 @@ int BTLobby_InRoom() { return 0; }
|
||||
int BTLobby_Host(void *, void *) { return LobbyRoomLeft; }
|
||||
int BTLobby_Join(void *, void *) { return LobbyRoomLeft; }
|
||||
int BTLobby_Room(void *, void *) { return LobbyRoomLeft; }
|
||||
void BTLobby_PushRaceResults() { }
|
||||
void BTLobby_PullRaceResults() { }
|
||||
void BTLobby_PushMissionResults() { }
|
||||
void BTLobby_PullMissionResults() { }
|
||||
|
||||
#else
|
||||
|
||||
@@ -45,8 +45,8 @@ extern int BTLocalConsole_GetResult(int index, int *kills, int *deaths);
|
||||
extern void BTLocalConsole_ClearResults();
|
||||
extern void BTLocalConsole_InjectResult(int slot, int kills, int deaths, const char *name);
|
||||
extern const char *BTLocalConsole_GetResultName(int slot);
|
||||
// (The remote-pod network-race marshal -- collating every pod's scores over the
|
||||
// wire -- is deferred; the owner publishes its local snapshot for now.)
|
||||
// (The remote-pod network-mission marshal -- collating every pod's scores over
|
||||
// the wire -- is deferred; the owner publishes its local snapshot for now.)
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -160,9 +160,9 @@ namespace
|
||||
members[i].gamePort, members[i].id.ConvertToUint64());
|
||||
}
|
||||
|
||||
// Owner side: prime the hosted-race env (BT412HOSTPODS/ADDR/PORT) + the
|
||||
// Owner side: prime the hosted-mission env (BT412HOSTPODS/ADDR/PORT) + the
|
||||
// hosted-pilot loadouts the front end feeds into the egg.
|
||||
void PrimeHostedRace(MemberInfo *members, int count) {
|
||||
void PrimeHostedMission(MemberInfo *members, int count) {
|
||||
static char pods_env[512], addr_env[64], port_env[32];
|
||||
CSteamID self = SteamUser()->GetSteamID();
|
||||
FEHostedPilot pilots[kMaxLobbyMembers]; int pilot_count = 0;
|
||||
@@ -205,7 +205,7 @@ namespace
|
||||
FillRect(mem, &cl, (HBRUSH) GetStockObject(BLACK_BRUSH)); SetBkMode(mem, TRANSPARENT);
|
||||
SelectObject(mem, room->titleFont); SetTextColor(mem, kGreenBright);
|
||||
RECT title = cl; title.top = cl.bottom/28; title.bottom = title.top + cl.bottom/10;
|
||||
DrawTextA(mem, "STEAM RACE LOBBY", -1, &title, DT_CENTER|DT_TOP|DT_SINGLELINE);
|
||||
DrawTextA(mem, "STEAM MISSION LOBBY", -1, &title, DT_CENTER|DT_TOP|DT_SINGLELINE);
|
||||
SelectObject(mem, room->textFont);
|
||||
int row_h = cl.bottom/16, top = cl.bottom/4, left = cl.right/4, right = 3*cl.right/4;
|
||||
char text[128];
|
||||
@@ -226,7 +226,7 @@ namespace
|
||||
:"Waiting for the host to launch...", -1, &hint, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
|
||||
HBRUSH frame = CreateSolidBrush(kGreenBright);
|
||||
if (IsOwner()) { FrameRect(mem, &room->launchRect, frame); SetTextColor(mem, kGreenBright);
|
||||
DrawTextA(mem, "L A U N C H R A C E", -1, &room->launchRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); }
|
||||
DrawTextA(mem, "L A U N C H M I S S I O N", -1, &room->launchRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); }
|
||||
FrameRect(mem, &room->leaveRect, frame); SetTextColor(mem, kGreenBright);
|
||||
DrawTextA(mem, "LEAVE LOBBY", -1, &room->leaveRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
|
||||
DeleteObject(frame);
|
||||
@@ -311,7 +311,7 @@ namespace
|
||||
}
|
||||
SteamMatchmaking()->SetLobbyData(gLobby, kGoKey, go);
|
||||
RegisterRoster(room.members, room.memberCount);
|
||||
PrimeHostedRace(room.members, room.memberCount);
|
||||
PrimeHostedMission(room.members, room.memberCount);
|
||||
outcome = LobbyLaunchHost; break;
|
||||
}
|
||||
}
|
||||
@@ -391,7 +391,7 @@ int BTLobby_Room(void *instance, void *main_window) {
|
||||
return RunRoom((HINSTANCE)instance, (HWND)main_window);
|
||||
}
|
||||
|
||||
void BTLobby_PushRaceResults() {
|
||||
void BTLobby_PushMissionResults() {
|
||||
if (!gInLobby || !IsOwner() || BTLocalConsole_ResultCount() == 0) return;
|
||||
SteamAPI_RunCallbacks();
|
||||
char sheet[700]; sprintf(sheet, "%d:", gLastGoNonce);
|
||||
@@ -405,7 +405,7 @@ void BTLobby_PushRaceResults() {
|
||||
gShownResultsNonce = gLastGoNonce;
|
||||
}
|
||||
|
||||
void BTLobby_PullRaceResults() {
|
||||
void BTLobby_PullMissionResults() {
|
||||
if (!gInLobby || IsOwner() || gLastGoNonce == gShownResultsNonce) return;
|
||||
const char *sheet = NULL; DWORD deadline = GetTickCount() + 8000;
|
||||
for (;;) {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
// console/game ports + persona + loadout (mech/color/badge) as lobby member
|
||||
// data; the lobby OWNER is the console. Launching writes a "go" roster into
|
||||
// lobby data -- each pod registers every peer with the Steam transport and
|
||||
// enters the race: the owner through the hosted-race marshal (it builds the
|
||||
// egg and marshals the members over the wire), the members as network pods
|
||||
// waiting for the owner's console connection. The lobby OBJECT outlives races
|
||||
// (the single-binary payoff -- after a race everyone lands back in the room).
|
||||
// enters the mission: the owner through the hosted-mission marshal (it builds
|
||||
// the egg and marshals the members over the wire), the members as network pods
|
||||
// waiting for the owner's console connection. The lobby OBJECT outlives
|
||||
// missions (the single-binary payoff -- afterward everyone lands back in the room).
|
||||
//
|
||||
// Compiled to stubs without BT412_STEAM (single-player + LAN -net unaffected).
|
||||
//===========================================================================//
|
||||
@@ -20,26 +20,26 @@ enum BTLobbyOutcome
|
||||
{
|
||||
LobbyRoomLeft = 0, // player left the lobby -> back to the menu
|
||||
LobbyRoomClosed, // window went away -> quit
|
||||
LobbyLaunchHost, // owner launched: hosted-race path is primed
|
||||
LobbyLaunchMember // owner launched: enter the race as a network pod
|
||||
LobbyLaunchHost, // owner launched: hosted-mission path is primed
|
||||
LobbyLaunchMember // owner launched: enter the mission as a network pod
|
||||
};
|
||||
|
||||
// True when the Steam transport is up (the lobby UI is offered in the menu).
|
||||
int BTLobby_Available();
|
||||
|
||||
// True while we sit in a lobby (races return to the room).
|
||||
// True while we sit in a lobby (missions return to the room).
|
||||
int BTLobby_InRoom();
|
||||
|
||||
// Create a lobby / find-and-join one, then run the room screen.
|
||||
int BTLobby_Host(void *instance, void *main_window);
|
||||
int BTLobby_Join(void *instance, void *main_window);
|
||||
|
||||
// Re-enter the room of the lobby we are already in (post-race).
|
||||
// Re-enter the room of the lobby we are already in (post-mission).
|
||||
int BTLobby_Room(void *instance, void *main_window);
|
||||
|
||||
// Post-race score sheet: the owner publishes its console's results into lobby
|
||||
// data; members pull them so the same results screen shows everywhere.
|
||||
void BTLobby_PushRaceResults();
|
||||
void BTLobby_PullRaceResults();
|
||||
// Post-mission score sheet: the owner publishes its console's results into
|
||||
// lobby data; members pull them so the same results screen shows everywhere.
|
||||
void BTLobby_PushMissionResults();
|
||||
void BTLobby_PullMissionResults();
|
||||
|
||||
#endif // BTL4LOBBY_HPP
|
||||
|
||||
Reference in New Issue
Block a user