Two player requests from the six-player night, one cause between them: the lobby treated hosting as somewhere you GO, and a role you could only have by being the machine that went there. Hosting no longer leaves the setup page. HOST STEAM GAME claims the lobby and stays put: the button becomes CLOSE LOBBY, joiners list under GAME LENGTH as they arrive (callsign, vehicle, a cam tag, and WRONG BUILD where launch would refuse - the reasons launch might say no, standing on the same screen as the launch button), and the track, weather and length stay changeable the whole time, republished to the members' rooms as they change. LAUNCH GAME launches the whole room from right there, and after the race the host lands back on the same page, lobby still open, roster still live. The room screen still exists - for members, whose flow is untouched. Mechanically: RPL4Lobby_Host's create-then-run-the-room split into HostOpen (create, publish, return) plus Pump/PublishSetup/RosterLines/ HostLaunch/Leave, with the owner-launch and leave blocks extracted from the room's message loop so both screens call the same code. The menu gets a timer that pumps Steam callbacks - nothing else pumps them with no room running - and republishes dirty picks at most every 1.5s, because Steam throttles chatty writers. One wrinkle: the lobby publishes through the RPL4FrontEnd_* accessors, which read globals the menu only wrote on the way OUT, so publishing from a live menu syncs them first or every publish would carry the previous visit's picks. And a member's Live Cam pick now works. It was host-only by design - the pick published as member data and the room displayed it, but the egg builder never read it, so a member who chose Live Cam raced their default loadout instead (the "default Quark - red" Cyd was listed as). The pick now rides the whole chain - lobby row, hosted-pilot table, egg entry as hostType=1 / vehicle=camera - and the member machine sets its own cockpit from its own pick at launch, before the renderers build, exactly as the host and playback already did. One rule holds it together: SOMEBODY has to race. If every pilot picks cam, every pick is stripped and the log says so - a grid of cameras has nothing to point at, and is also the shape known to hang the map load. The playtest launch failures while a member had cam picked are not directly explained - no logs were kept from those attempts - but the half-implemented state they ran in (flag published, egg ignoring it) is exactly the seam this closes, and the failure cannot recur in that form: the pick is now either honoured everywhere or stripped everywhere. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
107 lines
3.9 KiB
C
107 lines
3.9 KiB
C
#pragma once
|
|
|
|
#include "..\munga\style.h"
|
|
|
|
//########################################################################
|
|
//########################### RPL4 Steam Lobby ###########################
|
|
//########################################################################
|
|
//
|
|
// The multiplayer front door (docs/RP412-FRONTEND-DESIGN.md section 3):
|
|
// an ISteamMatchmaking lobby stands in for the arcade's Site Management
|
|
// screen. Every member publishes its FakeIP + fake ports + persona +
|
|
// loadout as lobby member data; the 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 path (it builds the egg and marshals), the
|
|
// members as network pods waiting for the owner's console connection.
|
|
//
|
|
// The lobby OBJECT outlives races - that is the point of the single
|
|
// binary. After a race everyone lands back in the room for the next
|
|
// launch.
|
|
//
|
|
// Compiled to stubs without RP412_STEAM.
|
|
//
|
|
enum RPL4LobbyOutcome
|
|
{
|
|
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 pod
|
|
};
|
|
|
|
// True when the Steam transport is up (lobby UI is offered).
|
|
Logical
|
|
RPL4Lobby_Available();
|
|
|
|
// True when this build has Steam and environ.ini asked for it, whether
|
|
// or not it actually came up. The menu offers the lobby buttons on this
|
|
// and greys them out on Available() - a player who turned Steam on and
|
|
// then launched without the client running should be told so, not left
|
|
// looking at a menu that quietly has two fewer buttons than the last
|
|
// time they saw it.
|
|
Logical
|
|
RPL4Lobby_Configured();
|
|
|
|
// True while we sit in a lobby (races return to the room).
|
|
Logical
|
|
RPL4Lobby_InRoom();
|
|
|
|
//------------------------------------------------------------------------
|
|
// Hosting, from the setup menu.
|
|
//
|
|
// The host never leaves the configuration page: HostOpen claims the lobby
|
|
// and returns immediately, the menu keeps showing (and changing) the
|
|
// mission, joiners appear under GAME LENGTH via RosterLines, and LAUNCH
|
|
// GAME goes through HostLaunch. The room screen is for members only.
|
|
//------------------------------------------------------------------------
|
|
|
|
// Create the lobby and publish our row + the mission setup. True on
|
|
// success (also true if already in one). Does not open any window.
|
|
Logical
|
|
RPL4Lobby_HostOpen();
|
|
|
|
// True when we are in a lobby we own.
|
|
Logical
|
|
RPL4Lobby_IsOwner();
|
|
|
|
// Run the Steam callbacks once - the menu's timer calls this so member
|
|
// joins/leaves and their data show up while no room screen is pumping.
|
|
void
|
|
RPL4Lobby_Pump();
|
|
|
|
// Republish our member row and (as owner) the mission setup. Call after
|
|
// the host changes anything on the menu, so members' rooms track it.
|
|
void
|
|
RPL4Lobby_PublishSetup();
|
|
|
|
// The roster as display lines ("callsign vehicle [cam|WRONG BUILD]").
|
|
// Returns the number written, 0 when not in a lobby.
|
|
int
|
|
RPL4Lobby_RosterLines(char lines[][48], int max_lines);
|
|
|
|
// The owner's go: verify everyone, publish the roster, prime the hosted
|
|
// race. False (and a log line saying who) when the room is not ready.
|
|
Logical
|
|
RPL4Lobby_HostLaunch();
|
|
|
|
// Leave the lobby and clear the hosted-race environment.
|
|
void
|
|
RPL4Lobby_Leave();
|
|
|
|
// Find-and-join a lobby, then run the room screen (members).
|
|
int
|
|
RPL4Lobby_Join(HINSTANCE instance, HWND main_window);
|
|
|
|
// Re-enter the room of the lobby we are already in (post-race).
|
|
int
|
|
RPL4Lobby_Room(HINSTANCE instance, HWND main_window);
|
|
|
|
// Post-race score sheet: the owner publishes its console's results
|
|
// into lobby data; members pull them into the local results intake so
|
|
// the same results screen shows everywhere. Both are no-ops when not
|
|
// in a lobby (or not the respective role).
|
|
void
|
|
RPL4Lobby_PushRaceResults();
|
|
void
|
|
RPL4Lobby_PullRaceResults();
|