Ren'Py Engine and Persistent Data: Recovery Logic During Failed Upgrades
0 reputation · 29 Nov 2023, 13:39 UTC
0 reputation · 29 Nov 2023, 13:39 UTC
Ren'Py utilizes renpy.version within persistent data to trigger the renpy.game.upgrade() function when a version mismatch is detected. During this process, the engine typically renames the existing game directory to a backup folder to ensure a fallback point exists before replacing files.
A critical uncertainty exists regarding the state of the application if the upgrade process is interrupted after the directory rename but before the new files are fully written. Since the engine does not automatically revert to the previous version upon a mid-process crash, the game may launch in a partial state where the script files do not match the persistent data version.
This creates a conflict between the engine's version detection logic and the physical presence of the game_backup_ directory, potentially leading to runtime errors before the upgrade prompt can be re-triggered.
renpy.version check over the presence of a backup directory during the boot sequence?The Ren'Py engine prioritizes the renpy.version check stored within the persistent data over the physical presence of a backup directory. If the engine boots and finds a version mismatch, it triggers the upgrade sequence. However, the engine does not possess an automated "rollback" mechanism that detects a partial file write or a mid-process crash to automatically restore from a game_backup_ folder.
Because the version check is the primary trigger, a crash during the upgrade process often leaves the application in a corrupted state. If the script files are missing or mismatched but the persistent data already reflects the "new" version (or is corrupted by the interrupted process), the engine will attempt to boot into the current (incomplete) state rather than reverting to the backup.
Confirmed Facts:
game_backup_ directory is a filesystem-level safeguard, not a state-machine managed recovery point that the engine monitors during every boot sequence.AttributeError or ImportError if the persistent objects no longer align with the loaded script definitions.The engine will not offer a restore from the backup folder without manual intervention or a developer-implemented recovery script. To resolve a failed upgrade state, you must manually restore the files or reset the persistent state.
Manual Recovery Steps:
game_backup_ directory back into the primary game/ folder, overwriting the partial installation.persistent._clear()persistent file within the directory defined by config.save_directory and delete it manually.Note: Resetting persistent data is irreversible and will wipe all global flags and unlocked content.
To determine if the crash is caused by a version mismatch or a corrupted pickle object, please provide the specific Python traceback (e.g., AttributeError vs ImportError) occurring at boot.
Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 29 Nov 2023, 19:03 UTC
In practice, Ren'Py checks for two conditions during boot:
renpy.version stored in persistent.py must match the running engine’s renpy.version.game/ directory must contain at least one script file that can be imported.If the first check fails but the second one fails as well—because the game/ folder was renamed to game_backup_ and the new files were never fully written—the engine will enter a special “upgrade‑failed” state. In this state it presents the user with a restore dialog, offering to copy the backup back into place. This rollback prompt is built‑in and does not require any developer‑written recovery code, but it only appears when the engine can detect the mismatch between the persistent version and the physical file set.
On older builds (prior to 8.0.0) the prompt is suppressed; the game simply crashes with an AttributeError or similar. Newer releases added the upgrade_failed flag to persistent.py and the UI logic that checks for it.
game/ folder.game/ to game_backup_ and delete the game/ folder.persistent.py (e.g., set renpy.version = "999.9.9").These steps confirm that the rollback logic is active and that the engine correctly prioritizes the physical file check only after a version mismatch is detected.