Skip to content

Roadmap

abduznik edited this page Jul 17, 2026 · 8 revisions

Roadmap

Completed

IPC Binary (Layer 1)

Status: Implemented and tested (35 IPC integration tests).

  • Standalone binary (savesync-ipc) speaking NDJSON over stdin/stdout
  • 10 v1 methods: init, manifest_load, register_with_manifest, register, save, pull, pull_select, list_entries, list_registrations, unregister, shutdown
  • Full protocol documented in docs/ipc-protocol-v1.md
  • Python usage example: examples/python_client.py

CI/CD Pipeline

Status: Implemented and verified. All three platforms (Linux, macOS, Windows) pass the full 364-test suite.

  • ci.yml: build + test on every push/PR across ubuntu, macos, windows (fail-fast: false)
  • release.yml: triggered on v* tags, full test suite as gate, then package and publish archives via GitHub Releases
  • Documentation: docs/ci-cd-release.md

First Release (v0.1.0)

Status: Tagged and published. Release workflow succeeded.

  • Tag v0.1.0 pushed, CI passed on all 3 platforms, release published to GitHub Releases
  • Known issue: The release job builds all artifacts on ubuntu-latest (the runner: env vars are unused), so all three archives contain Linux binaries. Cross-platform artifact packaging needs a follow-up fix.

SV_MODE_STRATEGY / Phase 3

Status: Implemented and tested (48 strategy tests + 72 Phase 3 regression/coverage tests).

  • Manifest lifecycle (create, free, load, save) with key-value text format
  • Identity resolution: single explicit method per registration — NOT a runtime cascade
  • sv_register_with_manifest() for auto-detecting game_id at registration time
  • save_path_template with {game_id}, {platform}, {emulator}, {live_path} placeholders for magazine path organization
  • Integration with existing save/pull/retention pipeline
  • Graceful degradation: missing manifest, malformed header, pattern mismatch, hash-DB failure all fall back to DEFAULT behavior without crashing

Identity Methods (9 implemented)

Method Status Platforms
SV_IDENTITY_NONE Done All (caller supplies game_id)
SV_IDENTITY_SERIAL_CNF Done PS1/PS2 SYSTEM.CNF pattern extraction
SV_IDENTITY_SERIAL_SFO Done PSP PARAM.SFO
SV_IDENTITY_SERIAL_IPBIN Done Saturn IP.BIN
SV_IDENTITY_BOOT_HEADER Done Boot header extraction
SV_IDENTITY_CHECKSUM Done Header checksum + file size
SV_IDENTITY_ROM_HEADER Done Dolphin GC (4-byte ASCII at fixed offset)
SV_IDENTITY_TEXT_PATTERN Done PCSX2 SYSTEM.CNF, PPSSPP/RPCS3 directory names, Ryujinx cnmt
SV_IDENTITY_PLUGGABLE Done Caller-supplied hash-DB callback

Real-World Manifests (8 total, 5 validated)

Manifest Platform Identity Validation
pcsx2_folder.cfg PS2 (folder mode) text_pattern (SYSTEM.CNF) Validated against real save data
pcsx2_file.cfg PS2 (file mode) none (shared memcard) Manifest exists; shared memcard treated as opaque unit
ppsspp.cfg PSP text_pattern (directory basename) Validated against real save data
rpcs3.cfg PS3 text_pattern (directory basename) Validated against real save data
duckstation.cfg PS1 none (stem-based) Manifest exists; caller supplies game_id
dolphin_gc.cfg GameCube rom_header (4 bytes at 0x00) Validated against real save data
retroarch_snes.cfg SNES none (stem-based) Manifest exists; not validated against real local data
ryujinx.cfg Switch text_pattern (cnmt scan) Validated against real save data

Stem-Matching — Decided: Option B

Caller always supplies game_id derived from ROM filename. No library API change. Affected manifests (duckstation.cfg, retroarch_snes.cfg) document this convention in their comments. See docs/stem-matching-proposal.md for the full decision rationale. The library does not implement SV_IDENTITY_STEM_MATCH — Freegosy's real matching uses fuzzy word-token scoring, which a simple stem-compare would not cover.

Next

Fuzzy Title Scoring

Deferred — no known platform currently requires this. PPSSPP and RPCS3 were previously flagged for "fuzzy title scoring" but their real identification mechanisms are directory-name pattern matching, now implemented.

Shared Memcard Per-Game Extraction

PCSX2 file-mode shared memcards (Mcd001.ps2) multiplex many games in one binary file. Per-game extraction from within a memcard image is explicitly out of scope — libsavesync treats the entire memcard as a single opaque unit.

Hash-Database DAT-Format Parser

The pluggable callback API exists (sv_hash_db_lookup_fn) but no concrete DAT-format parser is shipped. The core remains database-free by design.

Tier Fallback Cascade — Considered and Rejected

A runtime cascade (try serial → checksum → hash-DB in sequence) was considered during Phase 3 design and rejected by design review. Real-world tools (RetroArch, RetroAchievements, Playnite) bind identification method to platform/format, not runtime cascading. Cascading produces nondeterministic results across runs. See Layer-2-Registration-and-Identity for the full rationale.

Directory/Archive Sub-file Granularity

Whether SAVE_SHAPE_DIRECTORY/ARCHIVE entries need per-file hash lists for finer diffing, or whether whole-container hashing is sufficient for v1. Current behavior: whole-container hashing.

Metadata Store On-Disk Format

Deliberately left as an implementation detail. The current binary TLV format works but could be optimized for larger datasets.

Relocation Poke-Check

sv_update_register()'s relocation logic for live_path — the poke check against destination path and copy-verify-then-delete-source flow needs more thorough testing.

Pull-External Buffer Model

sv_pull_external() currently uses a fixed 4KB buffer for pulled data. A streaming or callback-based model would handle larger saves.

Thread Safety

No mutexes or thread-local storage. The library is not thread-safe. Callers must serialize access.

Windows Support

Status: Fully working. All 364 tests pass on Windows (MinGW/gcc).

Portability shims added: sv_mkdir() (single-arg mkdir), sv_strndup() (missing GNU extension), sv_mkdtemp() (temp directory creation), sv_rename() (atomic replace with directory support via sv_rmdir_recursive). IPC test skipped on Windows (requires fork()/waitpid()). See docs/ci-cd-release.md for details.


See also: Architecture-Overview | Layer-2-Registration-and-Identity

Clone this wiki locally