pod: bundled per-game deployment (portable config, --exit-with, build-pod)
Phase 10: RIO hardware exists only on pods + dev boxes, so production is one RIOJoy copy inside each podized game folder, no resident tray. ConfigLocator makes a config.json beside the exe win over %APPDATA%; --exit-with <exe|pid> (CompanionTarget/CompanionExit, 60s startup grace) tears down and quits when the game exits; a starting --exit-with instance waits up to 15s for the predecessor mutex instead of silently exiting. deploy/build-pod.ps1 emits the ~4.5MB drop-in (app + portable config wrapping the profile + start script, no drivers) - verified against the shipped Descent profile. 455 tests; PLAN.md Phase 10 + INPUT-INTEGRATION.md pod section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -490,6 +490,45 @@ spec + client snippets in [`docs/FEEDBACK.md`](FEEDBACK.md). Delivers the
|
||||
settings (JSON-only today); shipped client examples (SimHub plugin / DCS
|
||||
export script) beyond the FEEDBACK.md snippets.
|
||||
|
||||
### Phase 10 — Pod-bundled deployment — code-complete ✅
|
||||
Deployment topology decision (2026-07-31): RIO hardware exists only on **pods**
|
||||
(the cockpit cabinets) and dev boxes — no freestanding end-user PCs. Production
|
||||
model is therefore **one RIOJoy copy bundled inside each podized game's
|
||||
folder**, started by the game's launch script and exiting with the game; no
|
||||
resident RIOJoy runs on a pod, and the native games simply don't bundle one
|
||||
(making the COM-port yield machinery vestigial in production). The resident
|
||||
tray + auto-switch reclassifies as the development harness. 455 xUnit tests
|
||||
total across the suite.
|
||||
- **Portable config**: `ConfigLocator.Resolve` — a `config.json` beside the
|
||||
exe wins over `%APPDATA%\RIOJoy\config.json`; `TrayApplicationContext.
|
||||
ConfigPath` resolves through it, so `--import-profile` targets the same
|
||||
store. A pod bundle needs no import step: its config *is* the profile.
|
||||
- **`--exit-with <exe|pid>`** (`CompanionTarget.Parse` — pid, or a name
|
||||
normalized like auto-switch triggers): the tray polls the companion on its
|
||||
existing 1 s timer and quits through the normal teardown (ports released,
|
||||
wallpaper restored, plasma blanked) once the game has run and then gone.
|
||||
`CompanionExit` holds the pure decision — launch order isn't guaranteed, so
|
||||
a never-seen companion only triggers exit after a 60 s startup grace
|
||||
(also covers "game failed to launch"). Clock-free and unit-tested
|
||||
(`tests/.../Hosting/CompanionExitTests`).
|
||||
- **Instance handoff**: with `--exit-with`, a starting instance waits up to
|
||||
15 s for the predecessor's single-instance mutex (game A's copy tearing
|
||||
down while game B's starts) instead of the historical silent exit-0; plain
|
||||
launches keep the instant-exit behavior. Abandoned mutex (predecessor
|
||||
crash) counts as acquired.
|
||||
- **`deploy/build-pod.ps1`**: emits the per-game drop-in — `riojoy\` app
|
||||
(flavor-selectable net48/net40, Skia-pruned) + portable `config.json`
|
||||
wrapping the game's profile document verbatim + `start-riojoy.bat`
|
||||
(`--exit-with` prefilled from the profile's first trigger) + README-POD —
|
||||
zipped as `RIOJoy-pod-<name>-<stamp>.zip` (~4.5 MB). Deliberately **no
|
||||
drivers**: pods are provisioned once by the universal package. Verified by
|
||||
building the Descent bundle and round-tripping its emitted config through
|
||||
`ConfigStore.Load`.
|
||||
- ⏳ **Remaining:** on-pod verification of the full launch/handoff cycle
|
||||
(launcher → game A → quit → game B); podize a first real game with the
|
||||
bundle; revisit the universal zip's `install.bat` framing (dev-setup only)
|
||||
once pod deploys are routine.
|
||||
|
||||
---
|
||||
|
||||
## Open items / risks
|
||||
|
||||
Reference in New Issue
Block a user