// OPENBOX DOCS

Save discovery and restore

Discover save locations, create versioned backups, and restore safely.

OpenBoxGL can discover where a game keeps its saves, back them up into versioned archives, and restore them with hard safety checks. This page covers the practical workflow: find saves, back them up, restore them, and recover when a restore is refused.

Before you start

  • The game must have a local file (path) so OpenBoxGL can identify it.
  • Saving works per game from the Save management section of the detail pane, or library-wide from the Health dialog (Scan library for saves).
  • Optional tools on PATH: Ludusavi and Hoard add external save-tool actions.

Discover save locations

Open a game's Save management and choose Discover locations. OpenBoxGL looks in the common places for each platform:

PlatformLocation checked
Steam Cloud~/.local/share/Steam/userdata/*/<appid>/remote (also .steam/steam and the Flatpak path)
PlayStation 2PCSX2 memcards (native and Flatpak)
PSPPPSSPP PSP/SAVEDATA
PlayStation 3RPCS3 dev_hdd0/home/00000001/savedata
GameCubeDolphin GC
Wii / WiiWareDolphin Wii/title
Wii UCemu mlc01/usr/save
Sega SaturnRetroArch saves (or ~/.mednafen)
RetroArchany save or state file under saves/states whose stem matches the game name

Candidates are shown as path + label + shared. Confirm them per game, or run Scan library for saves to apply discovered paths to every game at once. Confirmed paths are stored on the game (save_paths) and drive the library's Has saves view.

Back up saves

Back up now creates a ZIP per game under <data-dir>/save-backups/<hash>/ named YYYYmmdd-HHMMSS-<label>.zip containing a manifest.json and the configured save roots. Details:

  • Files are backed up individually; directories are walked.
  • Symlinks in save paths or the backup directory are refused.
  • After each backup, Save backup retention limit (0-500, default 10) trims the oldest archives.
  • Back up saves when a game session ends creates an on-close archive automatically and enforces the same retention.

The CLI form is python3 web_app.py --backup for whole-library backups; per-game save backups are a UI/API operation (POST /api/saves/backup).

Restore saves

Restore validates hard before writing anything:

  1. An automatic before-restore backup of the current saves is created first.
  2. The archive's manifest roots must match the game's currently configured save_paths exactly (count and order). If you edited the save paths after the backup, restore refuses with "Save backup roots do not match this game.", restore the paths to the archived values, or make a new backup.
  3. Members are validated: no absolute paths, no .., no duplicates, no symlinked destinations, per-member cap 4 GiB, total cap 32 GiB.
  4. Files are written with mode 0o600 through atomic copy.

Restoring is destructive by design, the before-restore archive is your safety copy.

Ludusavi and Hoard

Optional CLI save tools found on PATH:

  • Ludusavi: backup, restore, backups, find, run with --api JSON output and --force; an optional --path comes from the game's ludusavi_backup_path.
  • Hoard: backup, restore, list; backup/restore accept a game name.

Both treat restore as destructive (they overwrite local files), so run a backup first and verify the tool's own report.

Troubleshooting

ProblemCause / fix
"No configured save paths currently exist."The game has no discovered/confirmed save path. Run Discover locations or add one manually in Save management.
"Save backup paths may not be symlinks."A configured save path is a symlink; point save_paths at the real directory.
"Save backup roots do not match this game."The game's save_paths changed after the backup. Restore the archived paths (or back up again).
"Save backup not found."The archive name is not inside the game's backup directory; use a name from the backup list.
Restore does nothing / files missingCheck the diagnostic log; restores refuse symlink destinations and paths outside the data directory, and write 0o600.

See also