Files
RP412/RP_L4/RPL4LOBBY.h
T
CydandClaude Opus 5 47817ca6f5 The setup page is the host's room
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>
2026-08-11 21:34:12 -05:00

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();