Files
CydandClaude Fable 5 71292db455 Phase 0 lab plan: topology, VM management, experiments E1-E9
docs/PHASE0-PLAN.md:
- Lab topology mirroring production 1:1 - two minimum-shape sites
  (console + 2 cockpits) + hub, hub-and-spoke WireGuard over a
  host-only "WAN" net with netem as the simulated internet.
- Lab IP conventions (strawman seat map; flagged for alignment with
  real bay numbering before Phase 1).
- VM inventory: full 9-VM set and a 5-VM minimum-viable start.
- VM management recommendations: VMware Workstation Pro 17 (free
  personal; host is Win11 Home so no Hyper-V) for the first pass,
  Proxmox VE on a spare box as the persistent lab / future hub
  staging; gold images + linked clones, snapshot-per-experiment
  discipline, config-as-code under lab/, one-knob netem sweep script.
- Experiments E1-E9 with pass criteria mapped to the brainstorm's
  open questions: routed fabric + console RPC over WAN, broadcast
  locality, FS directed join + port matrix, latency cliff table,
  WAN-drop behavior, MTU, BT411 cross-subnet egg push, hub host +
  stream rehearsal, event-day dry run (SiteConfigMerge gate).
- Risks: MW4-in-VM rendering (physical-host fallback), vPOD fidelity
  limits, firewall discipline.

Linked from BRAINSTORM Phase 0 and the README contents table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 13:44:30 -05:00

18 KiB
Raw Permalink Blame History

SiteLink — design brainstorm

Working record, started 2026-07-10. Companion to PODBAY-ECOSYSTEM.md, which holds the verified facts this brainstorm builds on.

0. Goals (proposed — confirm/edit)

  1. Cross-site play: cockpits at site A and site B in the same match (Firestorm first; BT411/RP as they mature).
  2. Preserve the air gap: the linked fleet is one private network. No bay machine ever gets a route to the general internet.
  3. Fleet visibility/command: an operator (eventually a master console) can see — and where appropriate command — pods at every site.
  4. Shared front-of-house: cross-site events share a queue, callsigns, scores. (Voice: backburnered — see §6.)
  5. Zero changes to cockpit hardware, minimal changes to bay-local operation: a bay must keep working stand-alone when the link is down.

Non-goals (for now): public matchmaking, spectating from home, per-player home clients.

1. The seed proposal

Each site gets its own 10.0.y.x subnet (we get 10.0.1.x, you get 10.0.2.x, …), VPN them all together into a single /16, collect every site's .siteconfig, concatenate them, and give the result to a master console that commands the fleet.

Verdict: sound skeleton. The three pieces (site-numbered subnets, VPN mesh into 10.0.0.0/16, merged fleet config) survive contact with the code. The refinements below are about how, not whether.

2. Addressing plan

  • 10.0.<siteID>.0/24 per site, keeping each bay's existing last-octet conventions (pods .1.8, .11.18, camera .9, …) so per-site configs become a template stamped with a site ID. Legacy 200.0.0.x bays get renumbered on joining — that space is public internet space and must not exist inside the linked fleet.
  • Reserve 10.0.0.0/24 for shared infrastructure: VPN hub, master console, central PQS, Mumble, NTP, a neutral dedicated game host. Nothing site-specific lives there.
  • Site ID registry lives in this repo (sites/ — one small file per site: ID, name, operator, subnet, contact). First allocation: 10.0.1.0/24 = Fallout Shelter Arcade; 10.0.2.0/24 = next site. Scale reality (2026): 6 active pod bays, fewer than 120 cockpits in existence — 254 site IDs is beyond generous, and every topology choice below can assume single-digit sites.
  • Netmask choice is the real design fork (see §3): hosts configured /24 + gateway = routed model; hosts configured /16 = requires a bridged L2 overlay.
  • Renumbering mechanics: TeslaConsole already owns pod IP config (provisioning writes mIPAddress/mGateway/mDns/mSubnet), and the CTCL [teslas] inis are trivially regenerated from a template. So renumbering is a console-driven afternoon, not a reimage.

3. Topology: routed L3 vs bridged L2

Each site keeps its /24; a per-site VPN gateway (its only new hardware) routes between sites over WireGuard tunnels.

  • Works because Firestorm's join path is directed by IP (TryToJoinASpecificGame, see ecosystem doc) and every console→pod protocol (53290 RPC, Munga 1501, BT egg push) is directed TCP. Nothing in the match-play path needs broadcast.
  • Clean failure isolation, no cross-WAN broadcast chatter from era Windows boxes, easy per-flow firewalling at each gateway.
  • Hub-and-spoke (hub on shared infra, e.g. alongside mysticmachines.com) or full mesh — WireGuard does either; start hub-and-spoke, it's simpler and the hub is also where shared services live.
  • ⚠️ Breaks broadcast-dependent conveniences: DirectPlay "browse LAN games" listing and SecureConfig first-boot beacons don't cross sites. Both are acceptable: game joins are console-directed anyway, and provisioning is an on-site act by design.

