Files
SiteLink/docs/BRAINSTORM.md
T
CydandClaude Fable 5 e0d30120e0 SiteConfigMerge tool + operating-model updates from operator input
New: tools/SiteConfigMerge (net48 console app)
- dump: decode any .siteconfig (squads, pods, IPs, MACs, host types)
- merge: combine <siteName>.siteconfig inputs into master.siteconfig,
  renaming squads "<siteName>-<original squad name>"
- Pod records pass through byte-for-byte; only squad records (the
  rename) are re-serialized, under the TeslaConsole assembly identity
  captured from the input. Stand-in types + SerializationBinder, so no
  build dependency on TeslaSuite.
- Warns on duplicate pod GUID/MAC and cross-site IP overlap.
- Verified end-to-end: the real TeslaConsole.exe 4.11.4.1 loaded the
  merged master via its own Site.LoadFromFile (reflection harness).

Doc updates from operator decisions:
- Operating model settled: sites voluntarily hand console authority to
  the central console for the duration of a SiteLink event, by
  contributing their siteconfig. Federation ruled out at current scale.
- Siteconfig "secrets" framing corrected: pod keys have no practical
  value outside the air-gapped bay; files are exchanged per event and
  never stored in this repo (tools only).
- Fleet scale recorded: 6 active pod bays, <120 cockpits in existence;
  bay sizes range console+2 cockpits up to the full 20-node complement.
  Open question 9 answered.
- Hub hosting direction: neutral Firestorm host at the WireGuard hub;
  the FS server usually IS the Live Cam, so stream its output to all
  sites and optionally to the public internet. Mission Review instance
  runs at the hub too - one authoritative debrief streamed everywhere.
- Virtual PDF scoresheet printer at the hub: event debriefings print
  centrally, retrievable from any site on the link.
- Voice (Mumble) backburnered - revisit only on event interest.
- .gitignore: build outputs; siteconfig exclusion rationale reworded.

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

280 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SiteLink — design brainstorm
Working record, started 2026-07-10. Companion to
[PODBAY-ECOSYSTEM.md](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
### Option A — Routed L3 (recommended default)
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`](../tools/SiteConfigMerge/README.md)
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 arbitration** — *policy 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 ambitions~~ — **answered 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.*
- **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`](../tools/SiteConfigMerge/README.md), verified against the
real console loader) → run an event under the authority-handover model (§4): collect
`<siteName>.siteconfig`s, 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.