Direct answer
There is no official Ren'Py utility that validates a restored .save or persistent file before the game attempts to load it into live state. Compatibility can only be checked by inspecting metadata that Ren'Py writes at save time and by comparing it to the current build, with the caveat that any unpickling of a save file executes pickled code.
Confirmed facts
- Ren'Py .save files are pickle-serialized dictionaries. A top-level structure contains game state and a game_version string that reflects the version string active when the save was created.
- The persistent file is a separate pickle-serialized dictionary for the global persistent namespace. It has no built-in version stamp and is independent of individual save slots.
- Loading a save that was created with a different script structure or Ren'Py engine can fail or produce inconsistent state. Ren'Py will raise a save-related exception when it detects incompatibility during a real load.
Likely explanation and practical verification
The following approach is based on documented Ren'Py internals and is version-sensitive. It should be treated as a review draft until verified against your specific Ren'Py release.
1. Verify save compatibility without full game load
- Read the save metadata in a read-only context. In Ren'Py Python code you can attempt to load the save dictionary via the internal savegame API, e.g.
renpy.savegame.load_save, which returns the unpickled save contents.
- Extract the saved version:
save_data.get('game', {}).get('game_version').
- Compare to the current build:
renpy.config.game_version or renpy.version. A mismatch indicates likely incompatibility.
- Wrap the load in a try/except for
renpy.exceptions.SaveError or generic exceptions and log the result with renpy.log. Do not apply the save to the live game state during verification.
Assumption: renpy.savegame.load_save exists and accepts a path in your Ren'Py version. The API is internal and may change between releases.
2. Keep persistent data synchronized with saves
Ren'Py does not link persistent data to individual save slots. Synchronization must be enforced by the developer.
- When a save is created, store a fingerprint of the persistent dictionary inside the save metadata under a reserved key, e.g.
'persistent_checksum'. Compute it from the persistent dict keys/values, not from raw pickle bytes.
- On verification or load, recompute the fingerprint from the currently loaded persistent file and compare to the stored value. A mismatch signals that persistent was restored from a different point than the save.
- Schema drift can be checked by comparing expected persistent keys against
renpy.store.persistent after loading persistent. Missing or extra keys suggest a script change.
Checksum verification detects changes to the persistent dictionary but does not detect structural script changes that still cause load failures.
Safety notes
- Unpickling is unsafe for untrusted files. Run verification in a sandboxed or read-only context and avoid using
pickle.load directly on user-supplied files.
- Custom serialization or save transforms will break assumptions about the save structure.
To give a version-specific recommendation, one missing diagnostic detail is needed: which Ren'Py engine version and whether the project uses custom save transforms or renpy.config.save_dump modifications. That changes which internal loader is safe to use.