Option B — Bridged L2 overlay (fallback / experiment)

One virtual Ethernet across all sites (ZeroTier, VXLAN/EoIP between gateways, tinc switch mode); hosts could then even use a flat /16.

  • Everything behaves like one big LAN — broadcast discovery, any undiscovered broadcast assumption in 19962009 era code, zero renumbering logic beyond uniqueness.
  • One broadcast domain of ancient unpatched Windows across the WAN (NetBIOS chatter, broadcast storms), MTU headaches, harder to reason about, and failure at one site can be noisy everywhere.
  • Position: keep in the back pocket. If Phase-0 testing (vPOD + two subnets) turns up a flow that genuinely requires broadcast, bridge only that (e.g. a targeted UDP broadcast relay) before going full L2.

VPN tech choice

WireGuard first (kernel-fast, tiny config, UDP hole-punch friendly, runs on a $50 box or the site router). Tailscale/NetBird/ZeroTier are managed alternates if key/peer management becomes a burden — but note ZeroTier is the L2 option, Tailscale/NetBird are L3. The bay machines themselves never run VPN software; only the per-site gateway does. Bay boxes keep no default route — gateways carry routes for 10.0.0.0/16 only.

4. Fleet configuration: master console vs federation

The seed proposal: merge all .siteconfig files → one master console commands the fleet.

The merge tool exists: tools/SiteConfigMerge decodes <siteName>.siteconfig files and emits one master.siteconfig, renaming every squad <siteName>-<original squad name> ("FSA-bay1", "Pharaoh-bay1", …) — one squad group per site, which TeslaConsole's UI already organizes naturally. Pod records pass through byte-for-byte; verified against the real TeslaConsole 4.11.4.1 loader.

The operating model (settled 2026-07-10): event-scoped authority handover. When a SiteLink event runs, every participating site willingly hands console authority to the central console for the duration of the event — concretely, by contributing its <siteName>.siteconfig to the merged master. Outside events, each site console is authoritative over its own bay. Notes that keep this clean:

  • The pod keys inside a siteconfig have no practical value outside the bay's air-gapped network (anyone with bay access has the file anyway) — handing the file over is the handover ceremony, not a security event.
  • Siteconfigs change over time, so they are exchanged fresh per event and are not stored in this repo (tools only).
  • Nothing enforces the handover — TeslaLauncher has no arbitration if a site console and the central console command the same pod concurrently. Convention: site consoles stand down for the event window. A soft "event mode" lock in TeslaConsole is a nice-to-have if the convention ever gets violated in practice.
  • Remaining technical to-do for the central console: WAN-tolerant RPC timeouts, and it should live on shared infra (10.0.0.0/24) with a decent uplink.

Federation (a coordinator service so raw keys never leave a site) is off the table at current scale — 6 bays run by trusted operators doesn't need it. Recorded here only in case the fleet's trust model ever changes.

5. Linking the games themselves

