Lobby loop: auto-rejoin between rounds + seat reclaim + live mission edits
The between-rounds arcade flow (first-playtest-night field request): at
mission end every pod exited, seats dropped, and every round required
everyone to re-run join.bat with no way to adjust the mission.
1. AUTO-REJOIN: StopMission (operator END / mission clock -- NOT a
window close) sets gBTMissionStoppedByConsole; after the matchlog
upload btl4main relaunches the pod into the join wait with the same
cmdline (BT_CALLSIGN/BT_MECH ride the inherited environment).
2. SEAT RECLAIM: the assigned tag is mirrored file-scope
(BTRelaySelfTag) and re-presented as the 3rd SEAT_REQUEST payload
field (BT_SEAT_CLAIM); the relay holds a dropped seat for its tag
for 90s and a returning player gets their EXACT seat back -- static
ordering across rounds, the real-pod model. Non-claim joiners skip
reclaim-held seats.
3. LIVE MISSION EDITS: the console gains "Apply mission settings"
(enabled while a session runs) writing arena/time/weather/length
into the session egg; the relay re-reads the file at round reset and
egg release (roster shape locked mid-session).
Verified 2-pod 3-round: pods self-relaunched after each clock end; the
SECOND-to-rejoin still reclaimed its original seat (ordering held); the
between-rounds edit landed ("mission length now 75s"). Known edge
noted in the KB: a stale ready flag from a not-yet-exited old conn can
satisfy the launch gate mid-rejoin -- operators launch on green dots.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fa935777cc
commit
8368163b04
@@ -1688,6 +1688,16 @@ void
|
||||
Check(message);
|
||||
Verify(message->messageID == StopMissionMessageID);
|
||||
|
||||
// AUTO-REJOIN flag (2026-07-23): a StopMission (operator END or the
|
||||
// mission clock) is the ARCADE end of a round -- distinct from the player
|
||||
// closing the window. btl4main relaunches into the join wait when set,
|
||||
// so the same players flow into the next round without re-running
|
||||
// join.bat (and reclaim their seats -- see L4NET BT_SEAT_CLAIM).
|
||||
{
|
||||
extern int gBTMissionStoppedByConsole;
|
||||
gBTMissionStoppedByConsole = 1;
|
||||
}
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// If the application is already stopping then ignore the message
|
||||
|
||||
@@ -612,6 +612,21 @@ void BTRelayRememberGameSocket(SOCKET game_socket)
|
||||
s_relayGameSocketForReady = game_socket;
|
||||
}
|
||||
|
||||
// The assigned seat tag, mirrored file-scope for the between-rounds relaunch
|
||||
// (the L4NetworkManager -- and its relaySelf -- is gone by then).
|
||||
static char s_relaySelfTag[64] = "";
|
||||
|
||||
void BTRelayRememberSelfTag(const char *tag)
|
||||
{
|
||||
strncpy(s_relaySelfTag, tag, sizeof(s_relaySelfTag) - 1);
|
||||
s_relaySelfTag[sizeof(s_relaySelfTag) - 1] = 0;
|
||||
}
|
||||
|
||||
const char *BTRelaySelfTag(void)
|
||||
{
|
||||
return s_relaySelfTag;
|
||||
}
|
||||
|
||||
void BTRelayNotifyReady(void)
|
||||
{
|
||||
static int s_ready_sent = 0;
|
||||
@@ -1777,18 +1792,24 @@ Logical L4NetworkManager::RelayRequestSeat()
|
||||
// / BT_MECH; they ride the seat request as {callsign NUL mech NUL} and
|
||||
// the relay writes them into the session egg before it releases eggs.
|
||||
// Empty payload (no env) = the operator's roster defaults, as before.
|
||||
char seat_payload[64];
|
||||
char seat_payload[128];
|
||||
int seat_payload_length = 0;
|
||||
{
|
||||
const char *callsign = getenv("BT_CALLSIGN");
|
||||
const char *mech_tag = getenv("BT_MECH");
|
||||
// SEAT RECLAIM (2026-07-23): after a round the auto-rejoin carries
|
||||
// the previous seat tag -- the relay gives the SAME seat back so
|
||||
// ordering stays static across rounds (the real-pod model).
|
||||
const char *claim = getenv("BT_SEAT_CLAIM");
|
||||
if ((callsign != NULL && callsign[0] != '\0')
|
||||
|| (mech_tag != NULL && mech_tag[0] != '\0'))
|
||||
|| (mech_tag != NULL && mech_tag[0] != '\0')
|
||||
|| (claim != NULL && claim[0] != '\0'))
|
||||
{
|
||||
seat_payload_length = _snprintf(seat_payload,
|
||||
sizeof(seat_payload) - 1, "%s%c%s%c",
|
||||
sizeof(seat_payload) - 1, "%s%c%s%c%s%c",
|
||||
callsign != NULL ? callsign : "", 0,
|
||||
mech_tag != NULL ? mech_tag : "", 0);
|
||||
mech_tag != NULL ? mech_tag : "", 0,
|
||||
claim != NULL ? claim : "", 0);
|
||||
if (seat_payload_length < 0)
|
||||
seat_payload_length = sizeof(seat_payload) - 1;
|
||||
}
|
||||
@@ -1850,6 +1871,8 @@ Logical L4NetworkManager::RelayRequestSeat()
|
||||
{
|
||||
memcpy(relaySelf, tag, tag_max);
|
||||
relaySelf[tag_max] = '\0';
|
||||
extern void BTRelayRememberSelfTag(const char *);
|
||||
BTRelayRememberSelfTag(relaySelf);
|
||||
DEBUG_STREAM << "[relay] seat ASSIGNED: '" << relaySelf
|
||||
<< "'\n" << std::flush;
|
||||
got_seat = True;
|
||||
|
||||
Reference in New Issue
Block a user