File: README.md
Ludusavi
Ludusavi is a tool for backing up your PC video game save data,
written in Rust.
It is cross-platform and supports multiple game stores.
Features
- Ability to back up data from more than 19,000 games plus your own custom entries.
- Backup and restore for Steam, GOG, Epic, Heroic, Lutris, and other game libraries.
- Both a graphical interface and command line interface for scripting.
Tab completion is available for Bash, Fish, Zsh, PowerShell, and Elvish. - Support for:
- Saves that are stored as files and in the Windows registry.
- Proton saves with Steam.
- Steam screenshots.
- Available as a Playnite extension:
https://github.com/mtkennerly/ludusavi-playnite - Works on the Steam Deck.
This tool uses the Ludusavi Manifest
for info on what to back up for each game.
The data is primarily sourced from PCGamingWiki,
so please contribute any new or fixed data back to the wiki itself,
and your improvements will be incorporated into Ludusavi's data as well.
If you'd like to help translate Ludusavi into other languages,
check out the Crowdin project.
Demo
Installation
Download the executable for Windows, Linux, or Mac from the
releases page.
It's portable, so you can simply download it and put it anywhere on your system.
If you prefer, Ludusavi is also available via
Winget, Scoop, Flatpak, and Cargo.
Note:
- Windows users may see a popup that says
"Windows protected your PC",
because Windows does not recognize the program's publisher.
Click "more info" and then "run anyway" to start the program. - Mac users may see a popup that says
"Ludusavi can't be opened because it is from an unidentified developer".
To allow Ludusavi to run, please refer to this article,
specifically the section onIf you want to open an app [...] from an unidentified developer.
Usage
Detailed help documentation is available for several topics.
General
- Backup automation
- Backup exclusions
- Backup retention
- Backup validation
- Cloud backup
- Custom games
- Duplicates
- Filter
- Game launch wrapping
- Redirects
- Roots
- Selective scanning
- Transfer between operating systems
Interfaces
Other
Community
The community has created some additional resources you may find useful.
Please note that this is not an exhaustive list
and that these projects are not officially affiliated with Ludusavi itself:
- Secondary manifests:
- https://github.com/BloodShed-Oni/ludusavi-extra-manifests
- https://github.com/hblamo/ludusavi-emudeck-manifest
- https://github.com/hvmzx/ludusavi-manifests
- This has an example of using a scheduled GitHub workflow
to generate a manifest that adds more paths to the primary manifest's entries.
- This has an example of using a scheduled GitHub workflow
- Plugins for other applications:
- Decky Loader on Steam Deck: https://github.com/GedasFX/decky-ludusavi
- LaunchBox: https://github.com/johagan94/ludusavi-launchbox
- VS Code: https://marketplace.visualstudio.com/items?itemName=claui.ludusavi
- Tools:
Comparison with other tools
There are other excellent backup tools available, but not a singular
cross-platform and cross-store solution:
- GameSave Manager (as of v3.1.512.0):
- Only supports Windows.
- Much slower than Ludusavi. On the same hardware and with default settings,
an initial scan of the whole system takes 2 minutes in GSM versus 10 seconds in Ludusavi.
Performing a backup immediately after that scan takes 4 minutes 16 seconds in GSM versus 4.5 seconds in Ludusavi.
In this test, GSM found 257 games with 2.84 GB, and Ludusavi found 297 games with 2.95 GiB. - Closed source, so the community cannot contribute improvements.
- Interface can be slow or unresponsive.
For example, when clicking "select all / de-select all", each checkbox has to individually toggle itself.
With 257 games, this means you end up having to wait around 42 seconds. - Minimal command line interface.
- Can create symlinks for games and game data.
Ludusavi does not support this.
- Game Backup Monitor (as of v1.2.2):
- Does not support Mac.
- Database only covers 577 games (as of 2022-11-16), although it can also import
the Ludusavi manifest starting in 1.3.1. - No command line interface.
- Can automatically back up saves for a game after you play it.
Ludusavi can only do that in conjunction with a launcher like Playnite.
- Gaming Backup Multitool for Linux (as of v1.4.0.0):
- Only supports Linux and Steam.
- Database is not actively updated. As of 2022-11-16, the last update was 2018-06-05.
- No command line interface.
Development
Please refer to CONTRIBUTING.md.
File: docs/help/application-folder.md
Application folder
Ludusavi stores its configuration/logs/etc in the following locations:
- Windows:
%APPDATA%/ludusavi - Linux:
$XDG_CONFIG_HOME/ludusavior~/.config/ludusavi- Flatpak:
~/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi
- Flatpak:
- Mac:
~/Library/Application Support/ludusavi
Alternatively, if you'd like Ludusavi to store its configuration in the same
place as the executable, then simply create a file called ludusavi.portable
in the directory that contains the executable file. You might want to do that
if you're going to run Ludusavi from a flash drive on multiple computers.
Ludusavi also stores manifest.yaml (info on what to back up) here.
You should not modify that file, because Ludusavi will overwrite your changes
whenever it downloads a new copy.
File: docs/help/backup-automation.md
Backup automation
Normally, Ludusavi only runs when you launch it and manually request a backup.
However, it is possible to set up automatic backups that run in the background.
You can do this using any task automation app that can invoke Ludusavi's command line.
Windows: Task Scheduler
On Windows, you can use the built-in Task Scheduler app.
This is how to use it on Windows 11:
Search for
Task Schedulerin the Start Menu and click to launch it.On the right side of Task Scheduler, click
Create Basic Task....In the popup window, enter the task name (e.g.,
Ludusavi).
Clicknext.Select how often you'd like the backup to occur (e.g., daily).
Clicknext.If you want, you may adjust the exact date and time for the task to start.
Clicknext.Set the task action to
start a program.
Clicknext.Use the
browsebutton to select the full path to your copy ofludusavi.exe.In the
add argumentsfield, enter the following exactly:backup --forceYou can leave the
start infield blank.Click
next.On the last screen, click
finishto create the task.You can always view or edit the task on the left side of the main Task Scheduler window,
in theTask Scheduler Librarysection.
Linux: `cron`
On Linux, one option is cron.
For example, run crontab -e in your terminal to begin editing the list of tasks,
then add a daily backup task by adding this line:
0 0 * * * /opt/ludusavi backup --force(Use the actual path to your copy of ludusavi instead of /opt/ludusavi)
Linux: `systemd` timers
On Linux, another option is systemd timers.
For example, create two files:
~/.config/systemd/user/ludusavi-backup.service:text[Unit] Description="Ludusavi backup" [Service] ExecStart=/opt/ludusavi backup --force(Use the actual path to your copy of
ludusaviinstead of/opt/ludusavi)~/.config/systemd/user/ludusavi-backup.timer:text[Unit] Description="Ludusavi backup timer" [Timer] OnCalendar=*-*-* 00:00:00 Unit=ludusavi-backup.service [Install] WantedBy=timers.target
Then run systemctl --user enable ~/.config/systemd/user/ludusavi-backup.timer in your terminal.
File: docs/help/backup-retention.md
Backup retention
In the "other" screen's backup section,
you can configure how many backups to keep.
A full backup contains all save data for a game,
while a differential backup contains just the data that has changed since the last full backup.
When Ludusavi makes a new backup for a game, it will also remove any excess backups for that specific game.
When a full backup is deleted, its associated differential backups are deleted as well.
For example, if you configure a retention limit of 2 full and 2 differential,
then Ludusavi will create 2 differential backups for each full backup, like so:
- Backup #1: full
- Backup #2: differential
- Backup #3: differential
- Backup #4: full
- Backup #5: differential
- Backup #6: differential
When backup #7 is created, because the full retention is set to 2,
Ludusavi will delete backups 1 through 3.
If your full retention is only 1 and your differential retention is 1+,
then Ludusavi will keep the full backup and just delete the oldest differential as needed.
On the restore screen, you can use the three-dot menu next to a game to lock any of its backups.
Locked backups do not count toward the retention limits and are retained indefinitely.
File: docs/help/backup-structure.md
Backup structure
Within the target folder, for every game with data to back up, a subfolder
will be created based on the game's name, where some invalid characters are
replaced by_. In rare cases, if the whole name is invalid characters,
then it will be renamed toludusavi-renamed-<ENCODED_NAME>.Within each game's subfolder, there will be a
mapping.yamlfile that
Ludusavi needs to identify the game.When using the simple backup format, there will be some drive folders
(e.g.,drive-Con Windows ordrive-0on Linux and Mac) containing the
backup files, matching the normal file locations on your computer.
When using the zip backup format, there will be zip files instead.If the game has save data in the registry and you are using Windows, then
the game's subfolder will also contain aregistry.yamlfile (or it will
be placed in each backup's zip file).
If you are using Steam and Proton instead of Windows, then the Proton*.reg
files will be backed up along with the other game files instead.
During a restore, Ludusavi only considers folders with a mapping.yaml file.
Absolute vs relative paths
A common question is why Ludusavi stores files by their absolute path (e.g., C:\Users\foo\save.txt),
rather than using relative paths or placeholders (e.g., %USERPROFILE%\save.dat).
The motivation for this question is usually because people use multiple systems,
and the backed up files are tied to different usernames on each system
(or different Steam library locations, etc).
Although you can typically solve this by configuring redirects,
people often wonder why Ludusavi doesn't do that automatically.
The reason is that it may work in simple cases, but not in complex or unusual ones,
so Ludusavi errs on the side of caution.
For example, consider these potential challenges:
- You can configure Ludusavi to back up data from two different users on the same system at the same time.
It could become ambiguous which user folder to use when restoring the backup. - On Windows, you can relocate special system folders,
or on Linux, you can change theXDGvariables,
but some games may not respect that.
Let's say Ludusavi backed upC:\Users\foo\Documents\Some Game,
and then you used Windows Explorer -> Properties -> Location to move the Documents folder somewhere else.
Ludusavi wouldn't know if that game would use the Windows API to find and honor the new Documents location,
or if it would ignore that and use the standard location. - You can have multiple Steam libraries on the same system,
or the same game may belong to the primary library on one system and the secondary library on another.
Using absolute paths is the safest way to ensure that backups are always restored to the same place on the same system.
The trade-off is that you must define redirects to help Ludusavi understand your unique setup.
File: docs/help/backup-validation.md
Backup validation
On the restore screen, there is a "validate" button that will check the integrity
of the latest backup (full + differential, if any) for each game.
You won't normally need to use this, but it exists for troubleshooting purposes.
Specifically, this checks the following:
- Is mapping.yaml malformed?
- Is any file declared in mapping.yaml, but missing from the actual backup?
If it finds problems, then it will prompt you to create new full backups for the games in question.
At this time, it will not remove the invalid backups, outside of your normal retention settings.
File: docs/help/cloud-backup.md
Cloud backup
Ludusavi integrates with Rclone to provide cloud backups.
You can configure this on the "other" screen.
Any Rclone remote is supported, but Ludusavi can help you configure some of the more common ones:
Google Drive, OneDrive, Dropbox, Box, FTP servers, SMB servers, and WebDAV servers.
Support is verified for Rclone 1.62.2, but other versions should work as well.
If you turn on automtic synchronization,
then Ludusavi will check if your local and cloud saves are already in sync at the start of a backup.
If so, then any changes will be uploaded once the backup is done.
If they weren't in sync to begin with, then Ludusavi will warn you about the conflict and leave the cloud data alone.
You can perform an upload or download at any time on the "other" screen to resolve such a conflict.
Bear in mind that many factors can affect cloud sync performance,
including network speed, outages on the cloud side, and any limitations of Rclone itself.
You can try setting custom Rclone arguments if you find that it is too slow.
For example, --fast-list and/or --ignore-checksum can speed things up,
while --transfers=1 can help to avoid rate-limiting but may slow things down.
The "other" screen has a field to configure custom arguments,
and you can find documentation for them here: https://rclone.org/flags
You can also use other cloud backup tools of your choice,
as long as they can make the storage available as what looks like a normal folder.
For example:
- If you use something like Google Drive for Desktop,
which creates a special drive (G:) to stream from/to the cloud,
then you can set Ludusavi's backup target to a folder in that drive. - If you use something like Syncthing,
which continuously synchronizes a local folder across systems,
then you can set Ludusavi's backup target to that local folder. - If you use Rclone's mounting functionality,
then you can set Ludusavi's backup target to the mount folder.
Rclone and Flatpak
For Linux users who have installed Ludusavi via Flatpak,
the default Flatpak permissions will keep Ludusavi from seeing your system copy of Rclone.
Therefore, a copy of Rclone is included in the Flatpak environment,
which you can reference as /app/bin/rclone in Ludusavi.
If you prefer to use your system copy of Rclone,
one solution is to give Ludusavi host filesystem access
(flatpak override com.github.mtkennerly.ludusavi --filesystem=host).
Then, in Ludusavi, you can set the Rclone executable path to/var/run/host/usr/bin/rclone.
You can also configure Ludusavi's list of Rclone arguments to include--config /home//.config/rclone/rclone.conf
if you want to share the configuration from your system copy.
File: docs/help/command-line.md
Command line
Ludusavi provides a command line interface,
which you can use for automating tasks.
Run ludusavi --help for the overall CLI usage information,
or view info for specific subcommands, such as ludusavi manifest update --help.
You can also view the help text in the CLI docs.
Demo
JSON output
CLI mode defaults to a human-readable format, but you can switch to a
machine-readable JSON format with the --api flag.
Note that, in some error conditions, there may not be any JSON output,
so you should check if stdout was blank before trying to parse it.
If the command line input cannot be parsed, then the output will not be
in a stable format.
API output goes on stdout, but stderr may still be used for human-readable warnings/errors.
If stderr is not empty, you may want to log it,
since not all human-readable warnings have an API equivalent.
There is also an api command that supports using JSON for the input as well.
Schemas
Example
Output for backup --force --api:
{
"errors": {
"someGamesFailed": true,
},
"overall": {
"totalGames": 2,
"totalBytes": 150,
"processedGames": 1,
"processedBytes": 100,
},
"games": {
"Game 1": {
"decision": "Processed",
"files": {
"/games/game1/save.json": {
"bytes": 100
}
},
"registry": {
"HKEY_CURRENT_USER/Software/Game1": {
"failed": true
}
}
},
"Game 2": {
"decision": "Ignored",
"files": {
"/games/game2/save.json": {
"bytes": 50
}
},
"registry": {}
}
}
}File: docs/help/configuration-file.md
Configuration
Ludusavi stores its configuration in the application folder,
in a file named config.yaml.
If you're using the GUI, then it will automatically update the config file
as needed, so you don't need to worry about its content. However, if you're
using the CLI exclusively, then you'll need to edit config.yaml yourself.
Schema
Example
manifest:
url: "https://raw.githubusercontent.com/mtkennerly/ludusavi-manifest/master/data/manifest.yaml"
roots:
- path: "D:/Steam"
store: steam
backup:
path: ~/ludusavi-backup
restore:
path: ~/ludusavi-backup