Firestorm (first target)

  • Session model: one DirectPlay host; everyone joins directed-by-IP. Options for host placement:
    • a) Host at one site's console (simplest; other site eats the WAN RTT; O(n²) load on that console's uplink);
    • b) Neutral host at the WireGuard hub (preferred direction, 2026-07-10). Symmetric latency for every site, best uplink — and it exploits an operational fact: the Firestorm server is almost always the Live Cam for that game. A hub-hosted host running the camera-ship role turns the neutral server into the event's broadcast point: capture its output and stream the show to every participating site (Live Cam screens everywhere show the same feed), and optionally stream it publicly to the internet as the fleet's shop window. Considerations: the camera ship renders, so the hub box needs a real GPU (physical box at the hub location or a GPU cloud instance — not a bare VPS); mw4dedicatedui (headless) remains the fallback if hub rendering is impractical, with a camera-ship client joining from a site instead. Streaming transport is one-way and latency-tolerant: OBS capture → SRT/RTMP internally, Twitch/YouTube for the public leg. Needs validation either way (dedicated UI is unexercised in the modern tree; camera-ship-as-DirectPlay-host in the CTCL flow should be confirmed against ctcl-game.ini's *1/cameraship entry and the PQS cameraship flag).
    • The Mission Review instance lives at the hub too, for the same reasons: one authoritative post-match review (ctcl-mr role / MSRSpectator) running next to the host that recorded the match, its output streamed to every site's Mission Review screen — every bay debriefs from the same show.
  • Player counts: the golden first milestone is 8v8 across two sites (8 cockpits each) — inside the stock 16-player cap, zero engine changes. Full 16v16 site-vs-site needs the already-drafted 16→32 plan in firestorm\CLAUDE.md (compiled defaults + drop-zone authoring per map + lobby UI polish).
  • Latency budget: the netcode shipped for dial-up (150300 ms era). Inter-city internet (2080 ms) + WireGuard (~1 ms) should be comfortable. Measure, don't assume: put netem delay/jitter/loss on a test gateway and find the cliff (see Phase 0).
  • Port hygiene: set the DirectPlayPort registry value at every site so game traffic is a single known port for the gateways' firewalls, instead of DirectPlay's default 47624 + 23002400 spread.
  • Fixed-port + MTU checks: DirectPlay UDP datagrams over a 1420-byte WireGuard MTU — verify no fragmentation weirdness (era stacks are fragile here).

BT411 (classic BattleTech)

  • The console already launches multi-pod games by address list (btconsole.py MP.EGG 10.0.1.11:1501 10.0.2.11:1501 is a cross-site launch). Two unknowns to resolve:
    1. Does the pod↔pod mesh derived from the egg [pilots] list carry literal IPs (routes fine) or assume same-subnet?
    2. The 1996 sim's latency tolerance — lockstep-ish engines of that era can be unforgiving. netem test early.
  • Console-must-stay-connected quirk means the WAN link drop kills the match — argues for running the BT console at the site with the most pods, or fixing the engine bug.

Red Planet (RP411 reconstruction)

  • Same console-directed model (Munga TCP 1501). Park until BT411 learnings land — shared engine lineage means most answers transfer.

Original Tesla 4.10 games under emulation (TeslaRel410)

  • When the DOSBox-X/VPX emulator matures, the original BT/RP binaries land on current pod hardware speaking their original network stack: WATTCP (real TCP/IP) via NetNub, surfaced through NE2000-emulation bridged onto the bay LAN via pcap. Because it's plain IP with the emulated pod holding a real bay address, the routed-VPN model extends to them in principle unchanged.
  • Unknowns to test (cheap — emulator instances run on any PC, no cockpit needed): NetNub discovery/mesh addressing across subnets, and the latency tolerance of a 30 Hz 1996 lockstep-era sim. Fold into the Phase 0 netem lab once the emulator reaches its networking phase (PLAN.md Phase 6).
  • Strategic note: BT411/RP411 (native, netcode we can patch) and TeslaRel410 (faithful, netcode frozen in 1996) are complementary. If the original protocol proves WAN-hostile, the answer may be "emulated originals for local play, native reconstructions for cross-site" — SiteLink shouldn't promise WAN play for the emulated path until measured.

6. Shared services (the 10.0.0.0/24 rack)

Service Notes
WireGuard hub The rendezvous point; a VPS (could sit near the existing mysticmachines.com infra) or a box at the best-connected site
Virtual scoresheet printer A virtual printer at the hub that "prints" event debriefings/scoresheets to PDF (Firestorm's print path: printdebriefing / mw4print). PDFs land in one place and are retrievable from any site on the link — a simple web share on the hub over the VPN. Sites can still print paper locally from the PDFs
Voice (backburnered) The FS507D release integrated Mumble, but only one operator ever ran it. Technically easy to stand up on the shared network — revisit only if event interest warrants
Queue/roster coordination (future) Cross-site events will want one queue/roster. PQS — the operator-built event traffic-flow tool — is the natural seed, but for now it stays support tooling. If promoted: (a) one central instance all consoles poll — simplest, DB schema grows a site column; (b) per-site instances + sync — only if WAN-down resilience of the local queue matters during events. Callsign uniqueness would become fleet-wide
Neutral game host + event broadcast Firestorm host for site-vs-site matches, co-located with the WireGuard hub. Doubles as the Live Cam (the FS server usually is the Live Cam): stream its output to all sites' Live Cam screens, optionally to the public internet. The Mission Review instance runs at the hub too — one authoritative debrief streamed to every site's MR screen. Needs GPU at the hub
NTP One clock for scores, logs, and replay/debrief alignment
Fleet monitoring VncThumbnailViewer pointed across the VPN; later, master-console status board

Local-only forever: printer and RIO/cockpit I/O. For cross-site events the Live Cam and Mission Review instances run at the hub (above); each site's LC/MR screens become display endpoints for the hub streams, serving the local audience. Bay-local games keep running their own LC/MR stations exactly as today. Cross-site scoresheets go to the hub's virtual PDF printer (table above) — retrievable from any site, with local paper printing off the PDFs where wanted.

7. Security posture

  • The fleet stays air-gapped as a whole. Only gateways touch the internet, only to carry WireGuard to known peers. Bay machines: no default route, no DNS egress, static 10.0.0.0/16 routes via the gateway.
  • Gateway firewall = allowlist by flow, per the port map in the ecosystem doc. Suggested split:
    • Game plane (DirectPlay fixed port, Munga 1501, Mumble): site↔site and site↔shared.
    • Management plane (TCP 53290 launcher RPC, VNC 5900): only site-console↔own-pods and master-console↔pods — other sites' consoles have no business on your 53290.
  • Repo hygiene: WireGuard private keys never enter this repo. Siteconfigs aren't stored here either — not because the pod keys matter off-site (they don't; the bays are air-gapped and anyone with bay access has the file), but because they're living operational data exchanged fresh per event. Repo holds tools, templates, and public site registry data (subnets, endpoint hostnames, WireGuard public keys).
  • Era-Windows reality: assume every bay box is compromised-if-reachable. The allowlist above is the actual security boundary; the VPN is transport, not trust.

8. Open questions

  1. FS end-to-end join over routed subnets — directed-join API confirmed in source; prove the whole ConLobby/CTCL flow passes the host IP (vPOD + two subnets, or two VMs). Any broadcast dependency hiding in the lobby flow?
  2. DirectPlayPort in practice — is it set at existing sites, and does a fixed port carry all session traffic (or only enumeration) under DirectPlay Protocol?
  3. BT411 [pilots] mesh — IPs or subnet assumptions? (Read L4NET.CPP StartConnecting path.)
  4. Latency cliffs per title — netem sweep: at what RTT/jitter/loss does each engine degrade (rubber-banding, desync, disconnect)?
  5. Dedicated Firestorm host — does mw4dedicatedui build & run in the modern tree, and can camera/MR spectators join it cleanly?
  6. PQS promotion — if/when the event queue tool becomes cross-site coordination: site column vs event database; global callsign policy.
  7. Console arbitrationpolicy settled 2026-07-10: sites voluntarily hand authority to the central console for the event window. Residual: nothing enforces it (TeslaLauncher has no arbitration); an optional soft "event mode" lock in TeslaConsole only if the convention ever fails in practice.
  8. Who hosts shared infra — VPS vs best-connected site; bandwidth math for a 32-player O(n²) host (~upstream estimate needed from real packet captures).
  9. Site count ambitionsanswered 2026-07-10: 6 active bays, fewer than 120 cockpits in existence. Hub-and-spoke is trivially sufficient; federation is permanently unnecessary barring a trust-model change.
  10. WAN-drop behavior — for each linked flow, what breaks when the tunnel drops mid-match, and does the bay cleanly fall back to stand-alone?
  11. NetNub over routed subnets (TeslaRel410) — how do the original 4.10 games discover/address each other (read CODE\*\MUNGA_L4\NETNUB\ + L4NET lineage)? Broadcast-dependent or console-directed like their descendants? And what RTT does the 30 Hz 1996 sim tolerate?

9. Phased roadmap (strawman)

  • Phase 0 — Lab proof (no hardware, no travel). Two "bays" as VMs/vPOD instances on two subnets with a WireGuard/netem gateway between them. Prove: console→remote-pod RPC (53290), a 2-client Firestorm match across subnets, latency sweep, BT411 cross-subnet egg push. Everything above that's marked "verify" gets verified here. → Full plan with lab topology, VM inventory/management, and experiments E1E9: PHASE0-PLAN.md.
  • Phase 1 — First real link. Two sites, gateways, tunnel, renumber to 10.0.1.x/10.0.2.x. Fleet VNC + remote Mission-Review spectating. First cross-site Firestorm match at ≤16 total players (8v8) on the stock exe.
  • Phase 2 — Fleet operations. siteconfig merge tool built (tools/SiteConfigMerge, verified against the real console loader) → run an event under the authority-handover model (§4): collect <siteName>.siteconfigs, merge, central console commands the fleet. Optional PQS event mode with shared queue/callsigns; debrief/scoresheet distribution to both printers.
  • Phase 3 — Full site-vs-site. Execute the firestorm 16→32 plan (code defaults + drop zones), neutral dedicated host, 16v16 events.
  • Phase 4 — More titles, more sites. BT411/RP cross-site as those engines mature; 3rd+ site onboarding kit (gateway image + site-ID allocation + config templates); revisit federation and the GUN/GameSpy-style fleet game browser.