{"id":17089486,"url":"https://github.com/jwcook/save-scummer","last_synced_at":"2025-04-12T22:10:37.722Z","repository":{"id":57464022,"uuid":"331053480","full_name":"JWCook/save-scummer","owner":"JWCook","description":"A CLI utility for backing up \u0026 restoring roguelike game saves","archived":false,"fork":false,"pushed_at":"2025-02-25T05:20:25.000Z","size":73,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T12:39:03.965Z","etag":null,"topics":["backups","cli","roguelike","roguelite","savegame"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JWCook.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-01-19T17:13:31.000Z","updated_at":"2025-02-25T05:20:29.000Z","dependencies_parsed_at":"2023-12-29T06:25:26.676Z","dependency_job_id":"85c0c1c5-2da5-4b15-9035-099065d5a043","html_url":"https://github.com/JWCook/save-scummer","commit_stats":{"total_commits":20,"total_committers":1,"mean_commits":20.0,"dds":0.0,"last_synced_commit":"5822e84fa1d87d2d3db95d69a013234d213b4322"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWCook%2Fsave-scummer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWCook%2Fsave-scummer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWCook%2Fsave-scummer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JWCook%2Fsave-scummer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JWCook","download_url":"https://codeload.github.com/JWCook/save-scummer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248637771,"owners_count":21137538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backups","cli","roguelike","roguelite","savegame"],"created_at":"2024-10-14T13:47:26.618Z","updated_at":"2025-04-12T22:10:37.716Z","avatar_url":"https://github.com/JWCook.png","language":"Python","readme":"# Save Scummer\n\n[![Build](https://github.com/JWCook/save-scummer/actions/workflows/build.yml/badge.svg)](https://github.com/JWCook/save-scummer/actions)\n[![PyPI](https://img.shields.io/pypi/v/save-scummer?color=blue)](https://pypi.org/project/save-scummer)\n[![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/save-scummer)](https://pypi.org/project/save-scummer)\n\n* [Features](#features)\n* [Installation](#installation)\n  * [Autocompletion](#autocompletion--optional-)\n* [Usage](#usage)\n  * [Add](#add)\n  * [Backup](#backup)\n  * [List](#list)\n  * [Restore](#restore)\n    * [Backup specifiers](#backup-specifiers)\n    * [Restore Examples](#restore-examples)\n\n\nSave-Scummer is a simple CLI utility to backup and restore game saves.\nThis is intended for rogue-lite games like **Rogue Legacy**, **FTL** and **Don't Starve**,\nbut it could also be applied to other games or non-game applications.\n\nI made this because I enjoy roguelike/rogue-lite games, but when one starts to get too difficult,\nI may resort to [save-scumming](https://tvtropes.org/pmwiki/pmwiki.php/Main/SaveScumming) as an\noption to make the game a bit easier. When doing that manually, I find myself wasting precious _seconds_\nof time copying files back and forth, so naturally I decided to waste _hours_ making it (semi-)automated\ninstead.\n\nA full backup utility (like [Duplicati](https://github.com/duplicati/duplicati)) or sync utility\n(like [rsync](https://github.com/WayneD/rsync)) will obviously have _many_ more features, but for the\nbasic case of handling game saves, I wanted something simpler with concise command line usage.\n\n# Features\n* Just provide a save directory (or glob pattern) to configure a new game\n* Easily make backups, and restore them by most recent (default), time expressions\n  (to indicate how far back in time you want to go), or choose from a list\n* Tab autocompletion\n\n# Installation\nInstall with [uv](https://docs.astral.sh/uv) (recommended):\n```sh\nuv tool install save-scummer\n```\n\nOr with pip:\n```sh\npip install save-scummer\n```\n\n## Autocompletion (optional)\nTab autocompletion is available for most common shells: **bash, fish, zsh** and Windows **PowerShell**.\nTo install, run:\n```sh\nssc --install [shell name]\n``````\n\n# Usage\nSave-scummer provides the command `save-scummer` (also aliased as `ssc`) with the following subcommands:\n\n```sh\nsh: ssc COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  add      Add a game and its save directory\n  backup   Create a backup of one, multiple, or all games\n  ls       List all currently configured games\n  restore  Restore a backup of the specified game\n```\n\n## Add\nUse `ssc add` to add (or update) a game and its save directory.\n\nRelative paths, user paths, and [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming))\nare supported:\n```sh\nssc add game1 ~/Games/game1           # Add a dir (including any subdirs)\nssc add game1 '~/Games/game1/**'      # Equivalent glob pattern (quotes required)\nssc add game2 'C:\\Games\\game2\\*.sav'  # Add files ending in .sav\n````\n\n## Backup\nUse `ssc backup` to create a new backup. Just specify the game title, and an optional description:\n```sh\nssc backup game1 -d 'level 10 with full health'\n```\nOr just backup everything:\n```sh\nssc backup --all\n```\n\n## List\nUse `ssc ls` to show a summary of all configured games:\n```sh\n╒════════╤═════════════════╤═════════════════════════════════╕\n│ Title  │ Total backups   │ Last saved                      │\n╞════════╪═════════════════╪═════════════════════════════════╡\n│ game1  │ 0               │ never                           │\n├────────┼─────────────────┼─────────────────────────────────┤\n│ game2  │ 7 (94.96 KB)    │ 2021-01-19 15:20 (23 hours ago) │\n╘════════╧═════════════════╧═════════════════════════════════╛\n```\n\nOr use `ssc ls [game title]` to show more details on a specific game and its backups:\n```sh\nGame:               game2\nTotal backups:      7 (94.96 KB)\nLast saved:         2021-01-19 15:20 (23 hours ago)\nLast backed up:     2021-01-19 16:24 (22 hours ago)\nSource directory:   /home/user/game2/saves\nBackup directory:   /home/user/.local/share/save-scummer/backups/game2\nBackup files:\n0:  game2-2021-01-26T19:23:26.zip\n1:  game2-2021-01-20T16:33:42-pre-restore.zip\n2:  game2-2021-01-19T19:26:10.zip\n3:  game2-2021-01-19T18:31:58.zip\n4:  game2-2021-01-18T12:17:52.zip\n5:  game2-2021-01-17T16:18:09.zip\n6:  game2-2021-01-17T15:01:58.zip\n```\n\nNote that \"Last saved\" is the time that the source files were created/modified.\n\n## Restore\n\nUse `ssc restore` to restore a backup. A specific backup can be indicated by backup\n **index, age, date/time, or filename**. Otherwise, the most recent backup is restored.\n\n```sh\nUsage: ssc restore [OPTIONS] [TITLE]\n\nOptions:\n  -i, --index INTEGER  Backup number (starting at 0, from newest to oldest)\n  -a, --age TEXT       Minimum age (relative to current time)\n  -d, --date TEXT      Maximum date/time (absolute)\n  -f TEXT              Backup filename; either absolute or relative to backup dir\n```\n\n### Backup specifiers\n\n**Index:**\nThe backup index, sorted from newest to oldest, e.g.\n**\"Restore the save from x backups ago.\"** 0 is the latest backup, 1 is the\nbackup made before that, etc.\nNegative values can also be given; -1 would give you the oldest backup.\nSee `ls` command for full list of available backups.\n\n**Age:**\nMinimum age of the save to restore, e.g **\"I want to go back in time by 1 hour.\"**\nAmounts of time can be specified in 'HH:MM' format, or with a number followed by a unit.\nExamples:\n* '1:30' (an hour and a half ago)\n* '30m' (or '30 minutes')\n* '6h' (or '6 hours')\n* '9 hours, 15 minutes' (or '9:15')\n* '2d' (or '2 days')\n* See [pytimeparse](https://github.com/wroberts/pytimeparse) for more formats\n\n**Date/Time:**\nMaximum date/time of the save to restore, e.g., **\"I want to go back in\ntime to 1:30 yesterday.\"** Most date/time formats are supported.\nExamples:\n* '16:30' or '4:30 PM' (today)\n* '2021-01-20'\n* 'August 3 2020'\n* Most date/time formats are supported; see\n[dateutil](https://dateutil.readthedocs.io/en/stable/examples.html#parse-examples)\nfor more examples.\n\n**Filename:**\nEither a full path or just the filename (relative to the backup dir)\n\n### Restore Examples\n\n```sh\n# Just restore the most recent backup\nssc restore game1\n\n# Restore the backup made 2 backups ago (aka the 3rd most recent)\nssc restore game1 -i 2\n\n# Restore a backup from (at least) an hour and a half ago\nssc restore game1 -a '1:30'\n\n# Restore a backup from (at least) 2 days ago\nssc restore game1 -a 2d\n\n# Restore a backup from 4:00 PM today or earlier\nssc restore game1 -d '4:00 PM'\n\n# Restore a backup from March 22 or earlier\nssc restore game1 -d 'Mar 22 2021'\n\n# Restore a backup by filename\nssc restore game1 -f game1-2021-01-20T00:09:10.zip\n```\n\n# Development setup\nTo set up for local development (requires [uv](https://docs.astral.sh/uv/getting-started/installation/)):\n```sh\ngit clone https://github.com/JWCook/save-scummer \u0026\u0026 cd save-scummer\nuv sync --frozen\n```\n\nTo run linting, formatting, etc.:\n```sh\npre-commit run -a\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwcook%2Fsave-scummer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwcook%2Fsave-scummer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwcook%2Fsave-scummer/lists"}