500 lines
24 KiB
Markdown
500 lines
24 KiB
Markdown
<!-- Generated from the Runi source repository at v0.4.0. -->
|
|
<!-- Edit the original there, not this copy. -->
|
|
|
|
# Configuration schema
|
|
|
|
All paths below follow the XDG Base Directory spec (config vs. data vs.
|
|
cache) — see architecture.md (source repository)
|
|
for the full table, including external paths Runi reads/writes (Steam's
|
|
`compatibilitytools.d`, Steam library manifests, game install directories for
|
|
OptiScaler). Runi itself is installed via `pipx`/`uv tool install` into
|
|
an isolated environment, not system Python — see
|
|
architecture.md (source repository).
|
|
|
|
## Per-game config
|
|
|
|
`~/.config/runi/games/<id>.toml`, where `<id>` is Runi's own unique
|
|
registry key (`game.id` below) — **not** the same thing as umu's `GAMEID`,
|
|
which is deliberately shared across unrelated games. See
|
|
architecture.md (source repository) for why these are kept
|
|
separate.
|
|
|
|
```toml
|
|
# ~/.config/runi/games/steam-292030.toml
|
|
format_version = 9
|
|
|
|
[game]
|
|
id = "steam-292030" # our own unique registry key; always distinct
|
|
installation_id = "b1e6c9a0-..." # UUID for this concrete installation
|
|
display_name = "The Witcher 3"
|
|
exe = "/home/user/Games/witcher3/witcher3.exe"
|
|
args = []
|
|
store = "steam" # local|steam|gog|egs|itch|amazon|ubisoft
|
|
working_dir = "" # optional; defaults to exe's parent dir
|
|
platform = "windows" # original/content platform
|
|
port_target_os = "" # empty|windows|linux; non-empty means community port
|
|
platform_label = "" # custom origin label only when platform="other"
|
|
classification_source = "auto" # auto|manual; manual survives catalog reconciliation
|
|
install_root = "" # stable root for relative launch/action paths
|
|
|
|
[launch]
|
|
provider = "executable" # executable|xenia|rpcs3|ubisoft
|
|
engine = "proton" # proton|host|steam (see below)
|
|
content = "" # emulator content path when applicable
|
|
|
|
[store_binding]
|
|
installation_id = "" # shared store installation; empty for normal games
|
|
process_names = [] # executable names used for real game lifecycle detection
|
|
|
|
[[actions]]
|
|
id = "settings"
|
|
label = "Settings"
|
|
role = "configuration"
|
|
provider = "executable"
|
|
engine = "inherit"
|
|
exe = "Settings.exe"
|
|
args = []
|
|
working_dir = "."
|
|
content = ""
|
|
wrappers = false
|
|
|
|
[identity]
|
|
runi_game_id = "pgid_..." # canonical game across stores/installations
|
|
steam_appid = "292030" # dedicated Steam identity; empty when unknown
|
|
umu_gameid = "umu-292030" # exact GAMEID passed to UMU
|
|
steamgriddb_game_id = "" # confirmed SteamGridDB selection; not a Steam AppID
|
|
ubisoft_id = "" # Ubisoft Connect deeplink identity
|
|
ubisoft_space_id = "" # local Ubisoft catalogue correlation UUID
|
|
ubisoft_install_id = "" # local Ubisoft installation/catalogue identity
|
|
ubisoft_store_product_id = "" # Ubisoft Store master product/edition identity
|
|
canonical_title = "The Witcher 3: Wild Hunt"
|
|
source = "local Steam manifest" # evidence used for this resolution
|
|
confidence = "verified" # unknown|review|high|verified|manual
|
|
validated_at = "2026-07-07 15:00:00"
|
|
|
|
[runtime]
|
|
backend = "umu" # umu|native
|
|
proton = "GE-Proton9-27" # matches a discovered ProtonVersion name, or "auto"
|
|
prefix = "" # optional override; else derived from game.id/backend
|
|
cpu_affinity = "" # optional taskset CPU list, e.g. "0,1,2,3" or "0-3"
|
|
|
|
[env]
|
|
# free-form passthrough, e.g. DXVK_HUD = "fps"; dedicated OptiScaler provider keys must not be duplicated here
|
|
|
|
[gamescope]
|
|
enabled = false
|
|
output_width = 1920
|
|
output_height = 1080
|
|
render_width = 1280 # unset/equal to output = no upscaling
|
|
render_height = 720
|
|
filter = "linear" # fsr|nis|linear|nearest (-F)
|
|
scaler = "auto" # auto|integer|fit|fill|stretch (-S)
|
|
fullscreen = true
|
|
borderless = false
|
|
refresh_rate = 120 # nested display refresh; 0 = Gamescope default (-r)
|
|
fps_limit = 0 # optional cap; 0 = disabled (--framerate-limit)
|
|
|
|
[mangohud]
|
|
enabled = false
|
|
fps_limit = 0
|
|
config_file = "" # optional path; else MangoHud's own default resolution order
|
|
|
|
[linuwux]
|
|
enabled = false # wrap the launch with linuwux (LD_PRELOAD shim for
|
|
# Reflex/DenuvOwO-style DRM loaders); PATH-only dependency,
|
|
# never installed/managed by runi - see
|
|
# github.com/brcly/linuwux-runtime. Only GE-Proton/
|
|
# Proton-CachyOS are upstream-supported; `runi doctor`
|
|
# flags any other selected build as an advisory finding.
|
|
debug = false # LINUWUX_DEBUG=1; verbose, only for troubleshooting
|
|
|
|
[proton_tweaks]
|
|
fsr_fullscreen_hack = false
|
|
fsr_strength = 2
|
|
|
|
[optiscaler]
|
|
enabled = false
|
|
provider = "auto" # auto|manual|ge-integrated
|
|
applied_provider = "" # resolved/provisioned provider; managed by Runi
|
|
target_dll = "" # e.g. dxgi.dll
|
|
version = "default" # provider default or an exact OptiScaler version
|
|
fsr4_enabled = false # runner-managed FSR 4; integrated provider only
|
|
fsr4_version = "default"
|
|
|
|
[optiscaler.integrated_config]
|
|
# Structured Section.Option keys passed through PROTON_OPTISCALER_CONFIG.
|
|
# Example: "Upscalers.Dx12Upscaler" = "fsr31"
|
|
|
|
[lossless_scaling]
|
|
enabled = false # configure LSFG for the main Play action
|
|
multiplier = 2 # 2|3|4 displayed-frame multiplier
|
|
flow_scale = 1.0 # motion-estimation scale, 0.25..1.0
|
|
performance_mode = false # faster model with a small quality tradeoff
|
|
hdr_mode = false # compatibility mirror; managed by [hdr]
|
|
present_mode = "default" # default|fifo|mailbox|immediate; lsfg-vk 1.x
|
|
|
|
[hdr]
|
|
enabled = false # native game HDR; requires preconfigured Gamescope
|
|
|
|
[logging]
|
|
output = "console" # console|file - never both at once; see below
|
|
|
|
[customize]
|
|
applied_profile = "" # name of the currently-applied customize profile, if any
|
|
|
|
[notes]
|
|
key = "" # relates notes across multiple registrations of the same
|
|
# real-world game - defaults to game.id if unset; the notes
|
|
# themselves live as dated entries in
|
|
# ~/.config/runi/notes/<key>/<uuid>.md
|
|
|
|
[saves]
|
|
path = "" # save location for backup/restore - relative to the prefix's
|
|
# drive_c/, or an absolute path; the GUI can suggest paths
|
|
# from PCGamingWiki, but the user confirms what is stored here
|
|
```
|
|
|
|
The GUI presents each Gamescope width/height pair as one editable resolution
|
|
selector with common presets. New games added through the GUI use the primary
|
|
monitor's resolution for both output and render when it can be detected, while
|
|
`refresh_rate` and `fps_limit` remain `0`. Existing configurations and the
|
|
on-disk schema keep the separate integer fields shown above. The GUI's Display
|
|
Mode selector maps Fullscreen to `fullscreen = true`, Borderless Window to
|
|
`borderless = true`, and Windowed to both fields being false.
|
|
|
|
The GUI places MangoHud before Gamescope in Wrappers. Its header toggle maps to
|
|
`enabled`, its editable preset slider maps to `fps_limit`, and `config_file`
|
|
remains hidden under Advanced until explicitly expanded.
|
|
|
|
## Global config
|
|
|
|
`~/.config/runi/config.toml`:
|
|
|
|
```toml
|
|
[defaults]
|
|
backend = "umu"
|
|
proton = "auto"
|
|
|
|
[paths]
|
|
extra_proton_search_paths = []
|
|
prefixes_root = "" # empty = ~/.local/share/runi/prefixes; see below
|
|
|
|
[covers]
|
|
auto_download = true
|
|
steamgriddb_api_key = "" # optional; STEAMGRIDDB_API_KEY overrides this value
|
|
|
|
[library]
|
|
view = "grid" # grid|list
|
|
card_size = 80 # 50..100; fourth mark by default, maps 120px to 240px
|
|
|
|
[ai_research]
|
|
enabled = false # opt-in community HDR research; requests are still explicit
|
|
model = "gpt-5.6-terra" # managed Runi default
|
|
reasoning = "medium" # managed Runi default
|
|
```
|
|
|
|
### `[paths].prefixes_root`
|
|
|
|
Where per-game Wine prefixes live. Empty - the default - keeps them under the
|
|
data root at `~/.local/share/runi/prefixes`. Set it to move a prefix
|
|
collection that has outgrown that disk; `~` is expanded.
|
|
|
|
Three things worth knowing before setting it:
|
|
|
|
- **It must be absolute.** A relative value is ignored, and `runi doctor`
|
|
says so rather than letting it pass. Relative would resolve against the
|
|
working directory, and the launcher deliberately sets that to the game's
|
|
own folder - Wine prefixes would land inside the games.
|
|
- **Changing it moves nothing.** A game with no explicit `[runtime].prefix`
|
|
derives its prefix from this root, so the games whose prefixes stayed
|
|
behind would get a fresh empty one on next launch. Move the directories
|
|
across yourself; `runi doctor` reports any left behind
|
|
(`prefixes_root_unmoved`) until you do.
|
|
- **A per-game `[runtime].prefix` still wins.** This is only the default
|
|
root for games that have not been pointed somewhere specific.
|
|
|
|
Store installations keep their own prefixes under
|
|
`~/.local/share/runi/store-prefixes/`, and each one persists its path
|
|
absolutely, so this setting does not affect them.
|
|
|
|
### `[launch].engine = "steam"`
|
|
|
|
For a game **Steam launches**, not Runi. Steam builds the command, and Runi
|
|
contributes only what survives someone else owning the launch: the wrapper
|
|
prefix (gamescope, MangoHud, linuwux, `taskset`) and the environment. Put
|
|
this in the game's Steam launch options:
|
|
|
|
```
|
|
runi wrap <game-id> %command%
|
|
```
|
|
|
|
Steam substitutes the command it built for `%command%`, and `runi wrap`
|
|
prepends Runi's stages to it. Verify before launching anything for real:
|
|
|
|
```bash
|
|
runi wrap <game-id> --dry-run -- /usr/bin/proton run /path/game.exe
|
|
```
|
|
|
|
What still works: OptiScaler (both providers), frame generation, Proton FSR
|
|
tweaks, `WINEDLLOVERRIDES`, MangoHud, gamescope, linuwux and CPU affinity.
|
|
|
|
What has no effect, because Steam already decided it: `[runtime].backend`,
|
|
`[runtime].proton` and `[runtime].prefix` — Steam picks the compat tool and
|
|
uses `steamapps/compatdata/<appid>`. `runi config` says so when you set one
|
|
of them, and the GUI greys them out. `[runtime].cpu_affinity` is **not** in
|
|
that list: `taskset` is an argv prefix, so it survives.
|
|
|
|
Also given up: Runi's own log capture and `latest.log`, auxiliary launch
|
|
actions, and the exit code — all of which belong to whoever owns the process.
|
|
|
|
#### If the first launch seems to hang
|
|
|
|
Adding launch options often coincides with the game's *first* launch under a
|
|
different Proton build, and that first launch migrates the Wine prefix and
|
|
compiles shaders. On slow storage this takes minutes, with Steam showing
|
|
nothing but "Launching" throughout. It looks exactly like a broken wrapper.
|
|
|
|
Do not A/B it against a plain `mangohud %command%` and conclude from the
|
|
result: by the time you try the second option, the first attempt has already
|
|
paid the migration, so the comparison is a cold start against a warm one.
|
|
That mistake cost an hour during this feature's own validation.
|
|
|
|
Steam's own log is where the truth is:
|
|
|
|
```bash
|
|
tail -f ~/.steam/steam/logs/console-linux.txt
|
|
```
|
|
|
|
`Proton: Upgrading prefix from ... to ...` means it is working, not stuck.
|
|
And because Steam hides a wrapper's stderr, a shell script that logs `"$@"`
|
|
and then `exec`s `runi wrap ... "$@"` is the fastest way to see what Steam
|
|
actually passed and what Runi said about it.
|
|
|
|
`config.toml` is written with user-only (`0600`) permissions because it may
|
|
contain the SteamGridDB API key. Automatically downloaded covers live under
|
|
`~/.cache/runi/covers/`; imported custom covers are normalized and copied
|
|
to `~/.local/share/runi/covers/custom/<game.uid>/cover.jpg`. Custom covers
|
|
therefore do not depend on the original selected image remaining in place.
|
|
Validated identity lookups are cached for seven days under
|
|
`~/.cache/runi/identity/`; Runtime can force a fresh revalidation.
|
|
Local INI discovery is bounded to the installation, ignores symlinks and large
|
|
files, requires nearby Steam API evidence, and never persists an AppID until
|
|
Steam confirms that it belongs to a game.
|
|
|
|
The OpenAI API key is deliberately absent from this schema. Preferences stores
|
|
it in the system keyring, can keep it only for the current process, or reads
|
|
`OPENAI_API_KEY`. Community HDR findings contain no secret and live in
|
|
`~/.local/share/runi/knowledge.sqlite3`.
|
|
|
|
## Field notes
|
|
|
|
- **`game.id`** must be unique — it's the config filename and the default
|
|
prefix folder name. For Steam titles it's `steam-<appid>`; otherwise a
|
|
slugified name/filename. Never the literal `umu-default`. Uniqueness is
|
|
enforced, not assumed: `register_game()` refuses an id that already exists,
|
|
so registering a second copy of a game can never replace the first.
|
|
A second copy is offered `<slug>-<build version>` read from the executable
|
|
(`mortal-shell-ii-cl92120`), never a numeric counter; when no build version
|
|
tells the copies apart, Runi asks for a discriminator rather than
|
|
inventing one. The build version is *not* stored as a config field and is
|
|
not stable across an in-place game patch — the id is a name, not a
|
|
fingerprint.
|
|
- **Parallel installations** of the same game share `identity.*` (and
|
|
therefore the PGID-keyed notes, artwork and compatibility knowledge) but
|
|
keep separate Wine prefixes, settings, environment overrides, logs, save
|
|
backups and mod receipts.
|
|
- **`game.installation_id`** is a separate UUID4 generated once for a concrete
|
|
installation. Unlike `game.id` (a human-typed/derived slug), it is
|
|
what Runi uses internally to detect "has this game's install
|
|
directory been replaced externally" (stamped as a small marker file,
|
|
`<game_dir>/.runi-installation-id`, checked by `core/config.py`'s
|
|
`install_marker_matches()`/`runi doctor`). Not meant to be hand-edited.
|
|
- **`identity.runi_game_id`** is Runi's opaque canonical identity,
|
|
shared by separate installations and resolved from catalog aliases.
|
|
- **`identity.ubisoft_store_product_id`** identifies the commercial Ubisoft
|
|
Store edition used to resolve official boxshots. It is an edition alias and
|
|
never replaces `runi_game_id`; local catalog entries persist it under
|
|
`aliases.ubisoft_store`.
|
|
- **`identity.umu_gameid`** is the value forwarded as umu's `GAMEID` env var.
|
|
`umu-<appid>` for Steam titles (so community protonfixes key correctly),
|
|
`umu-default` otherwise. Independently editable if you later find the
|
|
specific umu-ID for a GOG/Epic title in the community `umu-database`.
|
|
- **`identity.steam_appid`** is independent of installation source. It is used
|
|
for Steam CDN artwork, Steam-aware save discovery and recipe matching.
|
|
- **`identity.steamgriddb_game_id`** is written only after an exact automatic
|
|
match or an explicit artwork selection. It never implies a Steam AppID or
|
|
UMU identity.
|
|
- **`game.display_name`** is the user-facing name and the artwork search term.
|
|
It is editable and is not treated as a stable game identity.
|
|
- **`game.platform`** records the original/content platform. A port from
|
|
GameCube to Linux therefore keeps `platform = "gamecube"`.
|
|
- **`game.port_target_os`** records the OS of a community port's executable.
|
|
The Library derives Windows Ports/Linux Ports from it; it is not a launch
|
|
backend. `classification_source = "manual"` protects a player correction
|
|
from later catalog reconciliation.
|
|
- **`runtime.proton = "auto"`** selects the newest installed GE-Proton
|
|
itself (umu backend only); for the native backend, `proton` must name an
|
|
already-discovered/installed `ProtonVersion`.
|
|
- The GUI presents `runtime.backend` as **Launch engine** and separates it from
|
|
**Runner family** and **Version**. The family is derived from the concrete
|
|
`runtime.proton` name, so existing TOML and CLI usage remain valid. Curated
|
|
families are GE-Proton, UMU-Proton, Proton-CachyOS, Proton-EM and Steam-managed Proton
|
|
Experimental; other discovered tools remain available under Advanced.
|
|
- **Gamescope refresh and FPS cap are independent.** `refresh_rate` controls
|
|
the nested display exposed to the game; `fps_limit` applies an optional cap.
|
|
- **`runtime.cpu_affinity`** wraps the complete launch chain with
|
|
`taskset --cpu-list` without invoking a shell. This supports older games
|
|
that fail when they detect or execute across too many CPU cores.
|
|
- **`[gamescope].filter` vs `[gamescope].scaler`** are independent axes
|
|
(gamescope's `-F` and `-S` flags) — filter is the upscale algorithm, scaler
|
|
is how the image is fit into the output window.
|
|
- **`[env]`** is the escape hatch: anything not modeled as a named field
|
|
(custom `DXVK_HUD`, `PROTON_LOG`, etc.) goes here and is passed through
|
|
as-is.
|
|
- **`[lossless_scaling]`** configures frame generation through a separately
|
|
installed lsfg-vk layer and a user-owned Steam copy of Lossless Scaling.
|
|
Runi detects both dependencies and never writes lsfg-vk's global config
|
|
or distributes `Lossless.dll`. Disabled means no Runi override, so an
|
|
external lsfg-vk profile can still apply. See
|
|
[lossless-scaling.md](lossless-scaling.md).
|
|
- **`[hdr]`** is the single per-game source of truth for native HDR. Enabling
|
|
it requires Gamescope to be configured already, adds `--hdr-enabled`, enables
|
|
the Gamescope WSI layer and selects the runner-supported Proton/DXVK HDR
|
|
variable. Runi only inspects the desktop HDR state; it never changes a
|
|
monitor or compositor setting. Raw `DXVK_HDR`, `ENABLE_GAMESCOPE_WSI`,
|
|
`PROTON_ENABLE_HDR` and `PROTON_USE_HDR` entries conflict with managed HDR.
|
|
See [hdr.md](hdr.md).
|
|
- **`[logging].output`** picks where a game's process output goes:
|
|
`console` (default — inherits the terminal, same as always) or `file`
|
|
(redirected to `~/.local/share/runi/logs/<installation-id>/<timestamp>.log`, with
|
|
a `latest.log` symlink kept pointing at the most recent run). Never both at
|
|
once. `runi run <id> --log`/`--console` transiently override this for
|
|
a single run without touching the saved config.
|
|
- **`[customize].applied_profile`** tracks which named "customize" profile
|
|
(community upscaler/mod workaround) is currently applied, if any — see
|
|
[customize-profiles.md](customize-profiles.md). Set/cleared by
|
|
`runi customize apply|remove`, not meant to be hand-edited.
|
|
- **`[notes].key`** is the only thing actually stored in the game's own
|
|
config — the entries live under
|
|
`~/.config/runi/notes/<key>/<uuid>.md` (`key` defaults to the PGID
|
|
if unset). Each entry has a date, title, and Markdown body. The GUI can
|
|
relink a re-added game to an existing collection. Notes are deliberately kept
|
|
*outside* the game's own config so notes survive `runi remove` —
|
|
set the *same* key on two different registrations (e.g. after a
|
|
reinstall creates a new `game.id`) to relate their notes. A deliberately
|
|
lightweight starting point rather than a designed findings/compatibility
|
|
schema — see roadmap.md (source repository).
|
|
- **`[saves].path`** is where a game's save files live, for
|
|
`runi saves backup|restore|list`. The GUI can query PCGamingWiki,
|
|
resolve common Windows paths against the Wine prefix, and present candidates;
|
|
the user must confirm the stored path. Relative paths resolve against the Wine prefix's
|
|
`drive_c/` (most saves live under a Windows user-profile path there);
|
|
absolute paths are used as-is.
|
|
|
|
Every field above (plus its type, default, and description) is also
|
|
queryable straight from the CLI — see `runi schema` below.
|
|
|
|
## Compatibility boundary
|
|
|
|
Schema v8 is written for new/edited registrations. Schema-v2 through v7
|
|
registrations
|
|
remain readable as Windows executable/Proton launches and are not rewritten by
|
|
read-only operations. Their first later save creates a version-labelled backup,
|
|
for example `.toml.v2.bak`, before writing v8. Schema v1 and unknown future
|
|
schemas remain rejected.
|
|
|
|
## The `--json` output contract
|
|
|
|
`--json` is an interface, not a convenience: the Decky plugin reads Runi by
|
|
running these commands and parsing stdout, so the shape is the coupling
|
|
between the two. Three properties hold everywhere.
|
|
|
|
**Every document is an object.** Listings carry their payload under a named
|
|
key rather than being a bare array, which leaves room beside it:
|
|
|
|
```json
|
|
{ "games": [ ... ] } // list, steam-scan
|
|
{ "sections": [ ... ] } // schema
|
|
{ "versions": [ ... ] } // versions
|
|
{ "findings": [ ... ] } // doctor
|
|
```
|
|
|
|
**A failure carries the exception type**, because `core` raises typed
|
|
exceptions precisely so a caller can tell one from another, and a sentence
|
|
gives a program nothing to branch on:
|
|
|
|
```json
|
|
{ "error": { "type": "GameNotFoundError", "message": "no such game: minos" } }
|
|
```
|
|
|
|
**A setting that will not take effect says so in the document.** `runi config
|
|
--json` reports both what changed and what that change cannot do, instead of
|
|
sending the warning to stderr where a JSON consumer never reads it:
|
|
|
|
```json
|
|
{
|
|
"id": "minos", "updated": ["runtime.proton"], "ineffective": ["runtime.proton"],
|
|
"notes": [{ "section": "runtime", "fields": ["backend", "proton", "prefix"],
|
|
"engine": "steam",
|
|
"reason": "Steam picks the compat tool and owns the prefix" }],
|
|
"config": { ... }
|
|
}
|
|
```
|
|
|
|
`--edit` is refused under `--json`: it opens an interactive editor, which a
|
|
program has no use for.
|
|
|
|
## CLI reference
|
|
|
|
- `runi add [<exe>] [--id ID] [--name NAME] [--store local|steam|gog|egs] [--steam-appid N] [--backend umu|native] [--proton NAME|auto] [--args ...]`
|
|
- `runi list [--json]`
|
|
- `runi versions [--refresh] [--backend umu|native|all] [--json]`
|
|
- `runi versions list-remote --source ge-proton|umu-proton|proton-cachyos|proton-em`
|
|
- `runi versions install <source> [<version>|latest] [--json]`
|
|
- `runi versions remove <name>`
|
|
- `runi run <id> [--dry-run] [--verbose] [--debug] [--log|--console]`
|
|
- `runi config <id> [--set section.key=value] [--edit] [--json]`
|
|
- `runi steam-scan [--json]`
|
|
- `runi optiscaler install <id> [--dll dxgi.dll] [--version latest]`
|
|
- `runi optiscaler configure <id> [--provider auto|manual|ge-integrated] [--dll dxgi.dll] [--version default] [--fsr4]`
|
|
- `runi optiscaler status <id>`
|
|
- `runi optiscaler migrate <id> --to manual|ge-integrated [--dll dxgi.dll] [--version default] [--fsr4]`
|
|
- `runi optiscaler remove <id>`
|
|
- `runi remove <id> [--keep-prefix]`
|
|
- `runi schema [--section runtime|gamescope|mangohud|linuwux|proton_tweaks|optiscaler|lossless_scaling|logging|customize|notes|saves] [--json]`
|
|
- `runi customize list [--json]`
|
|
- `runi customize apply <id> <profile-name-or-path> [--json]`
|
|
- `runi customize remove <id> [--json]`
|
|
- `runi mangohud-preset list [--json]`
|
|
- `runi mangohud-preset save <name> (--from-file <path> | --from-game <id>) [--description TEXT] [--json]`
|
|
- `runi mangohud-preset apply <name> <id> [--json]`
|
|
- `runi mangohud-preset remove <id> [--json]`
|
|
- `runi prefix open <id>`
|
|
- `runi lossless-scaling [--json]` — whether frame generation is usable
|
|
- `runi lossless-scaling install [--version TAG] [--json]` — install the
|
|
lsfg-vk Vulkan layer (never `Lossless.dll`); refuses if a layer of that
|
|
name is already registered. See [lossless-scaling.md](lossless-scaling.md)
|
|
- `runi lossless-scaling remove [--json]` — remove the layer runi installed
|
|
- `runi bundle export <id> --output <file.pfy>`
|
|
- `runi bundle inspect <file.pfy>`
|
|
- `runi bundle verify <file.pfy>`
|
|
- `runi bundle import <file.pfy> [--exe <path>] [--as <new-id>]`
|
|
- `runi saves backup <id> [--json]`
|
|
- `runi saves list <id> [--json]`
|
|
- `runi saves restore <id> <backup-file> [--json]`
|
|
- `runi saves import-ludusavi <id> <backup-folder> [--preview] [--no-set-save-path] [--json]`
|
|
- `runi gui` — launches the PySide6 GUI (optional `[gui]` extra)
|
|
- `runi doctor [--fix] [--json]` — audits the registry against the
|
|
real filesystem: missing exes, stale OptiScaler/customize state, an
|
|
install-directory marker mismatch, orphaned prefix/save-backup/log
|
|
directories. `--fix` auto-clears the safe findings (stale state, marker
|
|
mismatch) - never deletes an orphaned directory
|
|
- `runi doctor remove-orphan <path> [--yes] [--json]` — permanently
|
|
deletes one orphaned directory (the exact path as printed by
|
|
`runi doctor`); confirms first (showing total size) unless `--yes`
|
|
- `runi notes <id> [--edit] [--json]` — view/edit a game's findings
|
|
(stored outside its own config, see `[notes].key` above)
|
|
|
|
See [user-flows.md](user-flows.md) for these in context, and
|
|
[customize-profiles.md](customize-profiles.md) for the profile TOML format.
|