Files
BT411/context/steam-networking.md
T
arcattackandClaude Opus 5 9bb95d8580 steam-networking KB: the first real multi-player field verification (night 4)
Three back-to-back Steam lobbies, 3+ players, host-and-join, no operator
console: launch worked, DAMAGE APPLIED (previously suspected dead over Steam),
2 kills, clean round end, next mission launched.  Records what worked, the one
genuinely Steam-side defect found (#68 silent exit on a failed join), and the
triage lesson -- a bug found in a Steam lobby is only a Steam bug if it lives
in the lobby/token/transport layer; the three replication symptoms that night
produced (#67/#70/#55) are above the seam and would reproduce on the relay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 06:55:14 -05:00

4.2 KiB

id, title, status, source_sections, related_topics, key_terms, open_questions
id title status source_sections related_topics key_terms open_questions
steam-networking Steam networking — the BT_STEAM wire (transport + lobby) living docs/GLASS_COCKPIT.md §4; docs/STEAM_TEST.md; commits e79e8fa/48ede2f/f703bb1
glass-cockpit
multiplayer
PadRIO
miniconsole
live 2-account cross-machine session (docs/STEAM_TEST.md) — the step-4 exit criterion

Steam networking — the BT_STEAM wire

Internet MP for the glass cockpit (dev tooling; gate BT_STEAM, requires BT_GLASS). Status: CODE COMPLETE 2026-07-18; single-machine verified; live 2-machine test pending.

The three layers

  1. The wire seam (L4NET.CPP, always compiled): file-local BTNetSend/Recv/Accept/Close wrappers around the 9 raw Winsock sites — pure code motion when OFF; under BT_STEAM each offers the op to the transport first. Est. delegates: CheckSocket (peer address), OpenConnection TCP_OPEN head, GetMyAddress (self token).
  2. The transport (engine/MUNGA_L4/L4STEAMNET.*, gated): ISteamNetworkingSockets pseudo-SOCKETs (0x5EA0xxxx); engine TCP byte stream over reliable-NoNagle messages with per-connection reassembly rings (recv: empty→WSAEWOULDBLOCK, closed→0); listen channels console=0 / game=1 (CreateListenSocketP2P); install on env BT_STEAM_NET=1; degrades to Winsock at every failure. Pump = SteamAPI_RunCallbacks AND sockets RunCallbacks (the general dispatch carries the async results — sockets-only pumping stalls).
  3. The lobby (game/glass/btl4lobby.*, gated): ISteamMatchmaking room (btl4=1 list filter); pilots publish name/mech/color; the host's GO mints the roster and signals.

THE TOKEN MODEL (the FakeIP lesson) [T2]

FakeIP does NOT survive the per-mission process relaunch (live-disproven prior-art assumption: menu and mission processes got different FakeIPs; the pod timed out dialing its own stale address). Roster addresses are therefore opaque ipv4-shaped tokens169.254.77.N, port 1501=console / 1502=game — minted by the HOST at GO and mapped to Steam identities; connections ride ConnectP2P(identity, channel). Handoff to mission processes via env: BT_FE_MYFAKE (own token → GetMyAddress self-match) + BT_FE_STEAMMAP (ip=steamid64;...). The engine's roster matching, Waterloo swap logic, and self-identification all run UNCHANGED on tokens.

Testing

Single-machine (verified): lobby-of-1 GO → token map → egg roster token → mission runs over the stock console ladder. Live 2-machine procedure + checklist: docs/STEAM_TEST.md. AppID 480 (Spacewar) via auto-written gitignored content/steam_appid.txt.

FIRST REAL MULTI-PLAYER VERIFICATION — playtest night 4 (2026-07-27, 4.11.584) [T2 live]

Players ran three back-to-back Steam lobbies, host-and-join, 3+ players, with no operator console involved — the first genuine field exercise of this path. What worked: hosting and joining (Draco, SAURON, somebodee, RajelAran all succeeded; "steam works for self-hosting? neat"), mission launch, damage application (previously suspected dead over Steam — "panels were changing color", "I was damaged"), 2 kills in one round, clean round end, and the next mission launching after it. SAURON: "3 missions ran smooth ... felt smooth and normal". Load after LAUNCH felt "a bit long" (unquantified).

Found, and filed: #68 (a failed JOIN/HOST exits the process silently — the FE returns on any BTLobby_JoinAndWait failure, so "Steam not running" and a real crash look identical to a player). Everything else the night surfaced was NOT Steam-specific and is tracked in the general issues: #67 (replicant torso twist / muzzle placement), #70 (twist after respawn), #55 (heat readout not reset on death), #69 (Sunder V1 → Denkou naming).

Lesson for triage: a bug found in a Steam lobby is a Steam bug only if it lives in the lobby / token / transport layer. Everything above the seam is the same arcade mesh — the three replication symptoms this night produced would all reproduce on the relay.

Key Relationships

  • Rides: glass-cockpit miniconsole (marshal has a Steam-wire branch) · Extends: multiplayer (the arcade mesh, unchanged above the seam)