Skip to main content

A simple CLI utility to backup and restore game saves

Project description

Save Scummer

Build PyPI PyPI - Python Versions

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

save_scummer-0.1.2.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

save_scummer-0.1.2-py3-none-any.whl (13.4 kB view details)

Uploaded Python 3

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

Hashes for save_scummer-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0e6bf76f4f5b7c55cdf7c8f9315fd68f1ed1fd764fcb2f19264bd1358aa6632e
MD5 dfbe49c4f9edfe3bc90924ad633072d3
BLAKE2b-256 9d1fa94d3b3c077a4aed1ee7d6d6d18592b06bda5654960ba0402885602e751e

See more details on using hashes here.

Provenance

The following attestation bundles were made for save_scummer-0.1.2.tar.gz:

Publisher: build.yml on JWCook/save-scummer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for save_scummer-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c5e5db3fbe98b2f0d629dfca30f1183c9944c7d4aae231d7d2ecf2c4140dab75
MD5 fc9c989f336cb7386756abddce9a1936
BLAKE2b-256 cf67982385d7a24a11277653b5a1ccf44c941fc56e9b60c04b05b267cbb2915e

See more details on using hashes here.

Provenance

The following attestation bundles were made for save_scummer-0.1.2-py3-none-any.whl:

Publisher: build.yml on JWCook/save-scummer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page