# Steam multiplayer — multi-machine test procedure (BattleTech 4.12) The full end-to-end: two or three machines, that many Steam accounts, one lobby, one marshaled mission over Steam Datagram Relay (SDR). Adapted from RP412's procedure for BattleTech's kills/deaths model. > **Status:** the host→member mission feed (`BTLocalConsole_InstallNetworkMission`) > is implemented. The console protocol + launch handshake it uses are > **loopback-verified** (two `-net` pods fed by `tools/btconsole.py` mesh and run > after the engine's `gConsoleMarshalsLaunch` launch-hold change). The full > multi-machine Steam mesh has **not** been lab-tested — this procedure IS that > test. If a step diverges, collect the logs (bottom of this doc). ## Per machine (all of them) 1. Steam client installed, logged in (a **different account per machine**), and RUNNING. 2. Copy the `dist\` folder onto the machine. (It already contains `steam_appid.txt` = `480` — Valve's Spacewar public dev AppID — and an `environ.ini` with `BT412STEAM=1`.) 3. Run `start.bat`. Sanity check per machine: `btl4.log` (beside the exe) should show `SteamNetTransport: up as 169.254.x.y (fake ports N console, M game)` and `[steam] transport up -- lobby available`. If it says "staying on TCP", Steam isn't running / not logged in / `steam_appid.txt` is missing. ## The test 1. **Machine A (host):** on the setup menu pick a map, mech, color, time, weather, length, and pilot name, then click **HOST STEAM MISSION**. The lobby room appears with A listed as `[HOST]`. 2. **Machines B (and C):** pick loadouts on the setup menu FIRST (the lobby publishes them), then click **JOIN STEAM MISSION**. It joins the first open BT412 lobby it finds. 3. When every member's name shows **bright** in A's room (bright = FakeIP + loadout published), A clicks **L A U N C H M I S S I O N**. 4. All pods leave the room and boot the mission. Expect in the logs: - host A: `[marshal] network mission, N remote pod(s) connected` - host A: `[marshal] connecting to pod 169.254...` then `[marshal] egg sent to 169.254... (K chunks)` and `[marshal] EGG ACK (mesh complete)` per member - host A: `[marshal] all pods staged -- RUN` - every pod: `All connections completed!` then the mission runs 5. The mission runs for the length A picked; at expiry A's marshal snapshots the roster, stops every member, then stops itself (`[marshal] time expired -- stopping remote pods`). A gets the MISSION COMPLETE results (kills/deaths); the sheet is published to the lobby so B/C show the same board. 6. Everyone lands back on a fresh setup menu (the single-binary relaunch — the lobby ROOM does not persist across the relaunch in this build; re-HOST/JOIN for the next mission). ## Addressing (how the mesh is wired) - Every pod uses engine ports **1501 console / 1502 game** by convention under Steam; the transport maps them to the Steam-assigned fake ports per peer. - The lobby exchanges each member's FakeIP + fake console/game ports live through lobby member data (`ip`/`cp`/`gp`); nothing is configured by hand. - On LAUNCH the host writes the nonced `go` roster into lobby data; every pod calls `SteamNetTransport_RegisterPeer` for all peers before dialing out. - The host bakes every member into the mission egg's `[pilots]` list (`:1502`), so each pod finds its own slot in the shared mission. ## Controllers: disable Steam Input (once per machine) Steam Input intercepts Xbox controllers for AppID 480 the moment the game initializes SteamAPI, hiding them from XInput — the pad works everywhere else and is invisible only in-game. Fix, either scope: - Per game: Steam Library → Spacewar → Properties → Controller → Override: **Disable Steam Input**. - Global: Steam → Settings → Controller → uncheck **Enable Steam Input for Xbox controllers**. PadRIO re-probes every ~3 s, so the pad hot-connects the moment Steam releases it — no restart needed. (BT412's own AppID will set this server-side; test machines need the client setting.) ## Notes and knowns - Two instances under ONE Steam account cannot mesh (one identity per account) — hence separate machines/accounts. - If a member joins after A already launched once, it answers the NEXT launch only (launch signals are nonced). - Same-LAN machines may get a direct SDR route; different networks relay. Both are fine. - Known MP fidelity gaps carried from single-player (peer warp spheres, missile clusters, PNAME/PLACE billboards) do not block the connectivity test — log observations in `context/multiplayer.md`. ## No-Steam fallback (proven, for isolating a Steam-specific problem) Set `BT412STEAM=0` and drive the pods with the external console emulator over TCP (needs Python 3): ``` Machine A: btl4.exe -egg MP.EGG -net 1501 Machine B: btl4.exe -egg MP.EGG -net 1601 Feeder: python tools\btconsole.py MP.EGG :1501 :1601 ``` If this works but the Steam path does not, the problem is in the Steam transport / lobby layer, not the game mesh. ## What to collect if something breaks `btl4.log` from each machine (each dist folder) — grep `[steam]`, `[frontend]`, `[marshal]`, `net-tx` / `net-rx` — plus which step above diverged.