Files
RP412/RP_L4/RPL4LOBBY.h
T
CydandClaude Opus 5 bc56ab5d48 Joining stays on the page too, and there is one host at a time
The other half of the setup-page-as-room work, both halves Cyd's ask.

JOIN STEAM GAME now sits down where it stands. The mission column -
scenario buttons and the track, time, weather and length drop-downs -
greys out and MIRRORS the host: the owner's published setup is mapped
from display names back to catalog indices on every heartbeat, so a
member watches the host change the track from inside their own setup
screen. The right column stays theirs - callsign, role, vehicle, colour,
badge, recording - and republishes as they change it, so the host's
roster tracks them the same way. LAUNCH GAME reads WAITING FOR THE HOST
and answers to nobody; the go arrives through the same timer, registers
the peers, and leaves the menu as a member launch. JOIN becomes LEAVE
LOBBY while seated. The room screen is now unused by both roles - kept
compiled, but nobody's flow reaches it.

A member's launch also now sets the RECORDING flag from its own pick.
Nothing on the member path ever set it before - the same
published-but-never-acted-on seam as the member cam - so a member who
ticked RECORDING recorded nothing, all the way back to the feature
landing.

One host at a time, while the flow is young: HOST STEAM GAME first runs
the same worldwide search joining uses, and if an RP412 lobby is already
open anywhere it refuses with A LOBBY IS ALREADY OPEN - JOIN IT rather
than opening a second room nobody can tell from the first.
Check-then-create is not airtight against two people clicking in the
same breath, but for a playtest group on voice it is the rule that was
asked for. If the host leaves, ownership would migrate silently and turn
some member's page into a host's - the member poll treats inheriting
ownership as THE LOBBY CLOSED and steps out instead.

The old modal exits are gone with it: steamAction, the post-loop
RPL4Lobby_Join call, and the member's room re-entry path. The menu's
modal loop now ends only at launch or close, whoever you are.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 22:08:32 -05:00

145 lines
5.0 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.
//------------------------------------------------------------------------
enum RPL4LobbyHostOpen
{
HostOpenFailed = 0, // Steam said no (or is not there)
HostOpenCreated, // the lobby is ours (also: already was)
HostOpenLobbyExists // one host at a time - join the open one
};
// Create the lobby and publish our row + the mission setup. Does not
// open any window. Refuses when an RP412 lobby is already open anywhere:
// one host at a time while the flow is young.
int
RPL4Lobby_HostOpen();
enum RPL4LobbyJoinOpen
{
JoinOpenNothingFound = 0, // no open lobby, or Steam said no
JoinOpenJoined, // seated; our row is published
JoinOpenWrongBuild // bounced at the door (dialog shown)
};
// Find the open lobby and sit down in it. Does not open any window: the
// setup menu stays up, mission column greyed and mirroring the host.
int
RPL4Lobby_JoinOpen(HWND main_window);
enum RPL4LobbyMemberPoll
{
MemberPollNothing = 0, // keep waiting
MemberPollLaunch, // the go arrived; peers registered - launch
MemberPollClosed // the lobby is over (host left / mismatch)
};
// A seated member's heartbeat question: anything to act on?
int
RPL4Lobby_MemberPoll();
// The host's published mission setup as display names (each buffer at
// least 48 bytes). Empty strings before the first publish arrives.
void
RPL4Lobby_GetSetup(
char *scenario, char *map, char *time_of_day,
char *weather, char *length);
// 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();