pod: self-contained bundles - drivers install via the game postinstall

Per Cyd: no operator ever installs anything on a pod by hand. build-pod.ps1
now mirrors the universal inner layout (app/app-xp, vendor, install-core.bat
+ install-rio.ps1 reused verbatim) and bundles the flavor prerequisites
(ViGEmBus / XP .NET+KB+RioGamepadXP). New install-riojoy.bat entry point is
called from the game postinstall.bat: self-elevating, idempotent, add-only.
Deliberately no uninstall step - other podized games may share the drivers,
so they are abandoned in place. Also: deploy scripts must stay pure ASCII
(PS5.1 reads BOM-less UTF-8 as ANSI; an em dash decodes to a smart quote
that terminates strings).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-31 22:15:23 -05:00
co-authored by Claude Fable 5
parent 97caf124a6
commit 38cf37c5e6
3 changed files with 153 additions and 47 deletions
+18 -9
View File
@@ -203,13 +203,22 @@ podized game's install carries its own copy, built by:
deploy\build-pod.ps1 -ProfileJson <your-game-profile.json>
```
That emits a ~5 MB drop-in — `riojoy\` (app + a **portable** `config.json`
holding just this game's profile; a config beside the exe wins over the
per-user `%APPDATA%` store) plus `start-riojoy.bat` — which the game's
launch script calls before starting the game:
That emits a **self-contained** drop-in (~8 MB on net48): `riojoy\` — the app,
a **portable** `config.json` beside the exe holding just this game's profile
(it wins over the per-user `%APPDATA%` store), and all RIOJoy prerequisites
(ViGEmBus; on the XP flavor .NET 4.0 + the RioGamepadXP driver) — plus two
entry points the game's package wires up:
- **`install-riojoy.bat`** — call from the game's `postinstall.bat`.
Self-elevating and **idempotent**: safe on every install, reinstall, and
update; it installs only what's absent and never removes anything. Put
**nothing** in the game's pre-uninstall — drivers stay in place by design,
since another podized game may share them and idle drivers are harmless.
- **`start-riojoy.bat`** — call from the game's launch script before the
game:
```
start "" "...\riojoy\RioJoy.Tray.exe" --exit-with <game exe>
start "" "...\riojoy\app\RioJoy.Tray.exe" --exit-with <game exe>
```
`--exit-with` makes RIOJoy self-managing: it activates when the game's window
@@ -223,10 +232,10 @@ release the single-instance lock.
Properties that matter on a cabinet: each game pins the RIOJoy build it was
verified with (updating RIOJoy for a new game can't regress an old one);
native games simply don't bundle RIOJoy, so the COM ports are free for them
by construction; and drivers stay a one-time pod provisioning step (the
universal package's `install-rio.ps1`) — pod bundles deliberately carry none.
The bundled exe is still the full tray app: run it with no arguments on the
pod and you have the profile editor.
by construction; and every bundle is fully self-sufficient — drivers install
through the game's own postinstall, so a fresh pod needs no separate RIOJoy
provisioning pass. The bundled exe is still the full tray app: run it with no
arguments on the pod and you have the profile editor.
## Testing without hardware or game
+18 -8
View File
@@ -516,14 +516,24 @@ total across the suite.
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`.
- **`deploy/build-pod.ps1`**: emits the **self-contained** per-game drop-in —
nothing is ever installed on a pod by hand. Inner layout mirrors the
universal package (`app`/`app-xp`, `vendor`, `install-core.bat`,
`install-rio.ps1` reused **verbatim** — no forked install logic), plus the
portable `config.json` beside the exe (the game's profile document
verbatim), `start-riojoy.bat` (`--exit-with` prefilled from the profile's
first trigger), and `install-riojoy.bat`: called from the **game's
`postinstall.bat`**, self-elevating, **idempotent** (installs only what's
absent — ViGEmBus on net48; .NET 4.0 + KB2468871 + RioGamepadXP via devcon
on net40 — and never removes anything). There is deliberately **no
uninstall step**: drivers are abandoned in place on game removal, since
nothing can know whether another podized game still uses them and idle
drivers are harmless. Zipped as `RIOJoy-pod-<name>-<stamp>.zip` (~8.4 MB
net48 incl. ViGEmBus). Verified by building the Descent bundle and
round-tripping its emitted config through `ConfigStore.Load`.
Gotcha for future edits: PS 5.1 reads BOM-less scripts as ANSI, where a
UTF-8 em dash decodes into a smart quote that *terminates strings* — keep
deploy scripts pure ASCII.
- ⏳ **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)