Walk-up callsign/mech request: join menu -> relay -> the session egg

The 1995 front-desk conversation, over the internet.  join.bat/
join_lan.bat now open a JOIN-GAME menu (the FE in BT_FE_JOIN trim:
CALLSIGN edit + the 18-mech list + JOIN); the choice relaunches into the
normal join with BT_CALLSIGN/BT_MECH env, rides the relay SEAT_REQUEST
as {callsign NUL mech NUL} (empty payload = roster defaults, wire-
compatible), and the relay validates the mech tag, HOLDS egg delivery
until every pod's console pad is connected, rewrites the egg via
eggmodel (vehicle= + rasterized callsign bitmaps, graceful no-PySide6
fallback) and streams it to all pads -- so every player's egg copy
carries every player's callsign.

The hold is gated on CONSOLE-PAD count, not game-side registration: a
pod HELLOs only after parsing the egg's roster, so a registration gate
deadlocks (hit live in the first run; pods animate in WAITING FOR
MISSION ASSIGNMENT during the hold).

Verified 2-node e2e (env-injected requests): thor/vulture requested over
roster defaults bhk1/ava1 -> relay held 1/2, released at 2/2, rewrote
both seats (relay log), the delivered egg carries vehicle=thor/vulture +
name=VIPER/MONGOOSE, both pods launched and built [cyl] tables for both
requested mechs.  Join-menu layout screenshot-verified; the menu's
click-through relaunch awaits live human verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-22 13:58:51 -05:00
co-authored by Claude Opus 4.8
parent eb618fe9e6
commit fcedc046cf
9 changed files with 239 additions and 25 deletions
+25 -2
View File
@@ -1719,10 +1719,33 @@ Logical L4NetworkManager::RelayRequestSeat()
}
Logical got_seat = False;
Logical roster_full = False;
// CALLSIGN/MECH REQUEST (2026-07-22, the walk-up desk over the wire):
// the join menu (BT_FE_JOIN) stashes the player's picks in BT_CALLSIGN
// / 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];
int seat_payload_length = 0;
{
const char *callsign = getenv("BT_CALLSIGN");
const char *mech_tag = getenv("BT_MECH");
if ((callsign != NULL && callsign[0] != '\0')
|| (mech_tag != NULL && mech_tag[0] != '\0'))
{
seat_payload_length = _snprintf(seat_payload,
sizeof(seat_payload) - 1, "%s%c%s%c",
callsign != NULL ? callsign : "", 0,
mech_tag != NULL ? mech_tag : "", 0);
if (seat_payload_length < 0)
seat_payload_length = sizeof(seat_payload) - 1;
}
}
RelayTcpEnvelope request;
request.route = RELAY_ROUTE_SEAT_REQUEST;
request.length = 0;
if (RelaySendAll(seat_socket, (const char *)&request, sizeof(request)))
request.length = (unsigned int)seat_payload_length;
if (RelaySendAll(seat_socket, (const char *)&request, sizeof(request))
&& (seat_payload_length == 0
|| RelaySendAll(seat_socket, seat_payload, seat_payload_length)))
{
char reply[sizeof(RelayTcpEnvelope) + 80];
int have = 0;