# Road Handoff — where the work stands *Snapshot: 2026-07-27 midday, at commit `7afbda9`. This is a living file; update it or delete it when the picture changes. Everything below was checked against the machine/tracker, not memory.* --- ## 0. Operational state RIGHT NOW (read this first if you want to host) | Thing | State | |---|---| | **Parked relay** | **NOT RUNNING.** Ports 1500 / 1501 / 1507 have no listener. | | Stray pods | none — the leftover `OPERATOR.EGG -net 1501` process exited on its own. Machine is clean. | | RDP into the home machine | enabled, 3389 listening, rules in place | | Mesh VPN (Tailscale) | **not installed** — the control port is not tunnelled | | Release `4.11.600` | cut, verified, **not yet posted** | | Launcher fix at HEAD | **not in the 600 zip** — needs a re-cut to reach players (§6) | **To host from the road you must first get the relay up on the home machine** — a remote console *attaches*, it cannot start one. Either RDP in and double-click `tools\park_relay.cmd`, or put it in `shell:startup` so it survives a reboot. Full runbook (what a remote console can and cannot do, the control-port table, the secret's working-directory trap): **`context/operator-console.md` §Parked relay + remote console**. ⚠️ Forwarding **1507** to the open internet puts the operator secret on the wire in cleartext. Leave the player ports (1500/1501) as they are and carry the control link over a tunnel. --- ## 1. The release `dist\BT411_4.11.600.zip` (47.0 MB) + `dist\RELEASE_NOTES_4.11.600_discord.md` (1,915 chars). Verified on the final artifact: doc audit 35/35, bats byte-identical to `players/`, exe identical to the build at `39cb864`, clean-extract boot with **0 faults**, `bindings.txt` generated with the `# bindings-board 2` marker, and log rotation proven *inside the shipped zip* (solo run rotates `solo.log`, leaves a seeded `join.log` untouched). Notes cover **584 → 600**, since 584 is the build everyone actually installed. 599 was cut but never posted; its fixes are folded in. Nothing left to do but post it. --- ## 2. Live investigations (the real work) **26 issues are genuinely open** (24 plus #71/#72 filed today); **26 more carry `awaiting-verification`** — fix landed, no human has seen it work live. Snapshot script: `scratchpad/tracker_snapshot.py` (hits the Gitea API with your stored git credential; re-run it rather than trusting this list). ### Blocked on someone else - **#35 — Owens laser crash.** Waiting on Conn Man's `join.log`. His last one was overwritten, which is exactly what 600's log rotation fixes, so the next occurrence should survive. Repro rig is committed: `scratchpad/rig_killstorm.ps1` + the `BT_MP_FORCE_DMG=` hook in `game/reconstructed/mech4.cpp`. Result so far is an **honest negative** — the kill-storm does not reproduce it; notes in `scratchpad/crash_20260726_2316_notes.md`. Best current lead: firing at a *mech* rather than a truck. ### Ready to pick up - **#52 — replicant legs "ski"** (slide without walking). The natural sibling to the #67 torso work just finished: same replication path, same dead-reckoning clock. Start from `torso.cpp`'s `GetLastUpdateTime()` fix and look for the equivalent on the leg/gait side. - **#49 — radar/map does not draw the arena WALL geometry.** Audited: there is no wall path at all, so this is a build-it, not a fix-it. - **#43, #50, #56** — MFD/roster behaviour reported live but never reproduced on the bench. ### Deferred with a stated reason (don't re-derive) - **#55 remaining steps** — the `mechsub.cpp` rename pair, deleting `HeatableSubsystem::ResetToInitialState`, deleting `RespawnRepair`. All three need a `HeatableSubsystem` **vtable slot-10 pre-flight**, and there is no binary image in the repo to dump it from. Steps 0/1/2/4 landed in `ef8e449`. ### Two calls that are yours, not mine - **#54** (David's three energy weapons dead) — probably superseded by #57; close it or say why not. - **#66** (joyconfig.bat hangs after the wizard) — may be invalid; people report using it fine. ### Filed today, from the orphan investigation (§6) - **#71** — closing the Plasma window (or a glass panel) hides it with no way to get it back. - **#72** — `BTLoadPump` swallows `WM_QUIT` during mission load. Latent, does not hang today; filed so nobody re-derives it. --- ## 3. What landed in the last 24h and is unverified `#67` (both halves), `#55`, `#62`, close-means-quit, four lifecycle-window null-deref guards, the phantom-map filter, seat identity, console + launcher log rotation, console re-arm. **The gate is a live games night.** House rule: nothing moves off `awaiting-verification` until a human confirms it in a real session — a passing bench test is not verification. --- ## 4. Recent findings worth remembering - **The allocator was the bug.** `Memory::Allocate` used plain `operator new`; the pod's `MemoryBlock` arenas carve OS-zeroed pages. Every 1995 field the constructor never stored read as zero on the pod and as garbage here. That is #67's root cause, and the same class will bite again — suspect it whenever a value is wrong only for *remote* entities. (`mechrecon.hpp`) - **`artrucks` is an art sub-node, not a mission.** Offering it in the operator's map list hung every pod at "mission starting" for a whole evening. Map anatomy: `arena1 → {arenall → cavern, artrucks}`. - **The operator secret follows the relay's cwd.** Two files with different values existed in this repo; a mismatch shows up as a dropped control connection on timeout, not a "wrong password". Always park from `content\`. --- ## 5. Picking up on the laptop 1. `git pull` — everything above is committed, including `scratchpad/` (the repro rigs and crash notes travel with the repo). 2. **The launcher bats only work from an extracted zip** — they `cd /d %~dp0` and need `build\` and `content\` beside them. Running them from the repo silently hits `badpath`. This has burned two verification attempts; extract `dist\BT411_4.11.600.zip` somewhere and test there. 3. Uncommitted and intentionally left dirty: `content/LAST.EGG`, `content/OPERATOR.EGG` (session state), `scratchpad/sim3.py`. 4. Orientation: `CLAUDE.md` (router) → `context/*.md`. For last night specifically: `scratchpad/crash_20260726_2316_notes.md` is the full incident ledger, and `context/steam-networking.md` has the first real multi-player field verification. --- ## 6. Orphaned processes — investigated 2026-07-27 (commit `7afbda9`) Answering *"X-closing the game leaves the terminal open and leaves orphaned processes; I think it's a major contributor to MP hiccups."* Full write-up: **`phases/phase-12-orphan-processes.md`**. **The terminal half was real, and is fixed.** Every launcher's `:btwait` loop polled `tasklist /FI "IMAGENAME eq btl4.exe"` — **machine-wide**. Proved on the rig: a bat that launched *nothing* keeps spinning while an unrelated instance lives. So a second client, your own operator pod, or any orphan hangs every join window, it never prints its sign-off, and it reads as "the game didn't exit" — which is what makes people start killing processes and creating real ghosts. Fixed by snapshotting the PIDs alive before the launch and waiting only on ones absent from it. **The orphan half did NOT reproduce on 600.** Closing the main window exits cleanly in ~1 s during solo model-load, in the relay join wait, and after a real console launch — relay logs the seat freed, nothing relaunches. The orphans the playtesters saw match 584 and earlier, where every close relaunched. That fix is already in 600 and still needs a live night. **On the MP-hiccup theory:** the mechanism is real *if* an orphan exists — it keeps both relay TCP connections `Established`, so the relay counts a pilot who never readies and the seat-left grace never starts, which looks exactly like "waiting for mission assignment" forever. Since no orphan could be produced from a close on 600, the live contributor is more likely the `:btwait` bug above. ### ⚠️ What this means for the release The launcher fix is **at HEAD but not in `dist\BT411_4.11.600.zip`**. To ship it: rebuild, re-run `python tools/mkdist.py`, re-verify, and bump the version in the release notes. Otherwise post 600 as-is — the fix rides the next cut. **Your call; I did not re-cut.** ### One thing still unverified The `:btwait` logic is verified 4/4 (including the regression guard: nothing running must still sign off, or it would spin forever with nothing to wait for), and the patched bat still launches. But the **full handoff E2E was never exercised** — the bat blocks on the FE menu, which waits for a human, so automation never reaches the loop. One manual run closes this: run `join.bat`, play, close the game, and confirm the window prints "The game has exited" while another btl4 is running.