docs: shipping-a-profile section in the input integration guide

Documents the install-time handoff contract that previously lived only in
Program.cs comments: single-profile document + --import-profile, exit codes
(0/1/2/3), the tray-must-not-be-running rule and installer sequencing,
per-user/per-session scope, idempotent replace-by-name, and the game-repo
reference-copy convention (dxx-rebirth pattern).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-31 21:09:02 -05:00
co-authored by Claude Fable 5
parent 80222c5ea7
commit 9a792193f9
+50 -3
View File
@@ -135,9 +135,56 @@ example: throttle → `RightThumbY` `UnipolarPositive`, rudder mix →
5. **JSON-only settings** (edit `%APPDATA%\RIOJoy\config.json`): `AxisRouting`,
`Calibration` fine points, `PlasmaComPort`/`PlasmaGreeting`, and the
`Feedback` section (see FEEDBACK.md).
6. **Legacy import**: `RioJoy.Tray.exe --import-profile <file>` merges a
single-profile JSON document; the `Import .ini` menu converts an original
`RIO.ini` (buttons, inverts, greeting).
6. **Legacy import**: the `Import .ini` tray menu converts an original
`RIO.ini` (buttons, inverts, greeting). For programmatic install-time
handoff, see the next section.
## Shipping a profile with your game
A game (or its installer/launcher) hands its profile to RIOJoy as a
**single-profile JSON document** plus one command:
```
RioJoy.Tray.exe --import-profile <your-game-riojoy-profile.json>
```
The document is one `RioProfile` object — the shipped
[`profiles/descent-d1x.json`](../profiles/descent-d1x.json) is the reference
example. It must carry a `"Name"` (imports without one are rejected), and it
bundles everything in one payload: `Buttons`, `MatchExecutables` (the
triggers), `Calibration`, `AxisRouting`, `PlasmaGreeting`, `Feedback`,
overlay labels. Author it in the profile editor, then lift the profile object
out of `%APPDATA%\RIOJoy\config.json` into your distribution.
The import merges into the user's `%APPDATA%\RIOJoy\config.json` — created
with defaults if absent, all other content preserved. A profile with the
same name (case-insensitive) is **replaced in place**, so re-running the
import on a game update is idempotent and never disturbs other games'
profiles.
Contract for installers:
- **Check the exit code, not stdout** (the tray is a GUI-subsystem exe;
console output only appears when redirected): `0` imported, `1` failed,
`2` usage, `3` **RIOJoy is running**.
- **The tray must not be running** during import — a running tray holds the
config in memory and its own saves would silently discard the merge, so
the import refuses (exit 3) instead. Sequence: quit/skip the tray →
import → (re)launch. On launcher-managed cabinets (TeslaConsole owns the
RIOJoy lifecycle) a game's install step can import safely before the next
boot.
- **Per-user, per-session**: the config lives under the user's `%APPDATA%`
and the running-instance check is per-session — run the import in the
user's session, not as an elevated SYSTEM step.
Nothing else needs registering: once the tray starts with the merged config,
the profile's `MatchExecutables` auto-activates it whenever the game's window
is foreground (tray in Auto mode).
For games you control end-to-end, keep the profile document in the *game's*
repo as the source of truth — dxx-rebirth does this, and a RIOJoy test
(`ShippedDescentProfile_MatchesDxxRebirthReferenceCopy`) asserts the two
checkouts stay byte-identical so drift is caught in CI.
## Testing without hardware or game