KB: step-4 closeout -- Steam wire documented, live-test procedure, router

docs/GLASS_COCKPIT.md gains the step-4 ledger (seam/transport/lobby + THE
FAKEIP LESSON); NEW context/steam-networking.md topic (+ router row) and
docs/STEAM_TEST.md (the 2-machine live procedure = the step-4 exit criterion
on user hardware).  context/glass-cockpit.md: steps 3+4 status.  Final purity
re-check: pod build clean, forced-walk mission runs, ZERO glass/steam tags in
the pod log.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-18 00:05:51 -05:00
co-authored by Claude Fable 5
parent f703bb1d56
commit 75f136e9ff
6 changed files with 156 additions and 37 deletions
+28
View File
@@ -133,3 +133,31 @@ menu; menu relaunches CLEAR the handoff — the leak re-armed a marshal in cycle
Official Valve zip (provided by Cyd at the repo root), extracted to
`extern/steamworks_sdk_164/` and trimmed to `public/` + `redistributable_bin/` + Readme
(12.5 MB); zip removed. Consumed only under `-DBT_STEAM=ON`.
## 2026-07-17/18 — Step 4: the Steam wire — CODE COMPLETE (commits e79e8fa, 48ede2f, f703bb1)
**4a (e79e8fa) — the wire seam:** file-local `BTNetSend/Recv/Accept/Close` wrappers around the
9 raw Winsock sites in `L4NET.CPP`; OFF builds are pure code motion. Regression: 2-node loopback
MP through the seam — mesh forms, full 31/31 mission on both nodes.
**4b (48ede2f) — the transport:** gated TU `L4STEAMNET` — pseudo-SOCKETs (0x5EA0xxxx) behind the
seam; the engine's TCP byte stream rides reliable-NoNagle Steam messages re-assembled into
per-connection rings (recv semantics preserved: empty→WSAEWOULDBLOCK, closed→0); seam
completions: `CheckSocket` (peer = token address), `OpenConnection` TCP_OPEN delegate,
`GetMyAddress` self-token. Install on `BT_STEAM_NET=1`; graceful degrade to Winsock at every
step. BOTH pumps needed (`SteamAPI_RunCallbacks` + sockets `RunCallbacks`).
**4c (f703bb1) — the lobby + THE FAKEIP LESSON [T2]:** prior art assumed FakeIP survives the
per-mission process relaunch — DISPROVEN live (menu process got 169.254.124.110, the mission
process got 169.254.54.234; the pod timed out connecting to its own stale address). Redesign:
roster addresses are opaque ipv4-shaped TOKENS (`169.254.77.N`, ports 1501 console / 1502 game)
minted by the host at GO and mapped to Steam IDENTITIES; connections ride
`ConnectP2P(identity, channel)` (console=0, game=1); the map hands off via env
(`BT_FE_MYFAKE`/`BT_FE_STEAMMAP`). `btl4lobby`: ISteamMatchmaking room (`btl4=1` filter),
pilots publish name/mech/color, host GO mints tokens + writes `btl4map` + `btl4go`.
**Verified single-machine (ON/ON, live Steam client):** menu → HOST STEAM LOBBY → room → GO →
map `169.254.77.1=<steamID64>` → egg roster carries the token → mission process
`[steamnet] up ... 1 roster token(s) incl. self` → pod self-matches → stock console ladder →
mission RUNS (46 ticks). 3-config build matrix green throughout. **Remaining (user hardware):**
the live 2-account cross-machine session — procedure in `docs/STEAM_TEST.md`.
+38
View File
@@ -0,0 +1,38 @@
# STEAM_TEST — the live 2-machine internet-MP procedure (step 4 exit criterion)
Everything below the wire is verified single-machine (see `docs/GLASS_COCKPIT.md` §4); the ONE
untested leg is an actual cross-machine `ConnectP2P` session. Needs: **two machines, each with
its own logged-in Steam account**, both accounts able to see each other's lobbies (same region
or Steam friends; AppID 480 = Spacewar, no ownership needed).
## Build + stage (each machine)
1. `cmake -S . -B build-steam -G "Visual Studio 16 2019" -A Win32 -DCMAKE_GENERATOR_INSTANCE=... -DBT_GLASS=ON -DBT_STEAM=ON`
2. `cmake --build build-steam --config Debug`
3. Steam client running + logged in. `content\steam_appid.txt` (480) is auto-written on first run.
## Procedure
1. **Machine A (host):** run `build-steam\Debug\btl4.exe` zero-arg from `content\` → the
Mission Console menu. Set MAP/LENGTH (60 s recommended for the first attempt), MODE =
`HOST STEAM LOBBY`, ENTER → the lobby room appears.
2. **Machine B (member):** same exe zero-arg → MODE = `JOIN STEAM LOBBY`, ENTER → the room
should list both pilots within ~10 s. (No lobby found → check both accounts' regions,
`marshal.log` `[lobby]` lines both sides.)
3. **A presses ENTER** (GO). Both machines relaunch into mission processes; A's marshal feeds
itself over TCP loopback and B over the Steam wire.
## What to check (in order, both machines' `content\btl4.log` + `marshal.log`)
1. `[steamnet] up -- identity <id64>, 2 roster token(s) incl. self` — both sides.
2. A `marshal.log`: `egg -> 169.254.77.2:1501` (B's token) — the Steam-wire console feed.
3. B `btl4.log`: `[steamnet] incoming connection queued on channel 0` (the console feed
arriving), then the egg ladder.
4. Both: `RunMission #1/#2`, then `[tick]` lines reaching the full subsystem count — and
`[steamnet] connection N up` on channel 1 (the game mesh crossing the internet).
5. In-game: see the peer mech, drive, shoot it (cross-pod damage), mission stop at clock,
host returns to the menu.
## Known limitations / notes
- The lobby does NOT survive the per-mission relaunch — re-host/re-join per mission.
- The token map is minted at GO; a member joining after GO is not in the mission.
- Firewall: no inbound rules needed (SDR relays); Steam client must be allowed out.
- Fail cleanly = both sides stay on Winsock and log why (`SteamAPI_Init failed` / token
misses); nothing in the pod path is touched either way.