D1 phase 7: LAN auto-discovery (BT_RELAY=auto) + operator LAN scripts

LAN players now find the game with zero configuration -- the 90s arcade
model (cabinets locate the operator station) restored:

- Client (L4NET RelayDiscover): BT_RELAY=auto broadcasts 'BTR1DISC' on
  udp/15999 (255.255.255.255 AND 127.0.0.1 -- broadcast doesn't reliably
  loop back on Windows; covers same-box sessions), 5 x 1s attempts; the
  answering relay's SOURCE IP + its advertised console port become the
  relay address.  Explicit <host>:<port> path unchanged; mesh untouched.
- Relay (btconsole.py): best-effort discovery responder on udp/15999
  answers 'BTR1HERE' + <u16 consolePort>; degrades gracefully (logged) if
  the port is taken.
- Operator app: Export player scripts now writes a join_as_playerN_lan.bat
  pair (BT_RELAY=auto) next to each internet script -- LAN guests
  double-click and are found; internet guests use the public-host script.

Verified 2-node: both pods BT_RELAY=auto -> probe answered through a real
interface (not just loopback) -> discovered 172.19.x.x:1500 -> full session
to RunningMission.  KB: multiplayer.md D1 section updated (+ the operator
console entry).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-18 11:12:01 -05:00
co-authored by Claude Fable 5
parent 43fa53d542
commit 1436d27ac6
5 changed files with 208 additions and 32 deletions
+16 -2
View File
@@ -304,9 +304,23 @@ phase). Plan: `~/.claude/plans/partitioned-snuggling-piglet.md`.
MP_RELAY.EGG --bind 127.0.0.1`; pods `BT_RELAY=127.0.0.1:1500 BT_SELF=10.99.0.N:1502 btl4
-egg MP_RELAY.EGG -net 1501` (egg `[pilots]` = arbitrary unique tags). Diag: relay
`[relay-stats]` per-transport census; client `BT_NET_TRACE`.
- **LAN AUTO-DISCOVERY (2026-07-18) [T2]**: `BT_RELAY=auto` — the pod broadcasts `BTR1DISC` on
udp/15999 (broadcast + 127.0.0.1, 5×1s attempts); the relay answers `BTR1HERE`+<u16
consolePort>; the replier's source IP + advertised port become the relay address. Zero-config
for LAN players (the 90s cabinet model); broadcast never crosses routers so internet players
keep the explicit host:port. Verified 2-node: both pods `auto`-discovered through a real
interface and reached RunningMission. Relay side degrades gracefully if the discovery port is
taken.
- **OPERATOR CONSOLE (2026-07-18)**: `tools/btoperator.py` (PySide6) — the lost 1995 operator
station recreated: mission editor with ALL values validated live from BTL4.RES
(`tools/eggmodel.py`: maps=type14∩26, colors/badges/patches from the type-25 vehicletable,
vehicles from ModelLists), relay/mesh mode switch, live pod-status lights parsed from the
console/relay stdout, one-click local instance launcher, per-player `join_as_playerN.bat` (+
`_lan.bat` with `BT_RELAY=auto`) export. Wire logic stays in btconsole.py/eggmodel.py (GUI =
UI + QProcess only). E2E-verified: app-driven relay session → 2 local pods → LAUNCH observed.
- **STILL UNTESTED (config, not code)**: a real two-physical-machine / internet run (only the
relay's console+game ports need to be reachable inbound — one forwarded port total).
Optional future: LAN `BT_RELAY=auto` UDP-broadcast discovery.
relay's console+game ports need to be reachable inbound — one forwarded port total; or a
playit.gg-style tunnel in front of the relay, host-side only).
## Remaining (P6 phase 4 / Phase 7)
Pod-LAN config: **real-IP path VALIDATED (2026-07-15)** — an egg with the machine's real LAN IP in