A simple CLI utility to backup and restore game saves
Project description
Save Scummer
Save-Scummer is a simple CLI utility to backup and restore game saves. This is intended for rogue-lite games like Rogue Legacy, FTL and Don't Starve, but it could also be applied to other games or non-game applications.
I made this because I enjoy roguelike/rogue-lite games, but when one starts to get too difficult, I may resort to save-scumming as an option to make the game a bit easier. When doing that manually, I find myself wasting precious seconds of time copying files back and forth, so naturally I decided to waste hours making it (semi-)automated instead.
A full backup utility (like Duplicati) or sync utility (like rsync) will obviously have many more features, but for the basic case of handling game saves, I wanted something simpler with concise command line usage.
Features
- Just provide a save directory (or glob pattern) to configure a new game
- Easily make backups, and restore them by most recent (default), time expressions (to indicate how far back in time you want to go), or choose from a list
- Tab autocompletion
Installation
Install with uv (recommended):
uv tool install save-scummer
Or with pip:
pip install save-scummer
Autocompletion (optional)
Tab autocompletion is available for most common shells: bash, fish, zsh and Windows PowerShell. To install, run:
ssc --install [shell name]
Usage
Save-scummer provides the command save-scummer (also aliased as ssc) with the following subcommands:
sh: ssc COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
add Add a game and its save directory
backup Create a backup of one, multiple, or all games
ls List all currently configured games
restore Restore a backup of the specified game
Add
Use ssc add to add (or update) a game and its save directory.
Relative paths, user paths, and glob patterns are supported:
ssc add game1 ~/Games/game1 # Add a dir (including any subdirs)
ssc add game1 '~/Games/game1/**' # Equivalent glob pattern (quotes required)
ssc add game2 'C:\Games\game2\*.sav' # Add files ending in .sav
Backup
Use ssc backup to create a new backup. Just specify the game title, and an optional description:
ssc backup game1 -d 'level 10 with full health'
Or just backup everything:
ssc backup --all
List
Use ssc ls to show a summary of all configured games:
╒════════╤═════════════════╤═════════════════════════════════╕
│ Title │ Total backups │ Last saved │
╞════════╪═════════════════╪═════════════════════════════════╡
│ game1 │ 0 │ never │
├────────┼─────────────────┼─────────────────────────────────┤
│ game2 │ 7 (94.96 KB) │ 2021-01-19 15:20 (23 hours ago) │
╘════════╧═════════════════╧═════════════════════════════════╛
Or use ssc ls [game title] to show more details on a specific game and its backups:
Game: game2
Total backups: 7 (94.96 KB)
Last saved: 2021-01-19 15:20 (23 hours ago)
Last backed up: 2021-01-19 16:24 (22 hours ago)
Source directory: /home/user/game2/saves
Backup directory: /home/user/.local/share/save-scummer/backups/game2
Backup files:
0: game2-2021-01-26T19:23:26.zip
1: game2-2021-01-20T16:33:42-pre-restore.zip
2: game2-2021-01-19T19:26:10.zip
3: game2-2021-01-19T18:31:58.zip
4: game2-2021-01-18T12:17:52.zip
5: game2-2021-01-17T16:18:09.zip
6: game2-2021-01-17T15:01:58.zip
Note that "Last saved" is the time that the source files were created/modified.
Restore
Use ssc restore to restore a backup. A specific backup can be indicated by backup
index, age, date/time, or filename. Otherwise, the most recent backup is restored.
Usage: ssc restore [OPTIONS] [TITLE]
Options:
-i, --index INTEGER Backup number (starting at 0, from newest to oldest)
-a, --age TEXT Minimum age (relative to current time)
-d, --date TEXT Maximum date/time (absolute)
-f TEXT Backup filename; either absolute or relative to backup dir
Backup specifiers
Index:
The backup index, sorted from newest to oldest, e.g.
"Restore the save from x backups ago." 0 is the latest backup, 1 is the
backup made before that, etc.
Negative values can also be given; -1 would give you the oldest backup.
See ls command for full list of available backups.
Age: Minimum age of the save to restore, e.g "I want to go back in time by 1 hour." Amounts of time can be specified in 'HH:MM' format, or with a number followed by a unit. Examples:
- '1:30' (an hour and a half ago)
- '30m' (or '30 minutes')
- '6h' (or '6 hours')
- '9 hours, 15 minutes' (or '9:15')
- '2d' (or '2 days')
- See pytimeparse for more formats
Date/Time: Maximum date/time of the save to restore, e.g., "I want to go back in time to 1:30 yesterday." Most date/time formats are supported. Examples:
- '16:30' or '4:30 PM' (today)
- '2021-01-20'
- 'August 3 2020'
- Most date/time formats are supported; see dateutil for more examples.
Filename: Either a full path or just the filename (relative to the backup dir)
Restore Examples
# Just restore the most recent backup
ssc restore game1
# Restore the backup made 2 backups ago (aka the 3rd most recent)
ssc restore game1 -i 2
# Restore a backup from (at least) an hour and a half ago
ssc restore game1 -a '1:30'
# Restore a backup from (at least) 2 days ago
ssc restore game1 -a 2d
# Restore a backup from 4:00 PM today or earlier
ssc restore game1 -d '4:00 PM'
# Restore a backup from March 22 or earlier
ssc restore game1 -d 'Mar 22 2021'
# Restore a backup by filename
ssc restore game1 -f game1-2021-01-20T00:09:10.zip
Development setup
To set up for local development (requires uv):
git clone https://github.com/JWCook/save-scummer && cd save-scummer
uv sync --frozen
To run linting, formatting, etc.:
pre-commit run -a
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file save_scummer-0.1.2.tar.gz.
File metadata
- Download URL: save_scummer-0.1.2.tar.gz
- Upload date:
- Size: 10.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e6bf76f4f5b7c55cdf7c8f9315fd68f1ed1fd764fcb2f19264bd1358aa6632e
|
|
| MD5 |
dfbe49c4f9edfe3bc90924ad633072d3
|
|
| BLAKE2b-256 |
9d1fa94d3b3c077a4aed1ee7d6d6d18592b06bda5654960ba0402885602e751e
|
Provenance
The following attestation bundles were made for save_scummer-0.1.2.tar.gz:
Publisher:
build.yml on JWCook/save-scummer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
save_scummer-0.1.2.tar.gz -
Subject digest:
0e6bf76f4f5b7c55cdf7c8f9315fd68f1ed1fd764fcb2f19264bd1358aa6632e - Sigstore transparency entry: 845275713
- Sigstore integration time:
-
Permalink:
JWCook/save-scummer@d11b36323eb5e70ca18ac8a6ec8cccf313da9e12 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JWCook
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@d11b36323eb5e70ca18ac8a6ec8cccf313da9e12 -
Trigger Event:
push
-
Statement type:
File details
Details for the file save_scummer-0.1.2-py3-none-any.whl.
File metadata
- Download URL: save_scummer-0.1.2-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5e5db3fbe98b2f0d629dfca30f1183c9944c7d4aae231d7d2ecf2c4140dab75
|
|
| MD5 |
fc9c989f336cb7386756abddce9a1936
|
|
| BLAKE2b-256 |
cf67982385d7a24a11277653b5a1ccf44c941fc56e9b60c04b05b267cbb2915e
|
Provenance
The following attestation bundles were made for save_scummer-0.1.2-py3-none-any.whl:
Publisher:
build.yml on JWCook/save-scummer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
save_scummer-0.1.2-py3-none-any.whl -
Subject digest:
c5e5db3fbe98b2f0d629dfca30f1183c9944c7d4aae231d7d2ecf2c4140dab75 - Sigstore transparency entry: 845275751
- Sigstore integration time:
-
Permalink:
JWCook/save-scummer@d11b36323eb5e70ca18ac8a6ec8cccf313da9e12 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JWCook
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@d11b36323eb5e70ca18ac8a6ec8cccf313da9e12 -
Trigger Event:
push
-
Statement type: