Skip to content
CAI
Software that uses CAICheck a score

mtkennerly/ludusavi

65.4

Adequate · 29 September 2026

37.5k

lines of production code

Rust

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Ludusavi is a cross-platform application designed to back up and restore PC video game save data across multiple storefronts and launchers. It provides both a graphical interface and a command-line tool, supporting file-based saves, Windows registry entries, and Proton configurations. The system also exposes its core logic as a public library and offers a machine-readable API for programmatic integration and automation.

How it got here

2020 — Initial release and GUI development

8 changes.

Ludusavi transitioned from a prototype to a functional cross-platform application with an initial public release, introducing a full graphical user interface built with Iced alongside its existing command-line capabilities. The project established a public library crate for external integration and expanded test coverage for macOS packaging, backup validation, and Wine prefix handling. Infrastructure updates included upgrading to Rust edition 2024 and refining the application's visual identity with vector graphics.

2022–2023 — modular scan architecture and API expansion

7 changes.

This period focused on restructuring the core scanning logic into a modular system with change tracking, filtering, and support for multiple game launchers like Heroic, Legendary, and Lutris. It also introduced a new machine-readable API command for programmatic interaction and expanded localization support to include Arabic and Filipino.

2024–2026 — platform expansion and launcher support

5 changes.

The project expanded its platform support by adding macOS packaging scripts and enabling Windows DPI and long-path awareness. It also broadened game detection capabilities by integrating the Heroic launcher with Nile and sideloaded game sources, while migrating the Linux application ID for better distribution compliance.

Features

Add API usage example for game backups

A new example file (examples/api.rs) demonstrates how to use the ludusavi API to list and back up game data, specifically showing how to initialize the client, specify games (defaulting to 'Celeste' if none are provided), and execute a preview backup.

examples · high confidence

Added Arabic and Filipino language translations

The application now supports Arabic (ar-SA) and Filipino (fil-PH) locales. These new translation files provide localized strings for the user interface, including buttons, labels, error messages, and store names, allowing users in these regions to interact with the backup and restore features in their native language.

lang · high confidence

Added macOS app packaging and icon generation scripts

New scripts have been added to support creating a macOS application bundle. The \package-macos-app.sh\ script assembles the binary, icon, and \Info.plist\ metadata into a distributable \.app\ bundle and archives it. The \generate-macos-icon.py\ script converts the project's SVG icon into the required ICNS format with appropriate sizing and padding.

scripts · high confidence

Expanded game launcher detection with new and improved integrations

The scan/launchers module now detects games from additional sources and improves accuracy for existing ones. It adds support for the Faugus launcher and the generic filesystem scan, while Heroic Games Launcher detection now covers GOG, Nile, and sideloaded titles alongside Legendary. Lutris integration has been significantly enhanced to read both the SQLite database and YAML spec files, merge their data, and correctly resolve Wine prefix paths. The system also handles Flatpak environment path translation for Heroic and Faugus, and applies fuzzy matching to resolve ambiguous game titles across all supported launchers.

src/scan/launchers · high confidence

Heroic launcher now supports Nile and sideloaded games

The Heroic game launcher integration has been expanded to detect games from additional sources. In addition to the existing GOG and Epic (via Legendary) support, the scanner now reads from the Nile store cache (\store\_cache/nile\_library.json\) and the sideloaded apps library (\sideload\_apps/library.json\). This allows users to see their Nile-purchased titles and manually added sideloaded games in the scan results, alongside their existing Epic and GOG libraries.

src/scan/launchers/heroic · high confidence

Initial release of Ludusavi game save backup tool

Ludusavi is now a functional cross-platform application for backing up PC video game save data, replacing its previous prototype status. It supports Steam, GOG, Epic, Heroic, Lutris, and other game libraries, offering both a graphical interface and a command-line interface with tab completion. The tool handles file-based saves, Windows registry entries, and Proton saves, and includes features like cloud synchronization, custom game entries, and backup retention policies.

(repo-wide) · high confidence

Initial release of the graphical user interface

The application now includes a full graphical user interface built with the Iced framework, providing a visual alternative to the command-line tool. This interface allows users to manage game roots, configure primary and secondary manifests, and browse game lists. It supports scanning for changes, previewing and executing backups and restores, and managing custom games. The UI also features cloud synchronization capabilities, backup retention settings, and various filtering and sorting options for the game list.

src/gui · high confidence

New API command for machine-readable CLI output

The CLI now includes an \api\ command that accepts JSON input (via file or stdin) and returns structured JSON responses, enabling programmatic interaction with Ludusavi. This command supports requests to find game titles, check for application updates, and edit backup metadata (such as locking or adding comments). It also introduces an \--api\ flag on existing commands like \backup\ to output machine-readable JSON instead of human-readable text, facilitating integration with external scripts and tools.

src/cli · high confidence

New public library crate for Ludusavi internals

Ludusavi now exposes a public library crate (\src/lib.rs\) that allows external programs to access its core backup, restore, and scanning logic. This library re-exports the internal \api\ module (providing the \Ludusavi\ struct for programmatic operations), \cloud\ module (for Rclone synchronization), \path\ module (for strict path handling), \report\ module (for structured JSON output), and \resource\ modules (for configuration and manifest management). This enables developers to integrate Ludusavi's save data management capabilities directly into other applications.

src · high confidence

Support for Heroic Games Launcher 2.9.2+ environment variables

Added a new module in src/wrap/heroic.rs that detects games launched via Heroic by reading the HEROIC\_APP\_NAME and HEROIC\_APP\_RUNNER environment variables introduced in Heroic version 2.9.2. The implementation routes detection logic to specific sub-modules (gog, legendary, nile, sideload) based on the runner type, allowing the system to identify installed games from these sources without relying on older, deprecated detection methods.

src/wrap · high confidence

Behavioural changes

App icon converted to vector graphics

The application icon has been replaced with a new SVG vector graphic, ensuring it scales cleanly at any resolution without pixelation. This change updates the visual identity of the app across all platforms where the icon is displayed.

assets · high confidence

Introduce structured cache, config, and manifest resource models

The application now uses dedicated, serializable structs in src/resource to manage its state and settings. The new Cache model persists release check timestamps, migration flags, and recent game lists, enabling features like automatic app-update notifications and consistent configuration migrations. The Config model exposes granular user settings, including network security controls, manifest management (primary and secondary), root definitions, and custom game options. The Manifest model defines the supported game stores and operating systems, and introduces path placeholders (such as \<storeGameId\>) to allow more flexible game path resolution.

src/resource · high confidence

Linux app ID migrated to com.mtkennerly.ludusavi

The Linux desktop entry and metadata files have been updated to use the new application ID com.mtkennerly.ludusavi, replacing the previous com.github.mtkennerly.ludusavi identifier. The new desktop assets include explicit replacement directives to ensure a smooth transition for existing users, while the Flatpak assets retain the old ID for compatibility.

assets/flatpak, assets/linux · high confidence

New scan module with change tracking, filtering, and Wine redirect support

The \src/scan\ directory has been reorganized into a new modular structure that introduces game-level change detection (New, Different, Removed, Same, Unknown) and a comprehensive filtering system for uniqueness, completeness, enablement, change status, and manifest source. The module now supports dynamic Wine prefix redirects for portable backups between Windows and Wine/Proton, normalizes game titles to handle duplicates and special characters, and changes the Windows registry backup format from YAML to .reg. Additionally, it adds support for multiple launchers (Heroic, Legendary, Lutris, Faugus) and exposes scan results and backup statuses via the API.

src/scan · high confidence

Windows DPI and long-path awareness enabled

The Windows build now includes a resource manifest that enables per-monitor-v2 DPI awareness and long-path support. This ensures the application scales correctly on high-DPI displays and can handle file paths exceeding the legacy 260-character limit.

assets/windows · high confidence

Test coverage

Added test fixtures for Faugus, Heroic, Legendary, and Lutris launchers; Added test fixtures for Wine prefix validation; Added test fixtures for backup validation and migration scenarios; Added tests for macOS packaging and icon generation.

Dependencies

Upgrade to Rust edition 2024 and update dependencies

The project has upgraded to Rust edition 2024 and updated its dependencies, including Iced to 0.14.0, Clap to 4.5.17, and reqwest to 0.12.7. This update also includes a version bump to 0.31.0 and introduces new build configurations for binstall and profile optimizations.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 65 → 65 (+0.1)
  • Rubric changed (rubric-2026.09.9 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 77 → 77 (+0.0)
  • Architecture 98 → 86 (-11.5)
  • Maturity 54 → 54 (+0.2)
  • Readiness 66 → 66 (+0.6)
  • Security 80 → 85 (+5.0)
  • Event Sourcing 100 → 100 (+0.0)
  • Performance 100 (new)

Resolved (5)

  • Hotspot: src/gui/shortcuts.rs (src/gui/shortcuts.rs)
  • Hotspot: src/lang.rs (src/lang.rs)
  • Hotspot: src/path.rs (src/path.rs)
  • Hotspot: src/resource/config.rs (src/resource/config.rs)
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/gui/modal.rs)

New (8)

  • Dependency hygiene PARTLY measured — Cargo dependencies read, dependency currency not (crates.io unreachable)
  • Documentation: no architecture or design documentation (docs/help/troubleshooting.md)
  • Documentation: no installation or build instructions (docs/help/installation.md)
  • Inconsistent error handling pattern for read operations. Most other I/O operations on StrictPath (e.g., open, write_with_content, metadata, sha1) return a Result to handle potential I/O errors. However, read() returns a String directly, implying it panics or unwraps on error, while try_read() provides the safe Result variant. This breaks the uniform Result-returning convention established by the rest of the type.
  • Members sharing a duplicated core (5 members, 50+ identical tokens) (src/gui/modal.rs)
  • Projects may be oversized for their cohesion
  • Same inconsistency as above. same_content() returns a bool directly, while try_same_content() returns a Result. Comparing file content involves I/O which can fail, so the direct return is unsafe and inconsistent with the Result-returning try_same_content().
  • Same inconsistency as above. sha1() returns a String directly, while try_sha1() returns a Result. Given that computing a hash can fail (e.g., file not found, permission denied), the direct return is unsafe and inconsistent with the Result-returning try_sha1() and other methods like metadata().

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

mtkennerly/ludusavi was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 29 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 70f4abb31497fa5ed9b0d24098200f3662d6fda9 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-c4983f2d4e5c.