Ren'Py persistent data compatibility during engine upgrades
0 reputation · 18 Sept 2023, 15:15 UTC
0 reputation · 18 Sept 2023, 15:15 UTC
When upgrading a project from Ren'Py 7.x to Ren'Py 8.x, the engine handles persistent data and save files differently due to the transition to Python 3. While persistent objects are designed to survive across sessions, major engine version shifts can introduce serialization incompatibilities.
The goal is to ensure that player progress and persistent flags remain intact without requiring a full reset of the user's data store. However, it is unclear how the engine manages the transition of custom objects stored in the persistent store when the underlying Python version changes.
config.save_version for save file validation.What is the recommended mechanism for migrating custom persistent objects across major Ren'Py version boundaries? Does config.save_version provide a hook to transform legacy persistent data before the game initializes?
31775 reputation · 18 Sept 2023, 18:19 UTC
There is no built-in automated migration framework for transforming persistent data schemas during a Ren'Py upgrade. Because Ren'Py 8 moves from Python 2.7 to Python 3, custom Python objects stored in the persistent store may trigger serialization errors (such as UnpicklingError) due to breaking changes in the pickle module.
config.save_version is a validation tool, not a transformation hook. It allows the engine to detect when a save file was created with an older version of the game and trigger a warning to the user. It does not provide a mechanism to intercept, modify, or migrate the data before the game initializes.
To migrate custom persistent objects, you must implement a manual version-check and transformation routine during the early initialization phase of your game. Simple data types (integers, strings, booleans) generally migrate without issue, but complex custom classes require a manual rewrite.
The most reliable approach is to store a version integer within the persistent object itself and check it at the start of the game:
label start:
if persistent.data_version < 2:
# Perform migration logic here
# Example: Convert legacy object to a Python 3 compatible format
$ persistent.data_version = 2
$ renpy.save_persistent()
persistent.data_version variable to your project.start label (or a dedicated initialization label), check if the version flag is missing or outdated.renpy.save_persistent() to write the migrated data back to disk.This guidance assumes you are moving from a standard Ren'Py 7.x installation to 8.x. It is uncertain whether specific custom C-extensions or highly complex nested objects can be recovered if the pickle load fails entirely before the start label is reached. If the engine crashes during the initial load of the persistent file, you may need to implement a try...except block within an init python block to catch serialization errors and reset specific corrupted keys.
Diagnostic Detail Needed: Are you using custom Python classes stored in persistent, or only standard Ren'Py variables (strings, ints, lists)? If only standard variables are used, manual migration is likely unnecessary.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.