An online room this build hosts asks the lobby server for transport "host"
(match_caps.relay): the host carries the match on its own UDP port and
guests dial it; the server's relay (SFU) is the fallback when a guest's
probe fails (recomp-net-server WS_LOBBY.md "Host relay"). The mechanics are
recomp-net's recomp_net/host_relay.h, pinned here (lib/recomp-net b0751b7);
this engine's own lobby-client copy gets the same glue as rnet_lobby_client:
the cap (emitted only when asked), the launch's transport ->
PsxLobbyJoinInfo.transport_host (force_input_relay 0; the host accepts
first / hubs instead of dialling the guest's LAN address), each seat's
published path / path_fresh, host_relay_step() from psx_lobby_pump, and
unmap on leave / disconnect.
psx_netplay: transport_host takes the LAN / hub path instead of the "MotK
online needs the SFU" rule. main.cpp: relay_host_get/set + relay_status
for recomp-ui (Network Settings / MATCH SETTINGS / ROOM "Match Relay"),
transport_host on the launch and into PsxNetplayConfig, and the
host==guest-advertise SFU inference skipped on a host launch; all under
RECOMP_LAUNCHER_HAS_HOST_RELAY so older recomp-ui pins still build.
Compile-checked against workspace recomp-ui 58604b0 (MOTK scratch
configure: full build and link).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Host may sit in a spectator seat: session slot 0 stays the sim authority
with a muted pad and no port; slot->port map keeps players on the port of
their lobby seat (host first). Rematch path copies the same plan.
- Seat self-service on LAN (MOTK5 SEATMOVE / SWAPASK / SWAPANS / SWAPRES)
relayed by the host; online swap requests accept a gallery seat as target.
- Lobby chat ring + join/leave lines; country codes from the server.
- Keybinds: a key drives one input per player (binding S to Cross unbinds it
from Circle), and keybinds.ini is re-read after the rematch launcher too.
- LAN registry file anchored to the exe directory.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1dT6h1ZshMVUUVKTPxsCD
Seat 1 (P2) can bring its LOCAL slot-1 card to a match: it uploads the card
to the host at launch over the new recomp-net MEMCARD op, the host installs
it as the match's slot-2 card, and the usual card broadcast carries it to
everyone. The host's real slot-2 file is rebound to netplay/guest_card2.mcd
for the session and restored on shutdown; guests already sandbox both slots.
Lobby side: a per-seat memcard_offer on set_ready (has_card, share), a host
allow flag in match_caps, and guest_memcard_active settled ONCE by the host
at start and shipped with the launch, so a toggle racing the start cannot
split the room. LAN carries the same over MOTK5 UPDATE / MEMCARD / JOIN
tail / a trailing START line. PSX_NET_GUEST_MEMCARD=1 for CLI sessions;
a host waiting on a card that never comes stalls at a named phase
(mc_guest_wait), not a silent "ok".
Two latent guest-sandbox bugs fixed on the way: a disabled slot 2 had no
bound path, so a host blob carrying a card for it failed to import and the
guest stalled forever; and leaving the sandbox re-bound a disabled slot to
the sandbox file. Both slots are now bound in the sandbox and restored per
slot (memcard_rebind_path, which can also unbind).
Lobby chat: the client keeps a ring fed by the server's echo (op:chat);
LAN rooms relay through the host (MOTK5 CHATREQ guest->host, MOTK5 CHAT
host->everyone). Wired to the launcher's chat_send/chat_count/chat_get.
Also carries the spectator-seat work that was in the tree alongside this
(spectator seats in the lobby client, spectator_wire_slot in the launch).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1dT6h1ZshMVUUVKTPxsCD
Bumps recomp-net so empty lobby seats no longer block READY/admit; launch
builds the mask from seated members (online + LAN).
Co-authored-by: Cursor <cursoragent@cursor.com>
it stops checking the entire PSX disc for full hash check every time the launcher runs, assuming the user's hash checked it when selecting the disc the first time and saving it to settings, so it just validates the file name and size instead, then it shares lifecycle with the launcher and the game to load the game faster, and several optimizations were made to loadstate paths which I think in the end relied on reanchoring host timings to the restored clock that came with the state
Games pass MAX_PLAYERS (2..5, default 2) to bake PSX_MAX_PLAYERS. SCPH-1070
multitap maps pads 0–3 on port 1 and pad 4 on port 2. Lobby max_slots and
recomp-net slot_count follow the game player count; MotK stays at 2.
Co-authored-by: Cursor <cursoragent@cursor.com>