Lifecycle of a Running Ren'Py Game
When running a Ren'Py game, be it from the executable or from the launcher, it follows a series of steps up until the point where it is closed. This page exposes the various phases of this lifecycle, and various related statements.
Boot Time
There are a lot of things happening before the game window appears. This is the boot time. The only thing that's possibly visible at that point is the presplash.
Script Parsing Phase
To read the game's code, Ren'Py reads each of the game's .rpy
(and _ren.py
) files one by
one. That's the "parsing" phase, or "early" phase. The order that files are read in is:
Files inside
renpy/common
are loaded using using the full path, in unicode order. This is only for use by Ren'Py.Only if
game/libs/libs.txt
exists, files ingame/libs
have the first directory removed, if any and then are loaded in unicode order. In this order,game/libs/plants/aloe.rpy
will load beforegame/libs/animals/zebra.rpy
.
Files in
game
are loaded using the full path, in unicode order. (In this order,game/animals/zebra.rpy
will load beforegame/plants/aloe.rpy
.)Only if
game/mods/mods.txt
exists,game/mods
have the first directory removed, if any and then are loaded in unicode order. In this order,game/mods/plants/aloe.rpy
will load beforegame/mods/animals/zebra.rpy
.
The first creator-written code being executed is what's written in python early
blocks. These
are executed after the file they're in has been read and parsed, but before the next file gets
read. This is why statements which modify how parsing works, like Creator-Defined Statements,
Creator-Defined Screen Language Statements or new custom Warpers, must be written in python early
blocks.
The init python early
syntax is sometimes encountered, but it's redundant and doesn't change
anything in how the code gets executed compared to python early
.
Init Phase
After parsing/early phase, the "init" phase starts. Several statements are executed at that time, including the Init Python Statement, the Define Statement, the Transform Statement, the Image Statement, the Screen Statement, and the style statement.
The init phase is divided in successive epochs, or init priorities. Contrary to what the term may imply, epochs of lower priority are executed before epochs of higher priority. It is suggested that games use init priorities of -99 to 99. Libraries and mods can use from -999 to -100 and 100 to 999. Init priorities outside of the range -999 to 999 are reserved for Ren'Py's internal use.
By default, these statements are executed at init offset 0. However, they can be offset using the Init Offset Statement or by other means. The Image Statement is an exception to both of these rules, as it executes at an init priority of 500 by default, and the init offset statement adds or substracts from this 500, rather than replacing it.
Automatic image definition from the Images Directory occurs at init priority 0.
Define statements <define-statement> are executed at init time, and the variables set in define statements should not be changed, as Ren'Py considers those variables to be constants for the purpose of performance optimization.
Note that while the default statements are not executed at init time, the priority of the statements influences the order in which they will be executed, relative to one another.
Init Offset Statement
The init offset
statement sets a priority offset for all statements
that run at init time. It should be placed at the top of the file, and it applies to all following
statements in the current block and child blocks, up to the next
init priority statement. The statement:
init offset = 42
sets the priority offset to 42. In:
init offset = 2
define foo = 2
init offset = 1
define foo = 1
init offset = 0
The first define statement is run at priority 2, which means it runs
after the second define statement, and hence foo
winds up with
a value of 2.
Script Execution
This is when normal Ren'Py statements execute, and when the rules described in Labels & Control Flow apply.
Variables that are changed during this phase are saved when the game is saved, and restored when the game is loaded. The game window is shown during the first interaction that occurs during this phase.
Config variables should not be changed once script execution begins, as Ren'Py can cache the values of config variables.
Before Splashscreen
The items in this section at the start of Ren'Py, or after a return to the main menu. Notably, these still run even if the splashscreen is skipped.
Before the splashscreen is shown, default statements are executed. Then,
config.start_callbacks
are run.
Splashscreen
If it exists, the splashscreen label is executed until it returns.
A splashscreen is only displayed once per time Ren'Py is run, and is skipped when script execution restarts.
At the end of the splashscreen, even if it is skipped, Ren'Py executes scene black
to clear out
the splashscreen and provide a default black background.
In-Game Phase
This is the phase in which an actual playthrough of the game occurs, and this is the mode in which players generally spend most of their time. This phase continues until the game quits, or the game restarts and the player returns to the main menu.
During the in-game phase, the ShowMenu
action can be used to display a
screen in a new context.
The In-game phase continues until either the player quits or restarts the game
to return to the main menu. The game may be restarted by returning when no
call is on the stack, as explained explained in Labels & Control Flow. The game may
also be restarted by the MainMenu
action or the renpy.full_restart()
function.
When the game restarts, all non-persistent data is reset to what it was at the end of the script execution phase, and then the script execution phase begins again, skipping the splashscreen.