The lobby could stage a room but the launched mission never fed the members.
BTLocalConsole_InstallNetworkMission (btl4console.cpp) makes the host play the
arcade console in-process over the NetTransport seam (Winsock TCP or Steam SDR):
- connect to each member's console channel (ip[:port] from BT412HOSTPODS);
- feed each the chunked egg (NetworkManager::ReceiveEggFileMessage, \n->NUL
wire image like tools/btconsole.py), resending until it ACKs;
- poll member state (StateQueryMessage); when the whole mesh is staged at
WaitingForLaunch, dispatch RunMission to every member + locally at once;
- StopMission at expiry (members first, then self after a short grace);
- scores are BT's kills/deaths snapshotted from the *meshed* roster at the
stop -- no EndMission wire intake (that flow is a BT stub; the mesh already
put every pilot in the host's roster). The owner's own pod is fed locally
via L4NetworkManager::FeedLocalEgg.
Engine change (ported 1:1 from RP412): gConsoleMarshalsLaunch (APPMGR.h/.cpp) +
the `!gConsoleMarshalsLaunch &&` guard in APP.cpp's WaitingForLaunch self-launch.
The owner has no console connection to itself, so without this it would
self-launch before the mesh staged and never send the coordinated RunMission.
Default False = stock behavior; solo boot un-regressed.
WinMain host path (btl4main.cpp) now honors BT412HOSTPODS (+BT412HOSTPORT) for
the lobby host AND a classic-LAN host: SetNetworkCommonFlatAddress +
InstallNetworkMission, falling back to a solo marshal if no member is reachable.
Verified (loopback): two `btl4.exe -net` pods fed by tools/btconsole.py reach
"All connections completed!" and run after the engine change -- the exact
protocol + launch handshake the marshal uses. Both gates build+link; the
Release dist boots and the Steam transport comes up. The live multi-machine
Steam mission (FakeIP mesh + pilot-slot matching) is untestable here -- see the
new docs/STEAM-3-MACHINE-TEST.md. Dist README updated: multiplayer is now
"newly implemented, please test" rather than deferred.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
2.3 KiB
C++
47 lines
2.3 KiB
C++
//===========================================================================//
|
|
// btl4console.hpp -- BT412 in-process LocalConsole marshal.
|
|
//
|
|
// A front-end-launched solo mission has no operator console, so the mission
|
|
// clock would count up forever. This marshal plays the console's role in
|
|
// process: it watches the mission via the engine's per-frame hook
|
|
// (gPerFrameHook, called on the game thread in RunMissions) and dispatches
|
|
// StopMissionMessage when the selected length expires, exactly as the arcade
|
|
// console did. The single-binary WinMain loop then collects the result and
|
|
// cycles back to the setup menu.
|
|
//===========================================================================//
|
|
#ifndef BTL4CONSOLE_HPP
|
|
#define BTL4CONSOLE_HPP
|
|
|
|
// Arm the marshal for the next mission: it stops the mission after
|
|
// `mission_seconds` (0 = endless -- never auto-stops). Registers the
|
|
// per-frame hook.
|
|
void BTLocalConsole_Install(int mission_seconds);
|
|
|
|
// Arm the marshal as the HOST/OWNER of a NETWORKED mission: connect to every
|
|
// member pod's console channel (comma-separated "ip[:port]" list), then act as
|
|
// the arcade console -- feed each its egg, hold the mesh at WaitingForLaunch,
|
|
// launch everyone together, and StopMission at expiry. The owner's own pod is
|
|
// fed `egg_path` locally. Returns 1 on success, 0 if the egg is unreadable or
|
|
// a member could not be reached (caller should fall back to a solo mission).
|
|
int BTLocalConsole_InstallNetworkMission(int mission_seconds,
|
|
const char *egg_path, const char *remote_pod_list);
|
|
|
|
// True once the marshaled mission has stopped (time expired, or ended some
|
|
// other way while armed) -- the WinMain loop cycles back to the menu.
|
|
int BTLocalConsole_MissionCompleted();
|
|
|
|
// Final scores snapshotted at the stop (roster order; slot 0 = local pilot).
|
|
int BTLocalConsole_ResultCount();
|
|
int BTLocalConsole_GetResult(int index, int *kills, int *deaths);
|
|
const char *BTLocalConsole_GetResultName(int index);
|
|
|
|
// Lobby (owner) rebuilds the sheet from the collated wire scores before the
|
|
// shared results screen: clear, then inject each pod's name/kills/deaths.
|
|
void BTLocalConsole_ClearResults();
|
|
void BTLocalConsole_InjectResult(int slot, int kills, int deaths, const char *name);
|
|
|
|
// Drop the marshal + clear the per-frame hook.
|
|
void BTLocalConsole_Uninstall();
|
|
|
|
#endif // BTL4CONSOLE_HPP
|