-
Notifications
You must be signed in to change notification settings - Fork 0
Roadmap
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_templatewith{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
| 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_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 v1.7+ SYSTEM.CNF (pattern + normalization) |
SV_IDENTITY_PLUGGABLE |
Done | Caller-supplied hash-DB callback |
| Manifest | Platform | Identity | Validation |
|---|---|---|---|
pcsx2_v17.cfg |
PS2 v1.7+ | text_pattern (SYSTEM.CNF) | Synthetic + real structure check |
pcsx2_legacy.cfg |
PS2 legacy | none (shared memcard) | Real structure: 12 .ps2 files found |
ppsspp.cfg |
PSP | none (folder-based) | No real data on this machine |
duckstation.cfg |
PS1 | none (stem-based) | Real structure: 8 .mcd files found |
dolphin_gc.cfg |
GameCube | rom_header (4 bytes at 0x00) | Real structure: 7 .gci files found |
retroarch_snes.cfg |
SNES | none (stem-based) | No real data on this machine |
ryujinx.cfg |
Switch | none (cnmt scan needed) | Real structure: 1825 files, 99 dirs found |
Status: Design memo written (docs/stem-matching-proposal.md). Awaiting human decision on Option A (library reads ROM filenames) vs Option B (caller always supplies game_id). Recommendation: Option B.
PPSSPP and RPCS3 use word-token scoring against PARAM.SFO titles for disambiguation. This is fundamentally a different algorithm from pattern matching. Deferred — would require a dedicated scoring engine.
PCSX2 legacy 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.
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.
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.
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.
Deliberately left as an implementation detail. The current binary TLV format works but could be optimized for larger datasets.
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.
sv_pull_external() currently uses a fixed 4KB buffer for pulled data. A streaming or callback-based model would handle larger saves.
A standalone binary exposing the same operations over an IPC protocol. Not yet implemented — the C ABI is the primary interface.
No mutexes or thread-local storage. The library is not thread-safe. Callers must serialize access.
Currently uses POSIX APIs (/dev/urandom, mkdir, rename, unlink). A Windows port would need _mktemp_s, MoveFileEx, etc.
See also: Architecture-Overview | Layer-2-Registration-and-Identity
libsavesync Wiki