Renpy Programming Manual
Renpy Programming Manual
Renpy Programming Manual
RENPY PROGRAMMING
MANUAL
1
Renpy Programming Manual
Contenido
The Ren'Py Launcher ........................................................................................................... 10
A Simple Game ...................................................................................................................... 10
Characters.............................................................................................................................. 12
Images..................................................................................................................................... 13
Transitions ............................................................................................................................. 15
Positions ................................................................................................................................. 16
Music and Sound ................................................................................................................... 16
Ending the Game ................................................................................................................... 17
Menus, Labels, and Jumps ................................................................................................... 17
Python and If Statements ..................................................................................................... 18
Releasing Your Game ........................................................................................................... 19
Script of The Question .......................................................................................................... 20
The Structure of Ren'Py Scripts ............................................................................................... 20
Lines..................................................................................................................................... 20
Comments ........................................................................................................................... 21
Blocks .................................................................................................................................. 22
Init Blocks ................................................................................................................................ 22
Defining Images ................................................................................................................... 23
Defining Characters ............................................................................................................. 23
Basic Script Commands ........................................................................................................... 24
Speech ................................................................................................................................. 24
Show .................................................................................................................................... 25
Hide ..................................................................................................................................... 26
Scene ................................................................................................................................... 27
With ..................................................................................................................................... 27
Audio ....................................................................................................................................... 28
Play ...................................................................................................................................... 28
Stop ..................................................................................................................................... 30
Queue .................................................................................................................................. 30
Labels....................................................................................................................................... 32
Jump .................................................................................................................................... 33
Call and Return .................................................................................................................... 34
Variables and Control Structures ............................................................................................ 35
2
Renpy Programming Manual
Menu ................................................................................................................................... 35
If........................................................................................................................................... 35
Call ....................................................................................................................................... 35
While ................................................................................................................................... 35
Pass...................................................................................................................................... 35
Style Customization Tutorial ....................................................................................................... 36
Common Style Customizations ............................................................................................... 36
Customize Any Style ................................................................................................................ 36
Style Inspector ..................................................................................................................... 36
Style Hierarchy .................................................................................................................... 37
Style Indexing and Inheritance ............................................................................................ 40
Setting Style Properties ....................................................................................................... 40
Script, Line, and Block Structure ............................................................................................. 45
Syntax Constructs .................................................................................................................... 46
Statements .............................................................................................................................. 48
Call Statement ..................................................................................................................... 48
Define Statement ................................................................................................................ 49
Hide Statement ................................................................................................................... 49
If Statement......................................................................................................................... 49
Image Statement ................................................................................................................. 50
Init Statement ..................................................................................................................... 50
Jump Statement .................................................................................................................. 51
Label Statement .................................................................................................................. 51
Menu Statement ................................................................................................................. 52
Pause Statement ................................................................................................................. 54
Play Statement .................................................................................................................... 54
Pass Statement .................................................................................................................... 54
Python Statement ............................................................................................................... 55
Queue Statement ................................................................................................................ 55
Return Statement ................................................................................................................ 56
Say Statement ..................................................................................................................... 56
Scene Statement ................................................................................................................. 57
Show Statement .................................................................................................................. 58
Stop Statement ................................................................................................................... 59
3
Renpy Programming Manual
4
Renpy Programming Manual
5
Renpy Programming Manual
6
Renpy Programming Manual
7
Renpy Programming Manual
8
Renpy Programming Manual
Example................................................................................................................................ 284
Environment Variables ........................................................................................................... 286
Function Index......................................................................................................................... 288
9
Renpy Programming Manual
Getting Started.
To get started you'll want to download Ren'Py and unzip it. You'll then want
to start the launcher by running the renpy program.
Choosing a Project.
You should first see what the completed The Question game looks like. To do
this, start the Ren'Py launcher, and choose "Select Project". A menu of
projects will come up. Choose "the_question" from it. You'll be returned to
the main menu, and you can now choose "Launch" to start The Question.
You can get back to the Ren'Py demo by doing the same thing, but choosing
"demo" instead of "the_question".
Create a new project by choosing "New Project" from the launcher. The
launcher will ask you to choose a template. Choose "template". The launcher
will then ask you for a project name. Since "the_question" is already taken,
you should enter something different, like "my_question". The launcher will
then ask you to choose a color theme for the project. It doesn't matter what
you pick at this point, just choose something that appeals to you. You'll be
returned to the top menu of the launcher with your new game chosen.
A Simple Game
label start:
"I'll ask her..."
10
Renpy Programming Manual
"Silence."
"She is shocked, and then..."
This is perhaps one of the simplest Ren'Py games. It doesn't include any
pictures or anything like that, but it does show a conversation between the two
characters.
To try this out, go into the launcher, change to the "My Question" project, and
pick "Edit Script". This will open the script files in a text editor. Choose the
script.rpy file, and erase everything in it. We're starting from scratch, so you
don't need what's there. Copy the example above into script.rpy, and save it.
You're now ready to run this example. Go back to the launcher, and click Run.
Ren'Py will start up. Notice how, without any extra work, Ren'Py has given
you menus that let you load and save the game, and change various
preferences. When ready, click "Start Game", and play through this example
game.
The first line is a label statement. The label statement is used to give a name
to a place in the program. In this case, we create a label named "start". The
start label is special, as it's where Ren'Py scripts begin running when the user
clicks "Start Game" on the main menu.
The other lines are say statements. There are two forms of the say statement.
The first is a string (beginning with a double-quote, containing characters, and
ending with a double-quote) on a line by itself, which is used for narration,
and the thoughts of the main character. The second form consists of two
strings. It's used for dialogue, with the first string being a character name and
the second being what that character is saying.
Note that all the say statements are indented by four spaces. This is because
they are a block underneath the label statement. In Ren'Py, blocks must be
indented relative to the prior statement, and all of the statements in a block
must be indented by the same amount.
While this simple game isn't much to look at, it's an example of how easy it is
to get something working in Ren'Py. We'll add the pictures in a little bit, but
first, let's see how to declare characters.
11
Renpy Programming Manual
Characters
One problem with the first example is that it requires you to repeatedly type
the name of a character each time they speak. In a dialogue-heavy game, this
might be a lot of typing. Also, both character names are displayed in the same
way, in fairly boring white text. To fix this, Ren'Py lets you define characters
in advance. This lets you associate a short name with a character, and to
change the color of the character's name.
define s = Character('Sylvie', color="#c8ffc8")
define m = Character('Me', color="#c8c8ff")
label start:
"I'll ask her..."
"Silence."
"She is shocked, and then..."
The first and and second lines define characters. The first line defines a
character with the short name of "s", the long name "Sylvie", with a name that
is shown in a greenish color. (The colors are red-green-blue hex triples, as
used in web pages.)
The second line creates a character with a short name "m", a long name "Me",
with the name shown in a reddish color. Other characters can be defined by
copying one of the character lines, and changing the short name, long name,
and color.
We've also changed the say statements to use character objects instead of a
character name string. This tells Ren'Py to use the characters we defined in the
init block.
12
Renpy Programming Manual
Images
A visual novel isn't much of a visual novel without pictures. Let's add some
pictures to our game.
image bg meadow = "meadow.jpg"
image bg uni = "uni.jpg"
label start:
scene bg meadow
show sylvie smile
"Silence."
"She is shocked, and then..."
The first new thing we needed to do was to declare the images, using image
statements on lines 2, 3, 5, and 6, inside the init block. These image
statements give an image name, and the filename the image is found in.
For example, line 5 declares an image named "sylvie smile", found in the
filename "sylvie_smile.png", with the tag "sylvie".
We have a scene statement on line 12. This statement clears out the screen,
and shows the "bg meadow" image. The next line is a show statement, which
shows the "sylvie smile" image on the screen.
The first part of an image name is the image tag. If an image is being shown,
and another image with the same tag is on the screen, then the image that's on
the screen is replaced with the one being shown. This happens on line 19, the
second show statement. Before line 19 is run, the image "sylvie smile" is on
the screen. When line 19 is run, that image is replaces with "sylvie surprised",
since they share the "sylvie" tag.
13
Renpy Programming Manual
For Ren'Py to find the image files, they need to be placed in the game
directory of the current project. The game directory can be found at "<Project-
Name>/game/", or by clicking the "Game Directory" button in the launcher.
You'll probably want to copy the image files from the "the_question/game/"
directory into the "my_question/game/" directory, so you can run this
example.
Ren'Py does not make any distinction between character and background art,
as they're both treated as images. In general, character art needs to be
transparent, which means it should be a PNG file. Background art can be
JPEG or PNG files. By convention, background images start with the "bg"
tag.
Hide Statement.
Ren'Py also supports a hide statement, which hides the given image.
s "I'll get right on it!"
hide sylvie
"..."
It's actually pretty rare that you'll need to use hide. Show can be used when a
character is changing emotions, while scene is used when everyone leaves.
You only need to use hide when a character leaves and the scene stays the
same.
14
Renpy Programming Manual
Transitions
Simply having pictures pop in and out is boring, so Ren'Py implements
transitions that can make changes to the screen more interesting. Transitions
change the screen from what it looked like at the end of the last interaction
(dialogue, menu, or transition), to what it looks like after any scene, show, and
hide statements.
label start:
scene bg uni
show sylvie smile
scene bg meadow
with fade
The with statement takes the name of a transition to use. The most common
one is dissolve which dissolves from one screen to the next. Another useful
transition is fade which fades the screen to black, and then fades in the new
screen.
Both the "bg meadow" and "sylvie smiles" would be dissolved in at the same
time. To dissolve them in one at a time, you need to write two with
statements:
scene bg meadow
with dissolve
15
Renpy Programming Manual
show sylvie smile
with dissolve
This first dissolves in the meadow, and then dissolves in sylvie. If you wanted
to instantly show the meadow, and then show sylvie, you could write:
scene bg meadow
with None
show sylvie smile
with dissolve
Here, None is used to indicate a special transition that updates Ren'Py's idea
of what the prior screen was, without actually showing anything to the user.
Positions
By default, images are shown centered horizontally, and with their bottom
edge touching the bottom of the screen. This is usually okay for backgrounds
and single characters, but when showing more than one character on the
screen it probably makes sense to do it at another position. It also might make
sense to reposition a character for story purposes.
show sylvie smile at right
A user can define their own positions, but that's outside of the scope of this
quickstart.
When changing music, one can supply a fadeout clause, which is used to fade
out the old music when new music is played.
play music "illurock.ogg" fadeout 1.0
16
Renpy Programming Manual
Music can be stopped with the stop music statement, which can also
optionally take a fadeout clause.
stop music
Ren'Py support many formats for sound and music, but OGG Vorbis is
preferred. Like image files, sound and music files must be placed in the game
directory.
return
That's all you need to make a kinetic novel, a game without any choices in it.
Now, we'll look at what it takes to make a game that presents menus to the
user.
menu:
"It's a story with pictures.":
jump vn
label vn:
m "It's a story with pictures and music."
jump marry
label hentai:
m "Why it's a game with lots of sex."
jump marry
label marry:
scene black
17
Renpy Programming Manual
with dissolve
This example shows how menus are used with Ren'Py. The menu statement
introduces an in-game-menu. The menu statement takes a block of lines, each
consisting of a string followed by a colon. These are the menu choices which
are presented to the user. Each menu choice should be followed by a block of
one or more Ren'Py statements. When a choice is chosen, the statements
following it are run.
In our example, each menu choice runs a jump statement. The jump statement
transfers control to a label defined using the label statement. The code
following that label is run.
In our example above, after Sylvie asks her question, the user is presented
with a menu containing two choices. If the user picks "It's a story with
pictures.", the first jump statement is run, and control is transferred to the vn
label. This will cause the pov character to say "It's a story with pictures and
music.", after which control is transferred to the marry label.
Labels may be defined in any file that is in the game directory, and ends with
.rpy. The filename doesn't matter to Ren'Py, only the labels contained within
it. A label may only appear in a single file.
Python support can be accessed in two ways. A line beginning with a dollar-
sign is a single-line python statement, while the keyword "python:" is used to
introduce a block of python statements.
Python makes it easy to store flags in response to user input. Just initialize the
flag at the start of the game:
label start:
$ bl_game = False
You can then change the flag in code that is chosen by menus:
label hentai:
$ bl_game = True
18
Renpy Programming Manual
jump marry
if bl_game:
"Well, apart from that boy's love game she insisted on
making."
Of course, python variables need not be simple True/False values. They can
be arbitrary python values. They can be used to store the player's name, to
store a points score, or for any other purpose. Since Ren'Py includes the
ability to use the full Python programming language, many things are
possible.
Edit options.rpy. The options.rpy file, created when you create a new game,
contains a number of settings that you may want to customize. Some of them,
like the screen height and screen width, should probably be set before making
the game. Others, like the window title, can be set any time.
Add a plug for Ren'Py. This step is completely optional, but we do ask that
if you have credits in your game, you mention Ren'Py in them. We suggest
using something like "Made with the Ren'Py visual novel engine.", but that's
just a suggestion, and what you write is up to you.
We think that the games people make are the best advertising for Ren'Py, and
we hope that by including this, you'll help more people learn how to make
visual novels in Ren'Py.
19
Renpy Programming Manual
Check for a new version of Ren'Py. New versions of Ren'Py are released on
a regular basis, to fix bugs and add new features. You should check the
download page to see if a new version has come out. You may also want to
see if any bug-fixes are available on that page.
Check the Script. In the Launcher, you should go to the Tools page, and pick
"Check Script (Lint)". This will check your games for errors that may affect
some users. These errors can affect users on the Mac and Linux platforms, so
it's important to fix them all, even if you don't see them on your computer.
Build Distributions. From the Tools page, click distribute. The launcher will
check your script again, ask you a few questions, and then build the
distribution of your game.
Test. Lint is not a substitute for thorough testing. It's your responsibility to
check your game before it is released.
Release. You should post the generated files (for Windows, Mac, and Linux)
up on the web somewhere, and tell people where to download them from.
Congratulations, you've released a game!
If you want, you can tell us about it at the Lemma Soft forums.
This page provides a simple overview of the Ren'Py language intended for
non-programmers. There is also a more technical version of this page for more
advanced users.
This simple version may not contain the same amount of detail, and may not
be strictly accurate in a technical sense, but instead aims to give the reader an
understanding of the common usage of the language features described,
skipping exact detail for utility.
Ren'Py scripts consist of one or more .rpy files. These script files may be read
in any order, and all of them together make up a Ren'Py script. When the
game is started, Ren'Py will find the 'start' label and step through the lines one
by one in order, doing whatever each line tells it to, until it runs out of script.
20
Renpy Programming Manual
As Ren'Py runs through the script, it generally treats every line in the script
file as a separate instruction; however, there are some exceptions:
If you've opened a parenthesis and not closed it, then Ren'Py will keep
reading on to the next line to find the closed parenthesis. Similarly,
Ren'Py will match quotes enclosing text across lines. For example, the
following are considered all one instruction:
$ a = Character(
'Abigail',
color="#454580"
)
"I was disoriented,
feeling like my thoughts
were split up, and
scattered somehow."
If you want to split something across multiple lines, you can end one
line with a backslash (\) and continue on the next line, e.g.:
$ e = m * \
c * c
is equivalent to:
$ e = m * c * c
Comments
If you want to make notes within your script, then you can use comments. It's
generally considered a good idea to write comments describing anything you
think you'll need to remember - perhaps why a particular condition is checked,
or what a variable is used for. To write a comment, simply type a hash (#).
Ren'Py will ignore everything from that point until the end of the line, so you
can write anything you like.
# This line is a comment and will be ignored.
# This line will be ignored too.
"This line is going to be picked up by Ren'Py and used as
dialogue"
"This is dialogue" # but this bit on the end is a comment.
Note that because Ren'Py's ignoring the comments, it's not checking for
parentheses or quotes or backslashes on the end of the line - so comments can
never be extended over more than one line in your script file without putting
another hash in.
21
Renpy Programming Manual
Blocks
In this example, here are three blocks. One block contains everything, the
second block lines a and b, and the third contains lines c and d.
Note that lines a and b are said to be associated with line 1 - typically, line 1
will describe why lines a and b are in a block, e.g.:
if (x < 10):
# The lines in this block are only run if x is less than ten
"Sam" "Oh no!"
"Sam" "Ecks is less than ten!"
# But these lines - outside of the if's block - are run regardless
of the value of x.
"We wandered down the road a bit more, looking for anything else
as interesting as that ecks."
Note that lines which start a new block end with a colon (:). If a line ends with
a colon, Ren'Py will expect to find a new block beneath it; if a line doesn't end
in a colon, a new block shouldn't be started after that line.
The entire script will be divided up into label blocks and init blocks - these
control the overall flow of the game; Ren'Py will always start at the 'start'
label.
Init Blocks
Init blocks are used to define things which are going to be used again and
again throughout your script. Typically, this includes images and Characters.
It's generally a bad idea to define anything which has a changing state in an
init block; it's best to stick to things which remain the same throught the game,
like background images, character sprites and so on.
22
Renpy Programming Manual
When the game first starts, all of the init blocks in all of the game scripts are
run; if any init blocks are later encountered in the middle of the script they're
ignored and skipped entirely.
The most common things to find within an init block are definitions of Images
and Characters:
Defining Images
Note that you can give images names with spaces in - if you do this, Ren'Py
pays special attention to the first word of the name (see the show and hide
commands for more details) so it's wise to group your images by that first
part, e.g.:
init:
image eileen happy = "eileen-happy.png"
image eileen sad = "eileen-sad.png"
Defining Characters
23
Renpy Programming Manual
init:
$ l = Character("Lucy")
The dollar sign at the beginning of the line tells Ren'Py that this is a Python
line. This is necessary for defining characters because there's no Ren'Py
command to do it for us - Characters have too many options! The next part - 'l'
in the example above - is the name by which we refer to that character in the
rest of the script. The last part creates the Character itself; here we're just
supplying the name which we want to be displayed when that character is
used.
For further details on Characters and the many other options they have, see the
article on Defining Characters.
Speech
Speech displays text onto the screen, then waits for the user to click the mouse
button or hit space or enter before proceeding to the next instruction. Speech
falls into two categories - narration or dialogue.
Note that you can use either single or double quotes, but you must start and
end the text with the same kind of quote. Of course, this means that you can
include single-quotes in double-quoted text and vice-versa:
"'Twas the night before Christmas"
Dialogue is used to have particular characters speak. Because the reader can't
tell the difference between one character's voice and another's, when all their
dialogue is just text, the name of the character speaking is displayed alongside
24
Renpy Programming Manual
the dialogue. Of course, this means that you have to specify the name of the
character in the script, which is done by writing the character's name (in
quotes) first, then the dialogue for that character immediately afterward, e.g.:
"Hamlet" "Alas, poor Yorick! I knew him, Horatio, a fellow of
infinite jest, of most excellent fancy."
If you have defined a Character (in an init block), you can use that Character
instead of the name when writing dialogue, e.g.:
init:
$ e = Character("Eileen")
label start:
e "Hello!"
Show
The show command is used for adding a sprite to a scene. The sprite must
previously have been defined as an image in an init block, as the show
command uses the image name.
In its most basic form, the show command consists of the word 'show',
followed by the name of the image to show, e.g.:
init:
image eileen = "eileen.png"
label start:
show eileen
This will show the image named 'eileen' - the one from the file 'eileen.png' - in
the bottom-centre of the screen.
When you show an image, Ren'Py will look for an image which is already in
the scene which shares the same first part of the name - if such an image
exists, Ren'Py will remove it before showing the new image. This means that -
for example - you don't have to hide old sprites of the same character when
you're changing an expression.
init:
image eileen happy = "eileen-happy.png"
image eileen sad = "eileen-sad.png"
label start:
show eileen happy
show eileen sad
When the second 'show' command is run, Ren'Py looks at the first part of the
image name - in this case 'eileen' - and examines all the images already in the
scene for an image with that tag. The previous 'eileen happy' also had 'eileen'
25
Renpy Programming Manual
for the first part of the image name, so this is removed from the scene before
the second show takes place. This ensures that only one Eileen is on-screen at
the same time.
Of course, it's not particularly useful to only be able to show things in the
centre of the screen, so the show command can also be followed by an 'at'
giving a position at which to place the new image in the scene:
show eileen at left
This will show the 'eileen' image at the left of the screen. The positions that
Ren'Py understands out of the box are as follows:
left - at the left side, down against the bottom of the screen.
right - at the right side, down against the bottom of the screen.
center - in the middle, down against the bottom of the screen.
truecenter - centred both horizontally and vertically.
offscreenleft - just off the left side of the screen, down against the
bottom.
offscreenright - just off the right side of the screen, down against the
bottom.
Alternately, you can define your own positions with the Position function
Hide
The syntax is similar - simply the word 'hide' followed by the name of the
image to hide:
show eileen happy at left
# now there is one character in the scene
show lucy upset at right
# now there are two characters in the scene
hide eileen
# now there is only one character remaining
hide lucy
# and now there are none
As you can see from the above example, only the first part of the image name
is necessary - in the same way that the 'show' command will replace an image
in the scene just based on the first part of the image name, equally the hide
command only needs this much to find it and hide it. Also note that it is not
26
Renpy Programming Manual
necessary to specify the position of the character to hide. In fact, even if you
specify these things they will be ignored.
Scene
The scene command is used to start a new scene - this involves removing all
images from the current scene and changing the background image to suit the
new scene.
The scene command is followed by the image name for the new background
image:
init:
image bg funfair = "funfair.jpg"
image bg ferris = "ferriswheel.jpg"
image eileen = "eileen.png"
label start:
scene bg funfair
show eileen at left
# Now the background is 'funfair.jpg' and Eileen is shown at the
left.
...
scene bg ferris
# Now Eileen has been removed and the background replaced by
'ferriswheel.jpg'.
With
Transitions that Ren'Py understands out of the box can be found in the list of
predefined transitions.
Ren'Py will wait for a transition to finish before continuing, so if you instruct
it to perform several in a row, it could take several seconds to complete:
scene bg funfair with fade
# Ren'Py waits for the funfair scene to fade in before...
show eileen at left with dissolve
# Ren'Py waits for Eileen to fully dissolve in before...
hide eileen with moveoutleft
# Ren'Py waits for Eileen to completely disappear off the side of
the screen before...
27
Renpy Programming Manual
"Who was that?"
Of course, sometimes this isn't desirable - you may wish for the scene to fade
in, with a character sprite already displayed, in which case you need to stretch
the with over more than one statement. If you place the with clause on a line
on its own, then instead of being tied to one specific show, hide or scene, it
will apply to every such command since the last dialogue or menu - or the last
statement which did have its own with clause.
scene bg funfair
show eileen at left
show lucy at right
with fade
In the above example, whatever the previous scene was will fade to black,
then a scene containing eileen and lucy in front of the 'bg funfair' background
will fade in all as one single transition.
scene bg funfair with fade
show eileen at left
show lucy at right
with dissolve
In this example, however, the scene command had its own 'with' clause, so the
'with dissolve' at the end only applies to the two 'show' commands. So the
previous scene will fade to black, then the new scene at the funfair will fade
in, and as soon as that has finished Eileen and Lucy will both dissolve in at the
same time.
Audio
Play
The play statement is used for playing sound effects or music tracks.
To play music, follow the play command with the word 'music', then the
filename of the music file you wish to play:
play music "entertainer.ogg"
To play a sound, follow the play command with the word 'sound', then the
filename of the sound file you wish to play:
play sound "explosion.ogg"
When you play music, Ren'Py will loop the music, playing it over and over
again; when you play a sound, Ren'Py will play it only once.
28
Renpy Programming Manual
Channels
Sound output is divided into 'channels'. You can only be playing one piece of
audio - sound or music - on a single channel at once. If you want to play two
sounds simultaneously, you will need to specify that the second one is played
on a different channel - this can be done by adding 'channel' and then the
number of the channel you wish to use to the end of the command:
play sound "explosion.ogg" channel 0
play sound "yeehah.ogg" channel 1
Fade
By default, Ren'Py will stop any audio you already have playing on a channel
if you play something new; if you want to specify a fadeout for an already-
playing music or sound effect, then add 'fadeout' followed by a time in
seconds to fade for to the end of the command.
play music "waltz.ogg" fadeout 1
Similarly, if you want to fade the new piece of music in, then use the 'fadein'
keyword. One can combine any or all of these keywords in the same
command:
play music "waltz.ogg" fadeout 1 fadein 2
The above example will fade whatever music is currently playing out over the
course of one second, and fade in "waltz.ogg" over the course of two seconds.
Playlists
The above example will play "waltz.ogg", then once it is finished play
"tango.ogg", then "rumba.ogg", then start again at the beginning with
"waltz.ogg".
29
Renpy Programming Manual
Formats
Stop
Stop is the opposite of the play command; it stops whatever audio is currently
playing. Similarly to play, you can choose from either 'stop sound' to stop a
sound effect, or 'stop music' to stop playing music.
stop sound
Similarly to play, you can specify a fadeout for the audio you're stopping by
adding the word 'fadeout' followed by a time in seconds.
stop music fadeout 1.5
The above example fades the currently-playing music out over the course of
one and a half seconds.
You can also stop the audio that's playing on a particular channel. Again, this
is done in a similar manner to the play command - simply append 'channel'
and the channel number you wish to stop after the stop command, e.g.:
stop sound channel 2
Since you are only stopping audio which has already been played, the default
channels are the same - channel 0 for sound effects and channel 7 for music.
Queue
The queue command queues up music files or sound effects to play after the
currently-playing audio has finished. Ren'Py will queue the file you specify to
play immediately after the currently-playing music has finished.
The simple usage of the command is similar to the play command - the queue
command is followed by one of 'sound' or 'music' depending on whether you
30
Renpy Programming Manual
want to queue a music track or a sound effect, then the filename of the audio
file you wish to queue:
queue music "waltz.ogg"
If you call the queue command a second time before the first piece of music
finishes, your newly-queued file will replace the existing queued item and be
played as soon as the currently-playing audio has finished.
play music "waltz.ogg"
queue music "tango.ogg"
If the user clicks before the waltz finishes playing, then "rumba.ogg" is
queued - this replaces the already-queued tango and after the waltz
has finished, the rumba will follow.
If the user waits for the waltz to finish before continuing, then the
previously-queued tango will play immediately after the waltz, and
when the rumba is queued it will be played immediately after the
tango finishes.
In either scenario, once the rumba finishes it will continue to loop just the
rumba.
If you wish to queue up more than one file at once, then you can supply a list
of file names, separated by commas, inside square brackets ([, ]) instead of a
single file name.
play music "rumba.ogg"
queue music ["waltz.ogg", "tango.ogg"]
In this example, the rumba plays. Two files are added to the queue, so when
the rumba finishes, it will play the waltz next; when the waltz finishes, it will
play the tango. When the tango finishes, the entire queue will loop, so the
waltz will play, then the tango, then the waltz again, then the tango again, and
so on.
31
Renpy Programming Manual
Similarly to the play command, you can specify a channel on which to queue
the audio, by adding 'channel' followed by the channel number to the end of
the command.
queue sound "explosion.ogg" channel 2
Note that you cannot queue music to a channel which is currently playing
sound effects, or sound effects to a channel that is currently playing music.
Each channel has its own queue, so you can queue - for example - music on
the default channel and sound effects on the default channel and both of your
queued items will be played independently.
Labels
Labels are used to divide a Ren'Py script up into sections, and also to allow a
non-linear progression through those sections.
Generally, Ren'Py will run each line of the script in the order it finds them, so
by way of example:
"This line is run first"
# and so on...
Label names have to be unique across your entire script, because Ren'Py uses
them to identify that particular place in the script - you can't have two labels
with the same name, because Ren'Py wouldn't be able to tell those two label
blocks apart. Label names cannot have spaces in, so it's common to use
underscores to separate words in a label name:
label not valid:
# The preceeding label won't work, because it has spaces in the
name.
32
Renpy Programming Manual
label perfectly_valid:
# The label 'perfectly_valid', on the other hand, is fine.
When Ren'Py reaches the end of a label block - for example the line "As is
this one." in the above example - it simply continues on to the following label
block, so in the example above the four lines are delivered in the order they're
written, one after another, as if the label statements weren't there at all. Using
the jump and call commands, however, we can move between labels in a non-
linear fashion.
Jump
The jump command instructs Ren'Py to skip immediately to the label which is
given, ignoring all of the script in between the present position and that label.
Jumps can be forward or backward through the file, or even in a different
script file in the same game directory.
The jump command consists of the word 'jump' followed by the name of the
label to jump to:
jump some_label
Because the label could be anywhere, the jump command allows us to write
scripts in a non-linear order, for example:
label start:
"This line of dialogue will be spoken first."
jump stage_two
label stage_three:
"This line will be spoken third."
jump end
label stage_two:
"This line will be spoken second."
jump stage_three
label end:
"And this line will be last."
Ren'Py cannot execute the line in the middle ("This line will never be run")
because it's impossible to step line-after-line from a label to that dialogue line.
The 'jump end' command will get in the way and re-direct Ren'Py to the 'end'
label before it ever gets to that line of dialogue.
33
Renpy Programming Manual
Call instructs Ren'Py to go off and run the code at another label, and then
return and carry on from this point afterwards.
The call command consists of the word 'call', followed by the name of the
label to call:
call subroutine
At the other end, the command 'return' tells Ren'Py to go back to the point of
the call:
label subroutine:
"Do some stuff."
return
This means that if there is a part of your script which you want to re-use at
multiple points, then you can use call to visit that part from anywhere else in
your script and return to those different places without having to know each of
their label names.
label start:
"The teacher starts droning on about Hamlet..."
call boring
call boring
jump end
label boring:
"I can't keep my eyes open... so dull..."
"Ah! Did I fall asleep?"
return
label end:
"Huh. The lesson seems to be over. That was quick!"
34
Renpy Programming Manual
Note that the bold lines above are those included in the 'boring' label which
call skips to, after which it returns to the point in the script it was called from.
Sample code
menu:
"yes":
"yes"
jump yes
"no":
"no"
jump no
label yes:
"I agree."
label no:
The yes and no are your options; you can add as many as you like.
The : after each option lets you tell Ren'py what happens next like going to
another page of sript or adding text
If
Call
While
Pass
35
Renpy Programming Manual
Before we start, we should note that the style system is only one way to
customize your game, and may not be able to accomplish all customizations.
Layouts define the basic look of the various main and game menu
screens, such as what buttons and other displayables are present.
There are several built-in layouts, including imagemap-based layouts,
and it's possible to write your own.
Themes handle the largest changes to the style system, defining
consistent looks along many styles.
Once you have chosen your layout and theme, you can further tweak
the look of your game using the style system.
This tutorial is divided into two parts. The first part gives canned recipes for
the most common style customizations. The second part explains how to
customize any style and style property in the system, using the style inspector
and style tree tools.
Style Inspector
To use the style inspector, place the mouse over any element in the game, and
press shift+I. If nothing happens, then set config.developer to True, and
restart your game. Otherwise, a screen similar to the following will pop up,
showing the styles and Displayables underneath the mouse.
36
Renpy Programming Manual
This screenshot was created by hovering over the "Start Game" button on the
demo game main menu, and pressing shift+I.
The lines are arrange in the order that things are drawn on the screen, so that
the first line is the farthest from the user, and the last line is closest to the user.
Indentation is used to represent nesting of displayables. Such nesting may
affect the positioning of the various displayables.
Style Hierarchy
Styles may inherit from each other. The precise nature of style inheritance
varies based on the layouts and themes that are being used. For a full
accounting of styles the system knows about, hit shift+D and choose "Style
Hierarchy". This will display a list of styles that the system knows about.
37
Renpy Programming Manual
38
Renpy Programming Manual
layout.button_menu
39
Renpy Programming Manual
Some styles used by the game may be index. For example, the style
mm_button[u"Start Game"] is the style mm_button indexed with the string
u"Start Game". Indexing is used to specifically customize a single button or
label.
According to the style hierarchy tool, the default inheritance hierarchy for the
mm_button style is:
1. mm_button
2. button
3. default
1. mm_button[u"Start Game"]
2. mm_button
3. button[u"Start Game"]
4. button
5. default[u"Start Game"]
6. default
Ren'Py will look at styles in this order until it finds the first style in which a
value for the property is defined.
The roles and states correspond to prefixes that are applied to style properties.
The role prefixes are:
40
Renpy Programming Manual
"" (no prefix) - set for both selected and unselected roles.
"selected_" - set for only the selected role.
For example:
init python:
style.mm_button.background = "#f00"
style.mm_button.hover_background = "#ff0"
style.mm_button.selected_hover_background = "#00f"
style.mm_button[u"Start Game"].background = "#0f0"
The first line sets the background of all main menu buttons to be red. The
second changes the background of hovered main menu buttons to be yellow.
The third changes selected and hovered main menu buttons to be blue - this
doesn't actually do anything, since main menu buttons are never selected.
Finally, the last one changes the index style to have a green background. Since
the indexed style is hire in the inheritance order, it will take precedence over
all other styles.
Will cause hovered main menu buttons to have a red background. This is
because the second statement, which sets all roles and states, takes precedence
over the first statement. Generally, it makes sense to set the unprefixed
properties first, and the prefixed properties second.
41
Renpy Programming Manual
label start:
scene bg whitehouse
show eileen happy
e "I once wanted to go on a tour of the West Wing, but you have to
know somebody to get in."
e "I considered sneaking in, but that probably isn't a good idea."
In this case, the statement is creating a variable, `e`, and assigning to it the
result of a call to the Character function with the argument `'Eileen'`. In
simpler terms, it creates a shortcut for use when writing lines of dialogue in
the script, so that the full name Eileen doesn't have to be typed out every time
she says something.
42
Renpy Programming Manual
label start:
A label provides a spot for other Ren'Py script statements to call or jump to.
By default, the Ren'Py main menu jumps to the label `start` when you start a
new game.
Following the `start` label is the part of the script where you write the actual
interactive game, so to speak. First, a `scene` statement:
scene bg whitehouse
This scene statement simply adds the previously defined Displayable `bg
whitehouse` to the screen.
This show statement adds the previously defined `eileen happy` to the screen,
on top of the image shown by the preceding scene statement.
e "I'm standing in front of the White House."
This line is an example of a `say` statement, although you will notice that it
doesn't start with an actual 'say' keyword. Since `say` statements make up the
bulk of a game script, they use the most basic syntax possible.
Here, the statement starts with the previously defined Python variable `e`,
which is used to indicate to the Ren'Py interpreter that the line of dialogue
should be shown on screen with the name defined in the call to its Character
function - 'Eileen', of course.
This line demonstrates one of the subtle advantages to using a show statement
in combination with a multi-word Displayable label. Recall that in the init
block, there were `eileen happy` and `eileen upset` definitions. When the
show statement executes, it first checks whether there are already any images
on the screen where the first word of the name matches the first word of the
new image to show. If it finds any, the previous image is hidden and replaced
with the new one.
Put simply, the `eileen happy` image already on the screen is hidden and
replaced with `eileen upset`, since they both start with `eileen`.
43
Renpy Programming Manual
This line happens to be split onto two physical script lines, but will be joined
when shown on screen. Note that script line breaks will not be carried into the
displayed line - if you want to force a linebreak on screen, you will need to
use an explicit newline (`\n`).
The simplest say statement is just one quoted string. It will be shown on
screen without a character name label, and is thus generally used as narration
of POV character thoughts.
After you click on the final line of dialogue in-game, you will be returned to
the main menu.
44
Renpy Programming Manual
Each of these files is divided into a series of logical lines. The first logical line
of a file begins at the start of a file, and another logical line begins after each
logical line ends, until the end of the file is reached. By default, a logical line
is terminated by the first newline encountered. However, a line will not
terminate if any of the following are true:
Ren'Py script files also can include comments. A comment begins with a hash
mark that is not contained within a string, and continues to, but does not
include, the next newline character. Some examples are:
# This line contains only a comment.
scene bg whitehouse # This line contains a statement as well.
If, after eliminating comments, a logical line is empty, that logical line is
ignored.
Logical lines are then combined into blocks. Two logical lines are in the same
block if the lines have the same indentation preceding them, and no logical
line with a lesser amount of indentation occurs between the two lines.
Indentation may only consist of spaces, not tabs. In the following example:
line 1
line a
line b
line 2
line c
line d
In this example, here are three blocks. One block contains lines 1 and 2,
another lines a and b, and the third contains lines c and d. This example can
also serve to illustrate the concept of a block associated with a line. A block is
associated with a line if the block starts on the next logical line following the
line. For example, the block containing lines a and b is associated with line #
45
Renpy Programming Manual
There are three kinds of blocks in an Ren'Py program. The most common is a
block containing Ren'Py statements. Blocks may also contain menuitems or
python code. The top-level block (the one that contains the first line of a file)
is always a block of Ren'Py statements.
Syntax Constructs
Before we can describe Ren'Py statements, we must first describe a number of
syntactic constructs those statements are built out of. In this subsection, we
describe such constructs.
Keywords are words that must literally appear in the source code. They're
used ito introduce statements, or to delimit parts of statements. You'll see
keywords throughout the descriptions of statements. In grammar rules,
keywords are in quotes. The keywords used by Ren'Py are:
at
behind
call
elif
else
expression
hide
if
image
init
jump
label
menu
onlayer
pass
python
return
scene
set
show
transform
while
with
zorder
A string begins with a quote character (one of ", ', or `), contains some
sequence of characters, and ends with the same quote character. Inside a
Ren'Py string, whitespace is collapsed into a single space, unless preceded by
a backslash (as \ ). Backslash is used to escape quotes, special characters such
46
Renpy Programming Manual
as % (written as \%) and { (written as \{). It's also used to include newlines,
using the \n sequence.
Name Munging
Before parsing a file, Ren'Py looks for names of the form __word, where word
does not contain __. That is, starting with two or three underscores, and not
containing another two consecutive underscores. It munges these names in a
filename-specific manner, generally ensuring that they will not conflict with
the same name in other files. For example, in the file script.rpy, __v is munged
into _m1_script__v (the name is prefixed with the munged filename).
Names beginning with an odd number of underscores are reserved for Ren'Py,
while those beginning with an even number of underscores can safely be used
in scripts.
Grammar Rules
We will be giving grammar rules for some of the statements. In these rules, a
word in quotes means that that word is literally expected in the script.
Parenthesis are used to group things together, but they don't correspond to
anything in the script. Star, question mark, and plus are used to indicate that
the token or group they are to the right of can occur zero or more, zero or one,
or one or more times, respectively.
If we give a name for the rule, it will be separated from the body of the rule
with a crude ascii-art arrow (->).
47
Renpy Programming Manual
Statements
Call Statement
The call statement is used to transfer control to the statement with the given
name. It also pushes the name of the statement following this one onto the call
stack, allowing the return statement to return control to the statement
following this one.
call_statement -> "call" name ( "from" name )?
call_statement -> "call" "expression" simple_expression ( "from" name
)?
If the optional from clause is present, it has the effect of including a label
statement with the given name as the statement immediately following the call
statement. An explicit label is required here to ensure that saved games with
return stacks can return to the proper place when loaded on a changed script.
From clauses should be included for all calls in released games.
# ...
label subroutine:
return
48
Renpy Programming Manual
The call statement may take arguments, which are processed as described in
PEP 3102. If the return statement returns a value, that value is stored in the
_return variable, which is dynamically scoped to each context.
When using a call expression with an arguments list, the pass keyword must
be inserted between the expression and the arguments list. Otherwise, the
arguments list will be parsed as part of the expression, not as part of the call.
Define Statement
The define statement causes its expression to be evaluated, and assigned to the
supplied name. If not inside an init block, the define statement will
automatically be run with init priority 0.
define_statement -> "define" name "=" python_expression
define e = Character("Eileen")
Hide Statement
A hide statement operates on the layer supplied in the onlayer clause of the
image_spec, defaulting to "master" if no such clause has been supplied. It
finds an image beginning with the image tag of the image name, and removes
it from that layer.
Please note that the hide statement is rarely used in practice. Show can be
used by itself when a character is changing emotion, while scene is used to
remove all images at the end of a scene. Hide is only necessary when a
character leaves before the end of a scene.
If Statement
The if statement is the only statement which consists of more than one logical
line in the same block. The initial if statement may be followed by zero or
more elif clauses, concluded with an optional else clause. The expression is
evaluated for each clause in turn, and if it evaluates to a true value, then the
block associated with that clause is executed. If no expression evaluates to
true, then the block associated with the else clause is executed. (If an else
49
Renpy Programming Manual
else:
Image Statement
For a complete list of functions that define displayables, see the displayables
page.
image eileen happy = "eileen/happy.png"
image eileen upset = "eileen/upset.png"
Init Statement
The init statement is used to execute blocks of Ren'Py statements before the
script executes. Init blocks are used to define images and characters, to set up
unchanging game data structures, and to customize Ren'Py. Code inside init
blocks should not interact with the user or change any of the layers, and so
should not contain say, menu, scene, show, or hide statements, as well as calls
to any function that can do these things.
init_statement -> "init" (number)? ":"
50
Renpy Programming Manual
The priority number is used to determine when the code inside the init block
executes. Init blocks are executed in priority order from low to high. Within a
file, init blocks with the same priority are run in order from the top of the file
to the bottom. The order of evaluation of priority blocks with the same priority
between files is undefined.
The init blocks are all run once, during a special init phase. When control
reaches the end of an init block during normal execution, execution of that
block ends. If an init statement is encountered during normal execution, the
init block is not run. Instead, control passes to the next statement.
Jump Statement
The jump statement is used to transfer control to the statement with the given
name.
jump_statement -> "jump" name
jump_statement -> "jump" "expression" simple_expression
Unlike call, jump does not push the target onto any stack. As a result, there's
no way to return to where you've jumped from.
label loop_start:
jump loop_start
Label Statement
A label statement may have a block associated with it. In that case, control
enters the block whenever the label statement is reached, and proceeds with
51
Renpy Programming Manual
the statement after the label statement whenever the end of the block is
reached.
The label statement may take an optional list of parameters. These parameters
are processed as described in PEP 3102, with two exceptions:
This declares a variable as dynamically scoped to the current Ren'Py call. The
first time renpy.dynamic is called in the current call, the values of the
variables named in the supplied strings are stored. When we return from the
current call, the variables are given the values they had at the time when
renpy.dynamic was called. If the variables are undefined when renpy.dynamic
is called, they are undefined after the current call returns. If renpy.dynamic is
called twice for the same variable in a given call, it has no effect the second
time.
Menu Statement
Menus are used to present the user with a list of choices that can be made. In a
visual novel, menus are the primary means by which the user can influence
the story.
menu_statement -> "menu" ( name )? ":"
A menu statement must have a block associated with it. This is a menuitem
block that must contain one or more menuitems in it. There are several kinds
of menuitems that can be contained in a menuitem block.
caption_menuitem -> string
The first kind of menuitem is a string. This string is placed into a menu as a
caption that cannot be selected. In general, captions are used to indicate what
the menu is for, especially when it is not clear from the choices.
52
Renpy Programming Manual
choice_menuitem -> string ( "if" python_expression )? ":"
The second kind of menuitem gives a choice the user can make. Each choice
must have a block of Ren'Py statements associated with it. If the choice is
selected by the user, then block of statements associated with the choice is
executed. A choice may also have an optional if clause that includes a Python
expression. This clause gives a condition that must be satisfied for the choice
to be presented to the user. A terminating colon is used to indicate that this
menuitem is a choice.
set_menuitem -> "set" variable_name
The third kind of menuitem provides a variable in which to store the list of
choices the user has made, and prevent the user making the same choice if the
menu is visited multiple times. This variable must be defined before the menu
statement, and should be an empty list, [ ]. When the user chooses a choice
from the menu, that choice will be stored in the list. When the game reaches
another menu statement using the same variable name in a set clause (or
reaches the same menu again), any choices matching items in the list will not
be shown.
with_menuitem -> "with" simple_expression
The final kind of menuitem is a with clause. Please see Transitions for more
information on with clauses.
menu what_to_do:
"Go shopping.":
"We went shopping, and the girls bought swimsuits."
$ have_swimsuits = True
Details
When a menu is to be shown to the user, the first thing that happens is that a
list of captions and choices is built up from the menuitems associated with the
menu. Each of the choices that has an expression associated with it has that
expression evaluated, and if not true, that choice is removed from the list. If
no choices survive this process, the menu is not displayed and execution
continues with the next statement. Otherwise, the menu function is called with
53
Renpy Programming Manual
the list of choices, displays the menu to the user, and returns a chosen choice.
Execution continues with the block corresponding to the chosen choice. If
execution reaches the end of that block, it continues with the the statement
after the menu.
Pause Statement
The pause statement causes Ren'Py to pause until the mouse is clicked. If the
optional expression is given, it will be evaluated to a number, and the pause
will automatically terminate once that number of seconds has elapsed.
pause_statement -> "pause" ( simple_expression )?
Play Statement
The play statement is used to play sound and music. If a file is currently
playing, it is interrupted and replaced with the new file.
play_statement -> "play" name simple_expression
( "fadeout" simple_expression )?
( "fadein" simple_expression )?
( "loop" | "noloop" )?
( "if_changed" )?
Pass Statement
The pass statement does not perform an action. It exists because blocks of
Ren'Py statements require at least one statement in them, and it's not always
sensible to perform an action in those blocks.
pass_statement -> "pass"
menu:
"Should I go to the movies?"
54
Renpy Programming Manual
"Yes":
call go_see_movie
"No":
pass
Python Statement
The python statement allows one to execute Python code in a Ren'Py script.
This allows one to use Python code to declare things to Ren'Py, to invoke
much of Ren'Py's functionality, and to store data in variables that can be
accessed by user code. There are two forms of the python statement:
python_statement -> "$" python_code
python_statement -> "python" ( "hide" )? ":"
The first form of a python consists of a dollar sign ($) followed by Python
code extending to the end of the line. This form is used to execute a single
Python statement.
A second form consists of the keyword python, optionally the keyword hide,
and a colon. This is used to execute a block of Python code, supplied after the
statement. Normally, Python code executes in a script-global namespace, but
if the hide keyword is given, a new namespace is created for this block. (The
script-global namespace can be accessed from the block, but not assigned to.)
$ score += 1
python:
ui.text("This is text on the screen.")
ui.saybehavior()
ui.interact()
Init Python Statement. For convenience, we have created the init pythons
statement. This statement combines an init statement and a python statement
into a single statement, to reduce the indentation required for python-heavy
files.
init python_statement -> "init" ( number )? "python" ( "hide" )? ":"
Queue Statement
The queue statement is used to queue up audio files. They will be played
when the channel finishes playing the currently playing file.
queue_statement -> "queue" name simple_expression ( "loop" | "noloop"
)?
55
Renpy Programming Manual
Loop causes the queued music to loop, while noloop causes it to play only
once.
queue sound "woof.ogg"
queue music [ "a.ogg", "b.ogg" ]
Return Statement
The return statement pops the top location off of the call stack, and transfers
control to it. If the call stack is empty, the return statement performs a full
restart of Ren'Py.
return_statement -> "return"
return_statement -> "return" expression
Say Statement
The say statement is used to present text to the user, in the form of dialogue or
thoughts. Since the bulk of the of the content of a script will be dialogue or
thoughts, it's important that the say statement be as convenient as possible.
Because of this, the say statement is the only statement that is not delimited
with a keyword or other form of delimiter. Instead, it consists of a string, with
an optional simple_expression before it to designate who is doing the
speaking, and an optional with clause after it used to specify a transition.
say_statement -> ( simple_expression )? string ( "with"
simple_expression )?
There are two forms of the say statement, depending on if the simple
expression is provided. The single-argument form consists of a single string
(with or without the optional with clause). This form causes the string to be
displayed to the user as without any label as to who is saying it.
Conventionally, this is used to indicate POV character thoughts or narration.
"I moved to my left, and she moved to her right."
"I then moved to my right, and at the same time she moved to her
left."
56
Renpy Programming Manual
The simple_expression can also be a string, rather than an object. Strings are
used directly as the name of the character.
"Girl" "Hi, my name is Eileen."
Details
If it can't call the value of the expression, then it copies the name_only
character object, supplying the given string as a new character name, and then
uses that to say the dialogue. (This is done by the say and predict_say
functions found in the store. Changing these functions can change this
behavior.)
The single-argument form of the statement simply calls the special function
(or object) narrator with the string to be shown. This function is responsible
for showing the string to the user. Character and DynamicCharacter objects
are suitable for use as the narrator.
The with clause is used to specify a transition; see With Statement and
Clauses for details.
Scene Statement
The scene statement clears a layer by removing all images from it. It may then
show a supplied image to the user. This makes it appropriate for changing the
background of a scene.
scene_statement -> "scene" ("onlayer" name)? (...)?
57
Renpy Programming Manual
The scene statement first clears out all images from a layer, defaulting to the
"master" layer if no other layer is specified. If additional arguments are
present, then they are handled as if a show statement statement was supplied.
Show Statement
The show statement is used to add an image to a layer. The image must have
been defined using the image statement statement.
show_statement -> "show" image_name
( "at" transform_list )?
( "as" name )?
( "behind" name_list )?
( "onlayer" name )?
( "with" simple_expression )?
When adding an image, the show statement first checks to see if an image
with the same tag (by default, first part of the image name) exists in the layer.
If so, that image is replaced, without changing the order. This means that it's
rarely necessary to hide images.
When an image is shown, Ren'Py checks to see if there was a previous image
with that tag, and if that image used a transform. If this is true, Ren'Py does
two things:
The generally has the effect of "remembering" the position of images shown
on the screen. In some cases, this memory effect may override a position
58
Renpy Programming Manual
encoded into an image. In that case, the image must be hidden and shown
again.
scene living_room
show eileen happy at left
show golden glow as halo at left behind eileen
The show statement can also be used to display text, using the
ParameterizedText displayable. The text displayable is defined by default,
and uses the centered_text style:
show text "Centered text"
There is a second form of the show statement that takes an expression that
returns a displayable. This can be used to show a displayable directly. The tag
of the displayable is undefined, unless given with the as clause.
show_statement -> "show" "expression" simple_expression
( "as" name )?
( "onlayer" name )?
( "at" transform_list )?
( "behind" name_list )?
( "with" simple_expression )?
show expression "myimage.png"
Stop Statement
The name is expected to be the name of an audio channel. The sound or music
is stopped using renpy.music.stop. The optional fadeout clause expects a time
in seconds, and will cause it to take that long to fadeout the music.
stop sound
stop music fadeout 1.0
59
Renpy Programming Manual
Window Statement
The "window show" statement causes the window to be shown, while the
"window hide" statement hides the window. If the optional simple_expression
is given, it's a transition that's used to show and hide the window. If not given,
it defaults to config.window_show_transition and
config.window_hide_transition. Giving None as the transition prevents it from
occuring.
The with statement and with clauses are used to show transitions to the user.
These transitions are always from the last screen shown to the user to the
current screen. At the end of a with statement, the last screen shown to the
user is set to the current screen. The last screen shown to the user can also be
updated by say or menu statements, as well as by Python code.
60
Renpy Programming Manual
is equivalent to:
with None
show eileen happy
with dissolve
will cause two transitions to occur. To ensure only a single transition occurs,
one must write:
with None
show bg whitehouse
show eileen happy
with dissolve
With clauses can also be applied to say and menu statements. In this case, the
transition occurs when the dialogue or menu is first shown to the user.
For pre-defined transition functions that can be used in any script, see Pre-
defined Transitions. For functions that return transition functions, see
Transition Constructors.
While Statement
When control reaches the end of the block associated with the while
statement, it returns to the while statement. This allows the while statement to
61
Renpy Programming Manual
check the condition again, and evaluate the block if the condition remains
true.
while not endgame:
call morning
call afternoon
call evening
62
Renpy Programming Manual
Transform Statement. The first way is using the transform statement. The
transform statement creats a position and motion function that can be supplied
to the at clause of a show or scene statement. The syntax of the transform
statement is:
transform_statement -> "transform" name "(" parameters ")" ":"
atl_block
The transform statement should be run at init time. If it is found outside an init
block, then it is automatically placed inside an init block with a priority of 0.
The transform may have a list of parameters, which must be supplied when it
is called. The syntax is the same as for labels, except that we do not allow a
variable number of arguments.
Name must be given, and must be a python identifier. The transform created
from the ATL block is bound to this name.
Image Statement with ATL block. The second way to use ATL is as part of
an image statement with ATL block. This binds an image name to the given
transform. As there's no way to supply parameters to this transform, it's only
useful if the transform defines an animation. The syntax for an image
statement with ATL block is:
image_statement -> "image" image_name ":"
atl_block
Scene and Show statements with ATL block. The final way to use ATL is
as part of a scene or show statement. This wraps the image being shown inside
an ATL transformation.
atl_scene_statement -> scene_statement ":"
atl_block
63
Renpy Programming Manual
There are two kinds of ATL statements: simple and complex. Simple
statements do not take an ATL block. A single logical line may contain one or
more ATL statements, separated by commas. A complex statement contains a
block, must be on its own line. The first line of a complex statement always
ends with a colon (":").
ATL Statements
The following are the ATL statements.
Interpolation Statement
interpolation_statement ->
( warper simple_expression | "warp" simple_expression
simple_expression )?
( property simple_expression ( "knot" simple_expression )*
| "clockwise"
| "counterclockwise"
| "circles" simple_expression
| simple_expression )*
The first part of a the interpolation statement is used to select a a function that
time-warps the interpolation. (That is, a function from linear time to non-
linear time.) This can either be done by giving the name of a warper registered
with ATL, or by giving the keyword "warp" followed by an expression giving
a function. Either case is followed by a number, giving the number of seconds
the the interpolation should take.
64
Renpy Programming Manual
If no warp function is given, the interpolation is run for 0 seconds, using the
pause function.
The warper and duration are used to compute a completion fraction. This is
done by dividing the time taken by the interpolation by the duration of the
interpolation. This is clamped to the duration, and then passed to the warper.
The result returned by the warper is the completion fraction.
65
Renpy Programming Manual
An important special case is that the pause warper, followed by a time and
nothing else, causes ATL execution to pause for that amount of time.
Some properties can have values of multiple types. For example, the xpos
property can be an int, float, or absolute. The behavior is undefined when an
interpolation has old and new property values of different types.
Time Statement
time_statement -> "time" simple_expression
When the time given in the statement is reached, the following statement
begins to execute.This transfer of control occurs even if a previous statement
is still executing, and causes any prior statement to immediately terminate.
When there are multiple time statements in a block, they must strictly increase
in order.
image backgrounds:
"bg band"
time 2.0
"bg whitehouse"
time 4.0
"bg washington"
Expression Statement
expression_statement -> simple_expression ("with" simple_expression)?
The first simple expression may evaluate to a transform (defined with the
transform statement) or a displayable. If it's a transform, that transform is
executed. With clauses are ignored when a transform is supplied.
66
Renpy Programming Manual
Pass Statement
pass_statement -> "pass"
The pass statement is a simple statement that causes nothing to happen. This
can be used when there's a desire to separate statements, like when there are
two sets of choice statements that would otherwise be back-to-back.
Repeat Statement
repeat_statement -> "repeat" (simple_expression)?
The repeat statement is a simple statement that causes the block containing it
to resume execution from the beginning. If the expression is present, then it is
evaluated to give an integer number of times the block will execute. (So a
block ending with "repeat 2" will execute at most twice.)
Block Statement
block_statement -> "block" ":"
atl_block
67
Renpy Programming Manual
alpha 0.0 xalign 0.0 yalign 0.0
linear 1.0 alpha 1.0
block:
linear 1.0 xalign 1.0
linear 1.0 xalign 0.0
repeat
Choice Statement
choice_statement -> "choice" (simple_expression)? ":"
atl_block
Choice statements are greedily grouped into a choice set when more than one
choice statement appears consecutively in a block. If the simple_expression is
supplied, it is a floating-point weight given to that block, otherwise 1.0 is
assumed.
image eileen random:
choice:
"eileen happy"
choice:
"eileen vhappy"
choice:
"eileen concerned"
pause 1.0
repeat
Parallel Statement
Parallel statements are greedily grouped into a parallel set when more than
one parallel statement appears consecutively in a block. The blocks of all
parallel statements are then executed simultaneously. The parallel statement
terminates when the last block terminates.
The blocks within a set should be independent of each other, and manipulate
different properties. When two blocks change the same property, the result is
undefined.
show logo base:
parallel:
68
Renpy Programming Manual
xalign 0.0
linear 1.3 xalign 1.0
linear 1.3 xalign 0.0
repeat
parallel:
yalign 0.0
linear 1.6 yalign 1.0
linear 1.6 yalign 0.0
repeat
Event Statement
event_prod_statement -> "event" name
The event statement is a simple statement that causes an event with the given
name to be produced.
On Statement
Execution of the on statement will never naturally end. (But it can be ended
by the time statement, or an enclosing event handler.)
show logo base:
on show:
alpha 0.0
linear .5 alpha 1.0
on hide:
linear .5 alpha 0.0
Contains Statement
The contains statement sets the displayable contained by this ATL transform.
(The child of the transform.) There are two variants of the contains statement.
69
Renpy Programming Manual
image move_an_animation:
contains an_animation
Contains Block. The contains block allows one to define an ATL block that is
used for the child of this ATL transform. One or more contains block
statements will be greedily grouped together, wrapped inside a Fixed, and set
as the child of this transform.
contains_statement -> "contains" ":"
atl_block
Each block should define a displayable to use, or else an error will occur. The
contains statement executes instantaneously, without waiting for the children
to complete. This statement is mostly syntactic sugar, as it allows arguments
to be easily passed to the children.
image test double:
contains:
"logo.png"
xalign 0.0
linear 1.0 xalign 1.0
repeat
contains:
"logo.png"
xalign 1.0
linear 1.0 xalign 0.0
repeat
Function Statement
The function statement allows ATL to use Python functions to control the
ATL properties.
70
Renpy Programming Manual
function_statement -> "function" expression
The functions have the same signature as those used with Transform:
label start:
show logo base:
function slide_function
pause 1.0
repeat
71
Renpy Programming Manual
Warpers
A warper is a function that can change the amount of time an interpolation
statement considers to have elapsed. The following warpers are defined by
default. They are defined as functions from t to t', where t and t' are floating
point numbers between 0.0 and 1.0. (If the statement has 0 duration, than t is
1.0 when it runs.)
pause
linear
Linear interpolation.
t' = t
ease
easein
easeout
@renpy.atl_warper
def linear(t):
return t
72
Renpy Programming Manual
Transform Properties
The following transform properties exist.
When the type is given as position, it may be an int, absolute, or float. If it's a
float, it's interpreted as a fraction of the size of the containing area (for pos) or
displayable (for anchor).
Note that not all properties are independent. For example, xalign and xpos
both update some of the same underlying data. In a parallel statement, only
one block should adjust horizontal position, and one should adjust vertical
positions. (These may be the same block.) The angle and radius properties set
both horizontal and vertical positions.
pos
default: (0, 0)
xpos
type: position
default: 0
The horizontal position, relative to the left side of the containing area.
ypos
type: position
default: 0
anchor
default: (0, 0)
xanchor
73
Renpy Programming Manual
type: position
default: 0
yanchor
type: position
default: 0
align
xalign
type: float
default: 0.0
yalign
type: float
default: 0.0
rotate
default: None
74
Renpy Programming Manual
rotate_pad
type: boolean
default: True
If True, then a rotated displayable is padded such that the width and
height are equal to the hypotenuse of the original width and height.
This ensures that the transform will not change size as its contents
rotate. If False, the transform will be given the minimal size that
contains the transformed displayable. This is more suited to fixed
rotations.
zoom
type: float
default: 1.0
xzoom
type: float
default: 1.0
yzoom
type: float
default: 1.0
75
Renpy Programming Manual
alpha
type: float
default: 1.0
around
alignaround
angle
type: float
radius
type: position
76
Renpy Programming Manual
crop
default: None
corner1
default: None
If not None, gives the upper-left corner of the crop box. This takes
priority over crop.
corner2
default: None
If not None, gives the lower right corner of the crop box. This takes
priority over crop.
size
default: None
subpixel
type: boolean
default: False
77
Renpy Programming Manual
delay
type: float
default: 0.0
Circular Motion
Ren'Py will then interpolate the angle and radius properties, as appropriate, to
cause the circular motion to happen. If the transform is in align mode, setting
the angle and radius will set the align property. Otherwise, the pos property
will be set.
78
Renpy Programming Manual
External Events
The following events can triggered automatically:
start
show
replace
hide
Triggered when the transform is hidden using the hide statement. The
image will not actually hide until the ATL block finishes.
hover
idle
selected_hover
selected_idle
Python Equivalent
The Python equivalent of an ATL transform is a Transform. There is no way
to create ATL code programatically.
79
Renpy Programming Manual
Base Directory
The base directory is the directory that contains all files that are distributed
with the game. (It may also contain some files that are not distributed with the
game.) Things like README files should be placed in the base directory,
from where they will be distributed.
The base directory is created underneath the Ren'Py directory, and has the
name of your game. For example, if your Ren'Py directory is named renpy-
6.11.0, and your game is named "HelloWorld", your base directory will be
renpy-6.11.0/HelloWorld.
Game Directory
The name of the executable, without the suffix. For example, if the
executable is named moonlight.exe, it will look for a directory named
moonlight under the base directory.
The name of the executable, without the suffix, and with a prefix
ending with _ removed. For example, if the executable is
moonlight_en.exe, Ren'Py will look for a directory named en.
The directories "game", "data", and "launcher", in that order.
The launcher will only properly recognize the "game" and "data" directories,
however.
The game directory contains all the files used by the game. It, including all
subdirectories, is scanned for .rpy and .rpyc files, and those are combined to
form the game script. It is scanned for .rpa archive files, and those are
automatically used by the game. Finally, when the game gives a path to a file
to load, it is loaded relative to the game directory. (But note that
config.searchpath can change this.)
80
Renpy Programming Manual
Ignored Files
The following files and directories are not distributed with Ren'Py games,
even if they are in the base directory.
archived - This directory contains files that have been added to the
archives by the archiver included with the Ren'Py launcher. The
launcher scans this directory, along with the game directory, when
building archives.
icon.ico - This file is used to set the icon for a windows executable.
icon.icns - This file is used to set the icon for a mac application.
81
Renpy Programming Manual
Defining Characters
When showing dialogue to the user using the two-argument form of the say
statement, the first argument to the say statement should almost always be a
variable bound to a Character object. These objects implement (or call
functions that implement) much of the logic required to show dialogue to the
user.
This creates a new character object and binds it to the `e` variable. When the
say statement:
e "Hello, World!"
runs, the line of text "Hello, World!" will be preceded by the label "Eileen",
indicating who is talking. It's common to customize the color of this label.
This can be done by supplying the `color` keyword argument to Character, as
in:
init:
$ e = Character("Eileen", color=(200, 255, 200, 255))
The color argument is actually setting the color property on the label. The
color property takes an RGBA tuple consisting of four numbers, enclosed in
parenthesis and separated by commas, with each number ranging from 0 to
255.
Creates a new character object. This object is suitable for use as the first
argument of a two-argument say statement. When it is used as such, it shows a
window containing the character name and the second argument to the say
statement. This behavior is customized by passing parameters to this function.
82
Renpy Programming Manual
name is the name of the character that is speaking. It can be either a string
containing the character name, or None to indicate that the label should not be
shown. A name value consisting of a single space (" ") indicates that the label
should be a blank line, which allows a narrator character to line up narration
with character dialogue. name is the only requirement to Character.
kind, if supplied, gives the name of another Character object. The default
values for all the settings of the newly-created character object are taken from
that character object. If not given, defaults to adv. Another useful value is nvl,
which by default causes nvl-mode interactions.
Prefixes and Suffixes. The following keyword arguments can be used to add
a prefix or suffix to everything said through a character object. These can be
used when lines of dialogue need to be enclosed in quotes, as the preferred
alternative to adding those quotes to every line of dialogue in the script.
who_suffix - Text that is appended to the name of the character when forming
the label of the dialogue.
83
Renpy Programming Manual
ctc - If present, this argument takes a displayable that is used as the click-to-
continue indicator. If not present or None, then no click-to-continue indicator
is displayed.
Functions. The following are keyword arguments that allow one to massively
customize the behavior of a character object:
predict_function - The function that is called to predict the images from this
dialogue. It should have the signature of renpy.predict_display_say.
84
Renpy Programming Manual
Note that when interact=False, slow_done can occur after end. If callback is
not given or None, it defaults to config.character_callback, if not None. The
character callbacks in config.all_character_callbacks are called for all
characters, before any more specific callbacks.
Default Show Function The following are keyword arguments that are
processed by the default show_function.
show_two_window - Places the name of the character saying the dialogue into
its own window.
Styles. The following keyword arguments control the styles used by parts of
the dialogue:
85
Renpy Programming Manual
Equivalent to calling Character with the same arguments, and with the
dynamic argument set to true.
The copy method on Characters takes the same arguments as the funcref
Character constructor, with the exception that the name argument is optional.
This method returns a new Character object, one that is created by combining
the arguments of the original constructor and this method, with the arguments
provided by this method taking precedence.
86
Renpy Programming Manual
This use can programatically replace say statements. For example, the say
statement:
e "Hello, World!"
is equivalent to:
$ e("Hello, World!", interact=True)
Pre-Defined Characters
We give you a few pre-defined characters to work with.
extend will cause the last character to speak to say a line of dialogue
consisting of the last line of dialogue spoken, "{fast}", and the dialogue
given to extend. This can be used to have the screen change over the
course of dialogue. Extend is aware of NVL-mode, and treats it
correctly.
# Show the first line of dialogue, wait for a click, change
expression, and show
# the rest.
87
Renpy Programming Manual
88
Renpy Programming Manual
Text
This section covers aspects of text in Ren'Py. It first covers interpolation,
supported by the say and menu statements, which allows values to be
substituted into text. It next discusses text tags, which allow the style of
portions of strings of text to be customized. Finally, it covers how Ren'Py
handles fonts.
Interpolation
Interpolation is supported by the `say` and `menu` statements. These
statements support python string interpolation over the contents of the store.
The strings used by the statements support conversion specifiers of the form
`%(variable)s`, where `variable` is the name of a variable and `s` is a
conversion. Useful conversions include 's', which interpolates a string; 'd',
which interpolates an integer; and 'f', which interpolates a floating point
number. Conversions may also include characters that modify how the string
is converted. More information about conversions can be found at the Python
string formatting operations reference.
girl "My name is %(name)s, and I am %(age)d years old. I'm with you
%(withyou)d%%"
When interpolation is not supported, the effect can often be faked by putting
placeholder %s, %d, and %f with % (variable list) outside the string (see
example below).
ui.text("%s's Vital Statistics: %d" % (name, blood))
Text Tags
Text displayed by Ren'Py supports text tags. While styles can only be applied
to an entire Text displayable, allow only a portion of the text in the
displayable to be customized. As text tags are part of the Text displayable,
89
Renpy Programming Manual
they may be used in any string that is displayed on the screen. However, some
of the text tags will only have effect if used in the appopriate context.
Text tags should be used fairly sparingly. If you find you're using text tags on
every line of the game, it's quite possible text tags are not the right solution for
the problem at hand. Investigate text styles as a possible alternative to text
tags.
Text tags start with a left brace ({), and continue to the matching right brace
(}). Immediately following the left brace is the tag name. The name may be
followed by an argument, which is separated from the tag name by an equals
sign (=). Some tags require an argument, while others require that the
argument be omitted. Text tags are sensitive to case and white space.
Some tags require a corresponding closing tag. A closing tag is any text tag
where the name begins with a slash (/). Closing tags should be properly
nested: "{b}{i}this is okay{/i}{/b}", while "{b}{i}this is wrong{/b}{/i}".
While improper nesting of text tags will generally not cause an error, this
problem may cause undesirable rendering results. The text between a tag and
the corresponding closing tag is called the enclosed text. All tags must be
closed by the end of the text string.
To include a single left brace in text, two left braces ({{) musty be included
instead.
90
Renpy Programming Manual
inside that context, when he loads the game he will be returned to the
screen containing the hyperlink.
init:
$ definition = Character(None, window_yfill=True,
window_xmargin=20,
window_ymargin=20,
window_background=Solid((0, 0, 0, 192)))
label start:
"A game that instructs on how to make a game? Isn't that a sort of
{a=define_quine}Quine{/a}?"
# ...
label define_quine:
return
91
Renpy Programming Manual
The last {fast} tag is the one that is used. {nw}, {p}, and {w} tags only take
effect if they are after the last {fast} tag in the text.
The following is an example of a say statement that uses many text tags. Use
of this many text tags is not recommended in a high-quality game.
"Using text tags, we can make text {size=+12}bigger{/size} or
{size=-8}smaller{/size}. We can make it {b}bold{/b}, {i}italic{/i},
or {u}underlined{/u}. We can even change its
{color=#f88}color{/color}."
Fonts
The Text displayable attempts to find an an appropriate font using information
about the font name, boldness, italics, underline and size. This information is
supplied to the Text displayable using style properties, but may then be
modified using text tags. Ren'Py translates this into a font using the following
algorithm.
92
Renpy Programming Manual
The truetype font loading code will automatically scale and underline the font
as required. If you have not provided bold and italic font mappings, it will also
artificially thicken and slant the font when necessary.
For best results, fonts should be truetype files that ship with the game. This
ensures that required fonts are always present on the user's system.
Image-Based Fonts
Along with the usual TrueType fonts, Ren'Py supports image-based SFonts,
MudgeFonts, and BMFonts.
Please note that you must register an image-based font for each combination
of font, size, bold, italic, and underline your game uses. They can then be used
by setting the font property of a style to the name of the font.
To use SFonts, they must first be registered with Ren'Py using the
renpy.register_sfont function. For more information about SFonts, see [1].
93
Renpy Programming Manual
Legal issues regarding the use of copyrighted outline fonts in creating image-
based fonts are discussed in Bitmap Fonts and Copyright.
94
Renpy Programming Manual
Displayables
A displayable is a python object implementing an interface that allows it to
be displayed to the screen. Displayables can be assigned to an image name
using an `image` statement, and can then be shown to the user using the
`show` and `hide` statements. They can be supplied as an argument to the
ui.add function. They are also used as the argument to certain style properties.
In this section, we will describe functions that create displayables.
Image Manipulators
An Image is a type of displayable that contains bitmap data that can be shown
to the screen. All images are displayables, but not all displayables are images.
Images differ from displayables in that they can be statically computed, and
stored in the image cache. This loading occurs sometime before the image is
to be used (but not at the time the Image is created). This generally makes
Images faster than arbitrary displayables. An image manipulator is a function
that returns an Image.
95
Renpy Programming Manual
96
Renpy Programming Manual
If an image already has an alpha channel, values in that alpha channel are
reduced as appropriate.
base and mask should be image manipulators. This function takes the red
channel from mask, and applies it to the alpha channel of base to create a new
image.
This takes a variable number of arguments. The first argument is size, which
is either the desired size of the image (in pixels), or None to indicate that the
size should be the size of the first image.
97
Renpy Programming Manual
Scales the supplied image manipulator im by the given width and height
factors. If height is not given, it defaults to the width.
This is an image manipulator that can flip the image horizontally or vertically.
This adjusts the colors of the image that is its child. It takes as arguments 4
256 character strings. If a pixel channel has a value of 192, then the value of
the 192nd character in the string is used for the mapped pixel component.
The im.Map function can be used in a simple way, like im.Recolor, to scale
down or remove color components from the source image, or it can be used in
a more complex way to totally remap the color of the source image.
Returns a 256 character linear ramp, where the first character has the value
start and the last character has the value end. Such a ramp can be used as a
map argument of im.Map.
98
Renpy Programming Manual
This adjusts the colors of the supplied image, im. It takes four arguments,
rmul, gmul, bmul and amul, corresponding to the red, green, blue and alpha
channels, with each being an integer between 0 and 255. Each channel has its
value mapped so that 0 is 0, 255 is the argument supplied for that channel, and
other values are linearly mapped in-between.
This takes as arguments two colors, white and black. The image is mapped
such that pixels in white have the white color, pixels in black have the black
color, and shades of gray are linearly interpolated inbetween. The alpha
channel is mapped linearly between 0 and the alpha found in the white color,
the black color's alpha is ignored.
zoom - The zoom factor. Numbers that are greater than 1.0 lead to the image
becoming larger.
99
Renpy Programming Manual
This tiles the image, repeating it vertically and horizontally until it is as large
as the specified size. If no size is given, then the size defaults to the size of the
screen.
This displayable accesses images declared using the image statement. name
may be a string, or a tuple of strings giving the components of the image
name.
im.MatrixColor
The im.MatrixColor image manipulator takes a 20 or 25 element matrix, and
uses it to linearly transform the colors of an image.
100
Renpy Programming Manual
and R, G, B, and A are the red, green, blue, and alpha components of the
color, respectively, then the transformed color R', G', B', A' is computed as
follows:
R' = (a * R) + (b * G) + (c * B) + (d * A) + (e * 255)
G' = (f * R) + (g * G) + (h * B) + (i * A) + (j * 255)
B' = (k * R) + (l * G) + (m * B) + (n * A) + (o * 255)
A' = (p * R) + (q * G) + (r * B) + (s * A) + (t * 255)
R', G', B', and A' are clamped to the range [0, 255].
It's often convenient to specify the matrix using an im.matrix object. These
objects support a number of mathematical operations, such as matrix and
scalar multiplication and scalar addition. Multiplying matrices together lets
you perform multiple color manipulations at once, at the cost of a single
MatrixColor operation.
Returns an identity im.matrix (one that does not change color or alpha).
level - The amount of saturation in the resulting image. 1.0 is the unaltered
image, while 0.0 is grayscale.
101
Renpy Programming Manual
desat - This is a 3-element tuple that controls how much of the red, green, and
blue channels will be placed into all three channels of a fully desaturated
image. The default is based on the constants used for the luminance channel of
an NTSC television signal. Since the human eye is mostly sensitive to green,
more of the green channel is kept then the other two channels.
Constructs an im.matrix that tints an image, while leaving the alpha channel
intact. r, g, and b, should be numbers between 0 and 1, and control what
fraction of the given channel is placed into the final image. (For example, if r
is .5, and a pixel has a red component of 100, the corresponding pixel will
have a red component of 50.)
Constructs an im.matrix that inverts the red, green, and blue channels of the
source image, while leaving the alpha channel alone.
Constructs an im.matrix that alters the opacity of an image, while leaving the
red, green, and blue channels alone. An o of 0.0 is fully transparent, while 1.0
is fully opaque.
102
Renpy Programming Manual
This image operator converts the given image to grayscale. desat is as for
im.matrix.saturation.
Backgrounds
There are two displayables that are eminently suitable for use as backgrounds:
103
Renpy Programming Manual
image - The image (which may be a filename or image object) that will be
scaled.
For better performance, have the image share a dimension length in common
with the size the frame will be rendered at. We detect this and avoid scaling if
possible.
Returns a Displayable that is solid, and filled with a single color. A Solid
expands to fill all the space allocated to it, making it suitable for use as a
background.
color - The color that the display will be filled with, given either as an RGBA
tuple, or an html-style string
Text
Text can be used to show text to the user, as a displayable.
slow - If True, the text will be typed at the screen at a rate determined by the
slow_cps property, if set, or the "Text Speed" preference. If None (the
default), then it will be typed at a speed determined by the slow_cps property.
If False, then it will appear instantly.
104
Renpy Programming Manual
slow_speed - The speed of slow text. If none, it's taken from the preferences.
slow_offset - The offset into the text to start the slow text.
Ren'Py also supports a parameterized text object, which shows text as if it was
an image on the screen. But care should be taken, as it's almost always better
to use a Character object to show text. By default there is one
ParameterizedText image, named `text` declared, but the user can declare
more than one to show multiple text blocks on the screen at once.
This can be used as an image. When used, this image is expected to have a
single parameter, a string which is rendered as the image.
Dynamic
DynamicDisplayable can be used in styles to change the displayable shown
over the course of the game.
This displayable evaluates a function, and uses the result of that function to
determine what to show.
function should be function that should accept at least two arguments. The
first argument is the time (in seconds) that the DynamicDisplayable has been
shown for. The second argument is the number of seconds that a displayable
with the same image tag has been shown for. Additional positional and
keyword arguments passed to DynamicDisplayable are also given to the
function. The function is expected to return a 2-tuple. The first element of this
tuple should be a displayable. The second should be either the time (in
seconds) that the return value is valid for, or None to indicate the return value
is valid indefinitely.
The function is evaluated at least once for each interaction. It is also evaluated
again when the specified time has elapsed.
Note that DynamicDisplayable does not accept properties. Instead, it uses the
properties of the displayable returned by function.
105
Renpy Programming Manual
This chooses a displayable to show based on which images are being shown
on the screen. It expects an even number of positional arguments. Odd
positional arguments are expected to be image names, while even positional
arguments are expected to be displayables. An image matches if it is the prefix
of a shown image. If the image name is None, it always matches. It is an error
if no match occurs.
This takes the keyword argument layer, which specifies the layer that will be
checked to see if the images appear on it, defaulting to "master". Other
keyword arguments are used to position the chosen displayable.
Shown image names are tracked by the predictive image loading mechanism,
and so ShowingSwitch will properly predictively load images.
Since the ShowingSwitch matches on the prefix of a shown image, you can
"trick" it into thinking a particular image is displayed using null versions of
images.
init:
image eileen happy hidden = Null()
image eileen concerned hidden = Null()
Then if Eileen's not visible but you want her side image to show a particular
expression when she speaks, you can use code like this:
106
Renpy Programming Manual
show eileen concerned hidden
e "Are you sure that's a good idea?"
"Oh! I didn't realise Eileen was there."
show eileen concerned
107
Renpy Programming Manual
Animations
This section has been made somewhat obsolete by the introduction of ATL in
Ren'Py 6.10.
The displayable timebase is set to zero for children of a Button, each time the
button is focused or unfocused. This means that animations that are children
of the button (including backgrounds of the button) that have
anim_timebase=False will be restarted when the button changes focus.
Odd (first, third, fifth, etc.) arguments to Animation are interpreted as image
filenames, while even arguments are the time to delay between each image. If
the number of arguments is odd, the animation will stop with the last image
(well, actually delay for a year before looping). Otherwise, the animation will
restart after the final delay time.
108
Renpy Programming Manual
This takes arguments such that the 1st, 4th, 7th, ... arguments are displayables,
the 2nd, 5th, 8th, ... arguments are times, and the 3rd, 6th, 9th, ... are
transitions.
This displays the first displayable for the given time, then transitions to the
second displayable using the given transition, and shows it for the given time
(the time of the transition is taken out of the time the frame is shown), and so
on.
The last argument may be a transition (in which case that transition is used to
transition back to the first frame), or a displayable (which is shown forever).
Not all transitions can be used with this. (Most notably, the various forms of
MoveTransition can't.)
There is one keyword argument, apart from the usual style properties:
off - The amount of time the widget spends off, at low alpha.
rise - The amount time the widget takes to ramp from low to high alpha.
set - The amount of time the widget takes to ram from high to low.
109
Renpy Programming Manual
offset - A time offset, in seconds. Use this to have a blink that does not start at
the start of the on phase.
Images are shown, perhaps with a transition, when we are transitioning into a
state containing that image.
showold - If the keyword parameter showold is True, then the old image is
shown instead of the new image when in an edge.
image - The displayable that is shown to the user while we are in (entering)
this state. For convenience, this can also be a string or tuple, which is
interpreted with Image.
image should be None when this State is used with motion, to indicate that the
image will be replaced with the child of the motion.
atlist - A list of functions to call on the image. (In general, if something can be
used in an at clause, it can be used here as well.)
If any keyword arguments are given, they are used to construct a Position
object, that modifies the position of the image.
110
Renpy Programming Manual
old - The name (a string) of the state that this transition is from.
new - The name (a string) of the state that this transition is to.
trans - The transition that will be used to show the image found in the new
state. If None, the image is show immediately.
prob - The number of times this edge is added. This can be used to make a
transition more probable then others. For example, if one transition out of a
state has prob=5, and the other has prob=1, then the one with prob=5 will
execute 5/6 of the time, while the one with prob=1 will only occur 1/6 of the
time. (Don't make this too large, as memory use is proportional to this value.)
We present two examples of this in action. The first shows how one can create
a character that ocassionally, randomly, performs a 3-frame blink about once a
minute.
init:
image blinking = anim.SMAnimation("a",
anim.State("a", "eyes_open.png"),
# And so on...
anim.Edge("b", 0.25, "c"),
anim.State("c", "eyes_closed.png"),
anim.Edge("c", 0.25, "d"),
anim.State("d", "eyes_half.png"),
# And back to a.
anim.Edge("d", 0.5, "a")
)
Remember, State can take a Position, and Edge can take a transition. This lets
you move things around the screen, dissolve images into others, and do all
sorts of complicated, unexpected, things. (But be careful... not all transitions
do what you'd expect when used with SMAnimation.)
111
Renpy Programming Manual
This creates an animation from a single image. This image must consist of a
grid of frames, with the number of columns and rows in the grid being taken
from gridsize, and the size of each frame in the grid being taken from
framesize. This takes frames and sticks them into an Animation, with the
given delay between each frame. The frames are taken by going from left-to-
right across the first row, left-to-right across the second row, and so on until
all frames are consumed, or a specified number of frames are taken.
framesize - A (width, height) tuple giving the size of each of the frames in the
animation.
gridsize - A (columns, rows) tuple giving the number of columns and rows in
the grid.
frames - The number of frames in this animation. If None, then this defaults to
colums * rows frames, that is, taking every frame in the grid.
loop - If True, loop at the end of the animation. If False, this performs the
animation once, and then stops.
Layout
These displayables are used to layout multiple displayables at once.
112
Renpy Programming Manual
This takes a variable number of arguments. The first argument is size, which
must be a tuple giving the width and height of the composited widgets, for
layout purposes.
A layout that expands to take the size allotted to it. Each displayable is
allocated the entire size of the layout, with the first displayable further from
the user than the second, and so on.
113
Renpy Programming Manual
Widget
These are generally used with the ui functions, but may sometimes be used as
displayables.
This creates a button displayable that can be clicked by the user. When this
button is clicked or otherwise selected, the function supplied as the clicked
argument is called. If it returns a value, that value is returned from ui.interact.
child - The displayable that is contained within this button. This is required.
role - The role this button undertakes. This can be the empty string, or
"selected_".
Creates a viewport displayable. A viewport restricts the size of its child, and
allows the child to be displayed at an offset. This can be used for cropping and
scrolling the images.
114
Renpy Programming Manual
A displayable that does not display anything. By setting the width and height
properties of this displayable, it can be used to take up space.
Particle Motion
Ren'Py supports particle motion. Particle motion is the motion of many
particles on the screen at once, with particles having a lifespan that is shorter
than a single interaction. Particle motion can be used to have multiple things
moving on the screen at once, such as snow, cherry blossoms, bubbles,
fireflies, and more. There are two interfaces we've provided for the particle
motion engine. The SnowBlossom function is a convenience constructor for
the most common cases of linearly falling or rising particles, while the
Particles function gives complete control over the particle engine.
SnowBlossom is a function that can be used for the common case of linearly
rising or falling particles. Some cases in which it can be used are for falling
snow, falling cherry blossoms, and rising bubbles.
image - The image that is to be used for the particles. This can actually be any
displayable, so it's okay to use an Animation as an argument to this parameter.
count - The number of particles to maintain at any given time. (Realize that
not all of the particles may be on the screen at once.)
border - How many pixels off the screen to maintain a particle for. This is
used to ensure that a particle is not displayed on the screen when it is created,
and that it is completely off the screen when it is destroyed.
xspeed - The horizontal speed of the particles, in pixels per second. This may
be a single integer, or it may be a tuple of two integers. In the latter case, the
two numbers are used as a range from which to pick the horizontal speed for
each particle. The numbers can be positive or negative, as long as the second
is larger then the first.
yspeed - The vertical speed of the particles, in pixels per second. This may be
a single integer, but it should almost certainly be a pair of integers which are
115
Renpy Programming Manual
used as a range from which to pick the vertical speed of each particle. (Using
a single number will lead to every particle being used in a wave... not what is
wanted.) The second number in the tuple should be larger then the first.
start - This is the number of seconds it will take to start all particles moving.
Setting this to a non-zero number prevents an initial wave of particles from
overwhelming the screen. Each particle will start in a random amount of time
less than this number of seconds.
fast - If true, then all particles will be started at once, and they will be started
at random places on the screen, rather then on the top or bottom.
horizontal - If true, the particles start on the left or right edge of the screen. If
false, they start along the top or bottom edge.
The result of SnowBlossom is best used to define an image, which can then be
shown to the user.
init:
image blossoms = SnowBlossom(Animation("sakura1.png", 0.15,
"sakura2.png", 0.15))
If SnowBlossom does not do what you want, it may make sense to define your
own particle motion. This is done by calling the Particles function.
The create method of the factory object is called once per frame with two
arguments. The first is either a list of existing particles, or None if this is the
first time this Particles is shown (and hence there are no particles on the
screen). The second argument is the time in seconds from some arbitrary
point, increasing each time create is called. The method is expected to return a
116
Renpy Programming Manual
list of new particles created for this frame, or an empty list if no particles are
to be created this frame.
The predict method of the factory object is called when image prediction is
requested for the Particles. It is expected to return a list of displayables and/or
image filenames that will be used.
Particles are represented by the objects returned from each factory function.
Each particle object must have an update method. This method is called once
per frame per particle, usually with the time from the same arbitrary point as
was used to create the object. (The arbitrary point may change when hidden
and shown, so particle code should be prepared to deal with this.) The update
method may return None to indicate that the particle is dead. Nothing is
shown for a dead particle, and update is never called on it. The update method
can also return an (xpos, ypos, time, displayable) tuple. The xpos and ypos
parameters are a position on the screen to show the particle at, interpreted in
the same way as the xpos and ypos style properties. The time is the time of
display. This should start with the time parameter, but it may make sense to
offset it to make multiple particle animations out of phase. Finally, the
displayable is a displayable or image filename that is shown as the particle.
The result of these functions are suitable for use as the argument to the "at"
clause of the scene and show statements. The result can also be called (using a
second call) to return a displayable.
117
Renpy Programming Manual
Motion, when given the appropriate arguments, returns an object that when
given as the `at` clause of an image causes an image to be moved on the
screen.
function is a function that takes one or two arguments. The first argument is a
fraction of the period, a number between 0 and 1. If add_sizes is true, function
should take a second argument, a 4-tuple giving the width and height of the
area in which the child will be shown, and the width and height of the child
itself.
function should return a tuple containing two or four values. The first two
values are interpreted as the xpos and the ypos of the motion. (Please note that
if these values are floating point numbers, they are interpreted as a fraction of
the screen. If they are integers, they are interpreted as the absolute position of
the anchor of the motion.) If four values are returned, the third and fourth
values are interpreted as an xanchor and yanchor.
Please note that the function may be pickled, which means that it cannot be an
inner function or a lambda, but must be a function defined in an init block of
your script. In general, it's better to use a Pan or a Move, rather than defining
your own motion.
118
Renpy Programming Manual
Pan, when given the appropriate arguments, gives an object that can be passed
to the at clause of an image to cause the image to be panned on the screen.
The parameters startpos and endpos are tuples, containing the x and y
coordinates of the upper-left hand corner of the screen relative to the image.
time is the time it will take this position to move from startpos to endpos.
repeat, bounce, and time_warp are as for Motion.
As the current implementation of Ren'Py is quite limited, there are quite a few
restrictions that we put on pan. The big one is that there always must be a
screen's worth of pixels to the right and below the start and end positions.
Failure to ensure this may lead to inconsistent rendering.
Please note that the pan will be immediately displayed, and that Ren'Py will
not wait for it to complete before moving on to the next statement. This may
lead to the pan being overlayed with text or dialogue. You may want to use a
call to renpy.pause to delay for the time it will take to complete the pan.
Finally, also note that when a pan is completed, the image locks into the
ending position.
Move is similar to Pan, insofar as it involves moving things. But where Pan
moves the screen through an image, Move moves an image on the screen.
Specifially, move changes the position style of an image with time.
In general, one wants to use Pan when an image is bigger than the screen, and
Move when it is smaller. Both Pan and Move are special cases of Motion.
119
Renpy Programming Manual
A quadratic curve contains two points, the point to move to and the single
control point.
A cubic curve contains three points, the point to move to and the two control
points.
Any time you don't manually specify is linearly interpolated between the
previous and following times that are specified. This allows you to specify
that at a specific time, the motion will be at a specific point. By default, the
start time is 0.0 and the end time is 1.0, unless you specify something
different.
These movement clauses can also be used as Transitions, in which case they
affect the position of a single layer or the entire screen, as appropriate.
120
Renpy Programming Manual
This causes a zoom to take place, using image scaling. When used as an `at`
clause, this creates a displayable. The render of this displayable is always of
the supplied size. The child displayable is rendered, and a rectangle is cropped
out of it. This rectangle is interpolated between the start and end rectangles.
The rectangle is then scaled to the supplied size. The zoom will take time
seconds, after which it will show the end rectangle, unless an after_child is
given.
The start and end rectangles must fit completely inside the size of the child,
otherwise an error will occur.
size - The size that the rectangle is scaled to, a (width, height) tuple.
time - The amount of time it will take to interpolate from the start to the end
rectangle.
time_warp - If not None, a function that takes a fractional period (between 0.0
and 0.1), and returns a fractional period. Use this to implement non-linear
zooms. This function may be pickled, so it cannot be a lambda or other non-
top-level function.
bilinear - If True, the default, this will use bilinear filtering. If false, this will
use ugly yet fast nearest neighbor filtering.
opaque - If True and bilinear is True, this will use a very efficient method that
does not support transparency. If False, this supports transparency, but is less
efficient.
121
Renpy Programming Manual
This causes a zoom to take place, using image scaling. When used as an `at`
clause, this creates a displayable. The render of this displayable is always of
the supplied size. The child displayable is rendered, and then scaled by an
appropriate factor, interpolated between the start and end factors. The
rectangle is then scaled to the supplied size. The zoom will take time seconds,
after which it will show the end, unless an after_child is given.
The algorithm used for scaling does not perform any interpolation or other
smoothing.
time - The amount of time it will take to interpolate from the start to the end
factors.
time_warp - If not None, a function that takes a fractional period (between 0.0
and 0.1), and returns a fractional period. Use this to implement non-linear
zooms. This function may be pickled, so it cannot be a lambda or other non-
top-level function.
bilinear - If True, the default, this will use bilinear filtering. If false, this will
use ugly yet fast nearest neighbor filtering.
opaque - If True and bilinear is True, this will use a very efficient method that
does not support transparency. If False, this supports transparency, but is less
efficient.
122
Renpy Programming Manual
This function returns an object, suitable for use in an at cause, that rotates
and/or zooms its child.
rot_bounce - If true, rotate from start to end to start each cycle. If False, rotate
from start to end once.
zoom_bounce - If true, zoom from start to end to start each cycle. If False,
zoom from start to end once.
opaque - This should be True if the child is fully opaque, and False otherwise.
123
Renpy Programming Manual
The produced displayable has height and with equal to the hypotenuse of the
sides of the child. This may disturb the layout somewhat. To minimize this,
position the center of the RotoZoom.
Alpha returns a function that, when called with a displayable, allows the alpha
of that displayable to be changed over time. It's a more expensive version of
im.Alpha that works with any displayable, and can change over time.
time is the time, in seconds, it takes to complete one cycle. If repeat is True,
then the cycle repeats when it finishes, if False, the motion stops after one
period. If bounce is True, the alpha goes from start to end to start in a single
period, if False, it goes from start to end only.
Function: Revolve (start, end, time, around=(0.5, 0.5), cor=(0.5, 0.5), **kwargs):
Used to revolve it's child around a point in its parent. around is the point in
the parent that we are revolving around, while cor is the center of revolution
for the child. start is the start revolution, and end is the end revolution, both in
degrees clockwise.
124
Renpy Programming Manual
The At function is used to apply the results of position and motion functions
to displayables, yielding a displayable.
Position Definitions
These positions can be used as the argument to the at clause of a scene or
show statement.
Definition: left
A Position in which the left side of the image is aligned with the left side of
the screen, with the bottom flush against the bottom of the screen.
Definition: right
A position in which the right side of the image is aligned with the right side of
the screen, with the bottom of the image flush against the bottom of the
screen.
Definition: center
A position in which the image is centered horizontally, with the bottom of the
image flush against the bottom of the screen.
Definition: offscreenleft
A position in which the image is placed just off the left side of the screen.
Please note that an image placed in this position, while not visible to the user,
still consumes resources, and so images should be hidden when not visible.
This position is intended to be used with the move transition.
Definition: offscreenright
A position in which the image is placed just off the right side of the screen.
Please note that an image placed in this position, while not visible to the user,
still consumes resources, and so images should be hidden when not visible.
This position is intended to be used with the move transition.
125
Renpy Programming Manual
Transform
A Transform allows one to use a Python function to control many aspects of
its child. While more complicated, Transform is powerful enough to
implement all of the position and motion functions. A Transform may be used
as a displayable (by supplying a child) or a position and motion function (omit
the child).
child is the child of the Transform. This can be left None, in which case the
Transform will act as a Position and Motion function.
126
Renpy Programming Manual
The update method should be called on a transform after one or more fields
have been changed outside of the callback function of that Transform.
127
Renpy Programming Manual
Transitions
By default, Ren'Py displays each scene by replacing the old scene with a new
one. This is appropriate in general (such as for emotion changes), but it may
be boring for large changes, such as a change in location or a character
entering or leaving the scene. Ren'Py supports transitions that control how
changes to the scene lists are exposed to the user.
Transitions occur between the last scene that was shown to the user, and the
current scene that has been updated using the scene, show, or hide statements.
A transition runs for a given amount of time, but may be dismissed early by
the user. Once a transition is shown, the scene is considered shown for the
purposes of future transitions.
Transitions are introduced with the `with` statement. The `with` statement
takes an expression that is suitable for use with the `with` statement (that is, a
callable that takes as input two scene lists), and runs that transition.
Alternatively, if the expression is `None`, then the `with` statement has the
effect of showing the scene to the user, and returning instantly. This is useful
in conjunction with a future `with` statement, so that only some changes to the
scene list will be transitioned in.
An example is in order. First, let us define a few objects that can be passed in
as the argument to a with statement:
init:
# Fades to black, then to the new scene.
fade = Fade(0.5, 0, 0.5)
A simple use of with would be to place it after a series of show and hide
statements of the program. As an example:
scene bg whitehouse
show eileen happy
with fade
This series of statements will cause the old scene (displayed before these
statements started) to fade to black, and be replaced with the new scene all at
once. This is a useful behavior, for example, when we are replacing a scene
with a new one, such as when the story changes locations.
scene bg whitehouse
with None
show eileen happy
128
Renpy Programming Manual
with dissolve
The `with None` statement is useful to break changes to the scene list into
parts, as in the example above. When run, the background will be instantly
shown, and then the character image will be dissolved in over the background.
The `show`, `hide`, and `scene` statements all take a with clause. One of these
statement with a with clause associated with it is actually converted into three
statements: A `with None` statement, the original statement sans the with
clause, and the with clause as a with statement. For example:
scene bg whitehouse with fade
show eileen happy at left with dissolve
show lucy happy at right with dissolve
becomes
with None
scene bg whitehouse
with fade
with None
show eileen happy at left
with dissolve
with None
show lucy happy at right
with dissolve
This has the effect of fading out the old scene and fading in the new
background, then dissolving in the characters one after the other.
show albert at far_left
show bernardette at left
show charles at center
show derek at right
show eleanor at far_right
with dissolve
Additionally, you can also show multiple images at once by ordering them
consecutively and putting the 'with' statement at the end, followed by your
transition.
We also allow with clauses to be supplied for say and menu statements. When
a with clause is supplied on one of these statements, the transition is used to
introduce the say or menu element. For example,
129
Renpy Programming Manual
e "How are you doing?" with dissolve
If not none, specifies a default transition that is applied to all say and menu
statements that are not provided a with clause. This is only considered if the
transitions preference is set to "All".
If set to true, this will show an empty line of narration during transitions,
provided you are in the outermost context, and there is nothing transient on
the screen.
This variable may be changed outside of an init block, but a "with None"
statement should be run after doing so for change to take effect.
Pre-Defined Transitions
Definition: fade
An instance of the Fade transition that takes 0.5 seconds to fade to black, and
then 0.5 seconds to fade to the new screen.
Definition: dissolve
Definition: pixellate
130
Renpy Programming Manual
Definition: move
These move entering images onto the screen from the appropriate side, taking
0.5 seconds to do so.
These move leaving images off the screen via the appropriate side, taking 0.5
seconds to do so.
These are similar to the move- family of transitions, except that they use a
cosine-based curve to slow down the start and end of the transition.
Definition: zoomin
Definition: zoomout
Definition: zoominout
This zooms in entering images and zooms out leaving images, taking 0.5
seconds to do so.
Definition: vpunch
When invoked, this transition shakes the screen vertically for a quarter
second.
Definition: hpunch
When invoked, this transition shakes the screen horizontally for a quarter
second.
131
Renpy Programming Manual
Definition: blinds
Definition: squares
Definition: wiperight
Definition: wipeleft
Definition: wipeup
Definition: wipedown
Definition: slideright
Definition: slideleft
Definition: slideup
Definition: slidedown
Definition: slideawayright
An instance of CropMove that takes 1 second to slide the screen away and to
the right.
132
Renpy Programming Manual
Definition: slideawayleft
An instance of CropMove that takes 1 second to slide the screen away and to
the left.
Definition: slideawayup
An instance of CropMove that takes 1 second to slide the screen away and to
the up.
Definition: slideawaydown
An instance of CropMove that takes 1 second to slide the screen away and to
the down.
Definition: irisout
Definition: irisin
Transition Constructors
The following are functions that return things useful as transitions. The user
should not supply the new_widget or old_widget parameters, as these are
supplied by Ren'Py when a transition begins.
The CropMove transition works by placing the old and the new image on two
layers, called the top and the bottom. (Normally the new image is on the top,
but that can be changed in some modes.) The bottom layer is always drawn in
full. The top image is first cropped to a rectangle, and then that rectangle
drawn onto the screen at a specified position. Start and end crop rectangles
and positions can be selected by the supplied mode, or specified manually.
The result is a surprisingly flexible transition.
133
Renpy Programming Manual
This transition has many modes, simplifying its use. We can group these
modes into three groups: wipes, slides, and other.
In a wipe, the image stays fixed, and more of it is revealed as the transition
progresses. For example, in "wiperight", a wipe from left to right, first the left
edge of the image is revealed at the left edge of the screen, then the center of
the image, and finally the right side of the image at the right of the screen.
Other supported wipes are "wipeleft", "wipedown", and "wipeup".
In a slide, the image moves. So in a "slideright", the right edge of the image
starts at the left edge of the screen, and moves to the right as the transition
progresses. Other slides are "slideleft", "slidedown", and "slideup".
There are also slideaways, in which the old image moves on top of the new
image. Slideaways include "slideawayright", "slideawayleft", "slideawayup",
and "slideawaydown".
We also support a rectangular iris in with "irisin" and a rectangular iris out
with "irisout". Finally, "custom" lets the user define new transitions, if these
ones are not enough.
time - The time that this transition will last for, in seconds.
startcrop - The starting rectangle that is cropped out of the top image. A 4-
element tuple containing x, y, width, and height.
startpos - The starting place that the top image is drawn to the screen at, a 2-
element tuple containing x and y.
startcrop - The starting rectangle that is cropped out of the top image. A 4-
element tuple containing x, y, width, and height.
startpos - The starting place that the top image is drawn to the screen at, a 2-
element tuple containing x and y.
topnew - If True, the top layer contains the new image. Otherwise, the top
layer contains the old image.
134
Renpy Programming Manual
This dissolves from the old scene to the new scene, by overlaying the new
scene on top of the old scene and varying its alpha from 0 to 255. Dissolve
only works correctly when both scenes are the same size.
alpha - If True, the resulting displayable will have an alpha channel, at the
cost of some speed. If False, it will be treated as opaque, but be faster.
out_time - The amount of time that will be spent fading from the old scene to
the solid color. A float, given as seconds.
hold_time - The amount of time that will be spent displaying the solid color. A
float, given as seconds.
in_time - The amount of time that will be spent fading from the solid color to
the new scene. A float, given as seconds.
color - The solid color that will be fade to. A tuple containing three
components, each between 0 or 255. This can also be `None`.
widget - This is a widget that will be faded to, if color is `None`. This allows a
fade to be to an image rather than just a solid color.
If both color and widget are `None`, then the fade is to black.
135
Renpy Programming Manual
This dissolves the old scene into the new scene, using an image to control the
dissolve process. Basically, this means that white pixels come in first and
black last.
The two children should be the same size, or the behavior of ImageDissolve is
undefined.
image - The image that will be used to control this transition. The image
should be the same size as the scene being dissolved.
reverse - This reverses the ramp and the direction of the window slide. When
True, black pixels dissolve in first, and white pixels come in last.
alpha - If True, the resulting displayable will have an alpha channel, at the
cost of some speed. If False, it will be treated as opaque, but be faster.
This transition attempts to find images that have changed position, and moves
them from the old position to the new transition, taking delay seconds to
complete the move.
If old is True, then factory moves the old displayable with the given tag.
Otherwise, it moves the new displayable with that tag. (new in 6.6.1)
layers is a list of layers that the transition will be applied to. (new in 6.9.0)
136
Renpy Programming Manual
Images are considered to be the same if they have the same tag, in the same
way that the tag is used to determine which image to replace or to hide. They
are also considered to be the same if they are the same displayable.
If you use this transition to slide an image off the side of the screen, remember
to hide it when you are done. (Or just use it with a leave_factory.)
There are several constructors that create functions for use with enter_factory
and leave_factory:
pos - An (xpos, ypos, xanchor, yanchor) tuple, giving the position to move
from. Any component can be None, to take the corresponding component of
the final position.
pos - An (xpos, ypos, xanchor, yanchor) tuple, giving the position to move to.
Any component can be None, to take the corresponding component of the
original position.
137
Renpy Programming Manual
Returns a transition that shows the new screen for delay seconds.
This is useful for implementing a pause that behaves as a transition does, one
that is skipped when transitions are.
This pixellates out the old scene, and then pixellates in the new scene, taking
the given amount of time and the given number of pixellate steps in each
direction.
before - If not None, a transition that is applied to the old and new screens,
and used as the old screen for trans.
after - If not None, a transition that is applied to the old and new screens, and
used as the new screen for trans.
138
Renpy Programming Manual
This creates a transition that consists of one or more transitions. args must be
a list of odd length, containing at least 3 elements. Odd elements of this list
are considered to be displayables, while even elements are transitions. When
used, this causes the first element (a displayable) to transition to the third
element (a displayable), using the second element as the transition. If the
fourth and fifth elements are present, a transition will occur from the third
element (a displayable) to the fifth element (a displayable) using the fourth
element (a transition).
There are two special values that will be recognized as displayables. False
will be replaced with a displayable containing the scene before the transition,
while True will be replaced with a displayable containing the scene after the
transition.
Transition Families
This function defines a family of similar transitions.
This defines a family of move transitions, similar to the move and ease
transitions. For a given prefix, this defines the transitions:
139
Renpy Programming Manual
old - Causes the transitions to move the old displayables, rather than the new
ones.
Additional keyword arguments are passed (indirectly) to the moves. The most
useful additional keyword argument is probably subpixel=True, which causes
a subpixel move to be used.
140
Renpy Programming Manual
Interaction Functions
The Ren'Py interaction functions are available so that you can customize
interactions with the user taking advantage of the same code which the normal
interactions use.
The following functions either implement new game behavior that didn't merit
its own statement, or complement the behavior of statements.
Prevents the game from rolling back to before the current statement.
This creates a checkpoint that the user can rollback to. The checkpoint is
placed at the statement after the last statement that interacted with the user.
Once this function has been called, there should be no more interaction with
the user in the current Python block.
data - If not None, this contains data that can be accessed using
renpy.roll_forward_info if and when the current statement is re-executed due
to the user rolling back and then rolling forward again.
This is called to indicate to the skipping code that we have reached a choice. If
we're skipping, and if the skip after choices preference is not True, then this
disables skipping. This should only be needed in a custom interaction
function.
The game runtime counter counts the number of seconds that have elapsed
while waiting for user input in the current context. (So it doesn't count time
141
Renpy Programming Manual
Returns the value of the type parameter supplied to ui.interact() during the
current interaction. See renpy.last_interact_type for possible interaction types.
Displays a menu containing the given items, returning the value of the item
the user selects.
items - A list of tuples that are the items to be added to this menu. The first
element of a tuple is a string that is used for this menuitem. The second
element is the value to be returned if this item is selected, or None if this item
is a non-selectable caption.
This causes a full restart of Ren'Py. This resets the state of Ren'Py to what it
was when the init blocks finished running, and then restarts the game. After
some init code runs, transition will be set to run on the next interaction, and
control will be transferred to label. The default label initializes the main menu
context, and then invokes target. target can be a screen, like
"preferences_screen" or "load_screen".
142
Renpy Programming Manual
It generally doesn't make sense to specify both label and target. (changed in
6.9.0)
Returns the number of seconds that have elapsed in gameplay since the last
call to clear_game_timer, as a float.
The game runtime counter counts the number of seconds that have elapsed
while waiting for user input in the current context. (So it doesn't count time
spent in the game menu.)
Gets a function that, when called, will reshow the previous say statement.
Does not cause an interaction to occur.
Gets the roll forward info for the current interaction. This function is intended
to be used by overlay functions. The overlay function should return the result
of this function to cause a roll-forward to happen.
Note that it only makes sense to use this inside of an interaction. See
renpy.roll_forward_info for information on how to get the roll forward info
outside of an interaction.
Gets the transition that has been scheduled to occur using renpy.transition.
layer - if not None, finds the transition occuring for that specific layer.
143
Renpy Programming Manual
ground - The name of the file containing the ground image. The ground image
is displayed for areas that are not part of any hotspots.
selected - The name of the file containing the selected image. This image is
displayed in hotspots when the mouse is over them.
hotspots - A list of tuples defining the hotspots in this image map. Each tuple
has the format (x0, y0, x1, y1, result). (x0, y0) gives the coordinates of the
upper-left corner of the hotspot, (x1, y1) gives the lower-right corner, and
result gives the value returned from this function if the mouse is clicked in the
hotspot.
This pops up a window requesting that the user enter in some text. It returns
the entered text.
prompt - A prompt that is used to ask the user for the text.
default - A default for the text that this input can return.
length - If given, a limit to the amount of text that this function will return.
allow - If not None, then if an input character is not in this string, it is ignored.
144
Renpy Programming Manual
Returns the value of the type parameter supplied to ui.interact() during the last
interaction. Default types are:
In addition to these, other values can be created by giving the say argument to
Character or ui.interact.
When called with no arguments, this pauses and waits for the user to click
before advancing the script. If given a delay parameter, then Ren'Py will wait
for that amount of time before continuing, unless a user clicks to interrupt the
delay. This is useful to, for instance, show an image that will stay on screen
for a certain amount of time and then proceed to the next script statement
without waiting for a click forever.
music - If supplied, and music is playing, this takes precedence over the delay
parameter. It gives a time, in seconds, into the currently playing music track.
Ren'Py will pause until the music has played up to that point.
Returns True if the pause was interrupted by the user hitting a key or clicking
a mouse, or False if the pause was ended by the appointed time being reached.
145
Renpy Programming Manual
This is the default function used by Character to predict images that will be
used by renpy.display_say.
who - The name of the character that is speaking, or None to not show this
name to the user.
what - What that character is saying. Please note that this may not be a string,
as it can also be a list containing both text and displayables, suitable for use as
the first argument of ui.text.
146
Renpy Programming Manual
This function is required to return the ui.text widget displaying the what text.
This should be called when a window is shown on the screen. Calling this
prevents config.empty_window from being called when _window is true.
(And hence, prevents the empty window from being shown.)
Sets the transition that will be used for the next interaction. This is useful
when the next interaction doesn't take a with clause, as is the case with
interactions in the renpy.pause, renpy.input, and renpy.imagemap functions.
layer - If the layer setting is not None, then the transition will be applied only
to the layer named. Please note that only some transitions can be applied to
specific layers.
Calling this restarts the current interaction, while keeping any ongoing
transitions.
This should be called whenever displayables are added or removed over the
course of an interaction, or when the information used to construct the overlay
changes.
147
Renpy Programming Manual
Reshows the last say statement. Does not cause an interaction to occur.
When re-executing a statement after rollback, this returns the data stored using
renpy.checkpoint the last time this statement was executed. If this statement is
not being re-executed due to a rollback, this returns None.
Context Functions
Contexts store the current scene lists and execution location. Ren'Py supports
a stack of contexts, but only the top-level context is saved to the save file.
This code creates a new context, and starts executing code from that label in
the new context. Rollback is disabled in the new context. (Actually, it will just
bring you back to the real context.)
Use this to begin a second interaction with the user while inside an interaction.
This pushes the current context, and invokes the given python function in a
new context. When that function returns or raises an exception, it removes the
new context, and restores the current context.
Please note that the context so created cannot execute renpy code. So
exceptions that change the flow of renpy code (like the one created by
148
Renpy Programming Manual
renpy.jump) cause this context to terminate, and are handled by the next
higher context.
If you want to execute renpy code from the function, you can call it with
renpy.call_in_new_context.
Use this to begin a second interaction with the user while inside an interaction.
Causes control to leave the current context, and then to be transferred in the
parent context to the given label.
Debugging Functions
Function: renpy.log (msg):
If config.log is not set, this does nothing. Otherwise, it opens the logfile (if not
already open), formats the message to 70 columns, and prints it to the logfile.
Returns a pair giving the filename and line number of the current statement.
149
Renpy Programming Manual
Transfers control to label. Note that this will terminate the python block it's in.
Like the image statment, this function should only be executed in init blocks.
img - The displayable that is associated with that name. If this is a string or
tuple, it is interpreted as an argument to Image.
This clears out the specified layer, or 'master' by default. This is used in the
execution of the `scene` statement, but only to clear out the layer. If you want
to then add something new, like the `scene` statement would normally do
when an image parameter is given, call renpy.show after this.
This is used to execute the show statement, adding the named image to the
screen.
name - The name of the image to add to the screen. This may be a tuple of
strings, or a single string. In the latter case, it is split on whitespace to make a
tuple.
150
Renpy Programming Manual
at_list - The at list, a list of functions that are applied to the image when
shown. The members of the at list need to be pickleable if sticky_positions is
True.
tag - The tag of this image. If None, the tag is taken from name.
behind - A list of tags this image will be shown behind, if they are present on
the same layer at the same zorder, and an image with the same tag is not
already present on the layer.
This finds items in the given layer (or 'master' if no layer is given) that have
the same name as the first component of the given name, and removes them
from the layer. This is used to execute the hide statement.
name - The name of the image to hide from the screen. This may be a tuple of
strings, or a single string. In the latter case, it is split on whitespace to make a
tuple. Only the first element of the tuple is used.
always - Causes this transition to always occur, even if the user has transitions
turned off.
clear - If True, the transient layer will be cleared at the end of the transition.
151
Renpy Programming Manual
When called during image prediction, this uses the images that are predicted
to be shown, rather than the images that are currently being shown.
This gets the at_list that was used to show a given image tag. name is parsed
to get out the image tag, and the at_list corresponding to that tag is retrieved.
If no image with that tag has been shown on the given layer, then None is
returned.
This sets the layer_at_list, an at_list that is applied to the given layer as a
whole. This can be used to do things like moving the layer around, or zooming
it in and out.
For example, color('#123a') returns (17, 34, 51, 170), while color('c0c0c0')
returns (192, 192, 192, 255).
Note that as of Ren'Py 5.6.0, functions requiring a color accept the hex string
form of specification directly, with no need to use this color function.
152
Renpy Programming Manual
When this is called with one or more image manipulators, it causes those
image manipulators to be "pinned" into the image cache. This means that they
will be loaded soon after the game begins, and will never be removed from the
cache.
The usual use of this function is to preload images used in the game menu. Be
careful with it, as it can increase Ren'Py's memory usage.
This may be called with one or more image manipulators. It causes those
manipulators to become unpinned and removed from the image cache.
Positional arguments from the first call are placed before positional arguments
from the second call. If a keyword argument is given in both calls, the value
from the second call takes priority.
Curry objects can be pickled provided the original function remains available
at its original name.
Returns true if the given filename can be found in the searchpath. This only
works if a physical file exists on disk. It won't find the file if it's inside of an
archive.
153
Renpy Programming Manual
Returns a read-only file-like object that accesses filename. The file is accessed
using Ren'Py's standard search method, and may reside in an archive. The
object supports a wide subset of the fields and methods found on python's
standard file object. (Basically, all of the methods that are sensible for a read-
only object.)
Returns the set of all labels defined in the program, including labels defined
for internal use in the libraries.
This gets the placement of displayable d. There's very little warranty on this
information, as it might change when the displayable is rendered, and might
not exist until the displayable is first rendered.
This returns an object with the following fields, each corresponding to a style
property:
xpos
xanchor
xoffset
ypos
yanchor
yoffset
subpixel
154
Renpy Programming Manual
Returns True if the given filename is loadable, meaning that it can be loaded
from the disk or from inside an archive. Returns False if this is not the case.
This loads the Ren'Py module named name. A Ren'Py module consists of
Ren'Py code that is loaded into the usual (store) namespace, contained in a file
named name.rpym or name.rpymc. If a .rpym file exists, and is newer than the
corresponding .rpymc file, it is loaded and a new .rpymc file is created.
All init code in the module is run before this function returns. An error is
raised if the module name cannot be found, or is ambiguous.
Returns True if the given filename has been played at least once on the current
user's system.
Returns True if the named image has been seen at least once on the user's
system. An image has been seen if it's been displayed using the show
statement, scene statement, or renpy.show function. (Note that there are cases
where the user won't actually see the image, like a show immediately followed
by a hide.)
Returns true if the named label has executed at least once on the current user's
system, and false otherwise. This can be used to unlock scene galleries, for
example.
155
Renpy Programming Manual
This object is a random number generator that implements the Python random
number generation interface. Randomness can be generated by calling the the
various methods this object exposes. See the Python documentation for the
full list, but the most useful are:
Return the next random floating point number in the range (0.0, #0).
156
Renpy Programming Manual
Audio
Ren'Py supports playing music and sound effects in the background, using the
following audio file formats:
OGG Vorbis
MP3
WAV (uncompressed PCM only)
The 'Music Volume', 'Sound Volume', and 'Voice Volume' settings of the in-
game preferences menu are used to set individual volumes for these channels.
Sounds can also be set to play when buttons, menu choices, or imagemaps
enter their hovered or activated states. See Sound Properties.
Audio Statements
The usual way to play music and sound in Ren'Py is using the three
music/sound statements:
fadein and fadeout clauses are all optional. Fadeout gives the fadeout time for
currently playing music, in seconds, while fadein gives the time it takes to
fade in the new music.
play music "mozart.ogg"
play sound "woof.mp3"
157
Renpy Programming Manual
play myChannel "punch.wav" # 'myChannel' needs to be defined with
renpy.music.register_channel().
The advantage of using these statements is that your program will be checked
for missing sound and music files when lint is run. The functions below exist
to allow access to allow music and sound to be controlled from python, and to
expose advanced (rarely-used) features.
Defining Channels
It's possible to define your own channel by calling
renpy.music.register_channel in init code.
mixer - The name of the mixer the channel uses. The three mixers Ren'Py
knows about by default are "music", "sfx", and "voice".
158
Renpy Programming Manual
Music Functions
The music functions provide a programmatic interface to music playback.
This stops the music currently playing on the named channel, dequeues any
queued music, and begins playing the specified file or files.
loop - If True, the tracks will loop once they finish playing. If False, they will
not. If None, takes the default for the channel.
synchro_start - If True, all the channels that have had play called on them
with synchro_start set to True will be started at the same time, in a sample
accurate manner. This can be used to, for instance, have a piece of music
separated into separate percussion, melody, and background chord audio files,
and play them simultaneously.
fadein - The number of seconds to fade the music in for, on the first loop only.
tight - If True, then fadeouts will span into the next-queued sound. If False, it
will not, and if None, takes the channel default.
if_changed - If True, and the music file is currently playing, then it will not be
stopped/faded out and faded back in again, but instead will be kept playing.
(This will always queue up an additional loop of the music.)
loop - If True, this music will loop. If False, it will not. If None, takes the
channel default.
clear_queue - If True, then the queue is cleared, making these files the files
that are played when the currently playing file finishes. If it is False, then
159
Renpy Programming Manual
these files are placed at the back of the queue. In either case, if no music is
playing these files begin playing immediately.
fadein - The number of seconds to fade the music in for, on the first loop only.
tight - If True, then fadeouts will span into the next-queued sound. If False, it
will not, and if None, takes the channel default.
This stops the music that is currently playing on the named channel, dequeues
all queued music, and sets the last queued file to None.
fadeout - If None, the music is faded out for the time given in
config.fade_music, otherwise it is faded for the given number of seconds.
This sets the volume of the named channel. The volume is a number between
0.0 and 1.0, and is interpreted as a fraction of the mixer volume for the
channel.
It takes delay seconds to change/fade the volume from the old to the new
value. This value is persisted into saves, and participates in rollback.
This function allows sound and music to be panned between the two stereo
channels.
pan - A number between -1 and 1 that control the placement of the audio. If
this is -1, then all audio is sent to the left channel. If it's 0, then the two
channels are equally balanced. If it's 1, then all audio is sent to the right ear.
channel - The channel the panning takes place on. This can be a sound or a
music channel. Often, this is channel 7, the default music channel.
Returns the filename of the music playing on the given channel, or None if no
music is playing on that channel. Note that None may be returned when the
user sets the music volume to zero, even if the game script requested that
music be played on that channel.
160
Renpy Programming Manual
This sets the volume of the named channel. The volume is a number between
0.0 and 1.0, and is interpreted as a fraction of the mixer volume for the
channel.
It takes delay seconds to change/fade the volume from the old to the new
value. This value is persisted into saves, and participates in rollback.
This sets a callback function that is called when the queue is empty. This
callback is called when the queue first becomes empty, and at least once per
interaction while the queue is empty.
Sound Functions
Most renpy.music functions have aliases in renpy.sound. These functions are
similar, except they default to the sound channel rather than the music
channel, and default to not looping.
161
Renpy Programming Manual
Movies
Ren'Py is capable of using ffmpeg (included) to play movies using the video
codecs:
Theora
MPEG 4 part 2 (including Xvid and DivX)
MPEG 2
MPEG 1
Vorbis
MP3
MP2
PCM
Matroska
Ogg
Avi
Various kinds of MPEG stream.
(Note that using some of these formats may require patent licenses. When in
doubt, and especially for commercial games, we recommend using Theora,
Vorbis, and Matroska or Ogg.)
Ren'Py expects that every movie will have an audio track associated with it,
even if that audio track consists of nothing but silence. This is because the
audio track is used for synchronization purposes.
Fullscreen Movies
The easiest way to display a movie fullscreen is to display it using the
renpy.movie_cutscene function. This function displays a movie for a specified
length of time. When that time has elapsed, or when the user clicks to dismiss
the movie, the movie ends and the function returns.
162
Renpy Programming Manual
delay - The number of seconds to wait before ending the cutscene. Normally
the length of the movie, in seconds. If None, the length of the movie will be
automatically determined. If -1, the cutscene will not automatically terminate,
and will continue until the user clicks.
stop_music - If True, stops the music channel while the cutscene is playing,
and starts it again when the cutscene is over.
Returns True if the movie was terminated by the user, or False if the given
delay elapsed uninterrupted.
$ renpy.movie_cutscene("On_Your_Mark.mpg")
label movie_sign:
scene black
show movie
"MAKE IT STOP!"
stop movie
hide movie
"Thats... better."
163
Renpy Programming Manual
fps - The framerate that the movie should be shown at. (This is currently
ignored, but the parameter is kept for backwards compatibility. The framerate
is auto-detected.)
size- This should always be specified. A tuple giving the width and height of
the movie.
The contents of this displayable when a movie is not playing are undefined.
(And may change when a rollback occurs.)
164
Renpy Programming Manual
UI Functions
While the say and menu statements are often enough for many games, there
are times when more complex user interfaces are desired. For example, dating
sim games can require more complex scheduling screens. These screens can
be built using the UI functions.
Most of the UI functions create widgets and add them to the screen. The UI
functions manage the complexity of nesting widgets. The screen can then be
shown to the user with ui.interact, and a value returned and used by the game
script.
To start, let's give a script snippet that uses the UI functions. The following
displays a window containing three buttons, arraigned horizontally. The string
assigned to choice varies depending on which of the three is picked.
$ ui.window()
$ ui.hbox()
$ ui.textbutton("A", clicked=ui.returns("A"))
$ ui.textbutton("B", clicked=ui.returns("B"))
$ ui.textbutton("C", clicked=ui.returns("C"))
$ ui.close()
$ choice = ui.interact(suppress_overlay=True)
There are three kinds of widgets that can be created by the UI functions.
The first kind of widget (of which ui.window is one), takes a single
child widget. When this kind of widget is open, the next widget to be
created is added to it, and it then closes automatically.
The third kind of widget cannot take any children. This kind of widget
is exemplified by ui.textbutton.
There is also a set of functions that are used to manage the interaction, and a
set of functions that can be used to perform various actions when buttons are
clicked.
165
Renpy Programming Manual
Single-Child Widgets
Function: ui.button (clicked=None, **properties):
This creates a button that can be clicked by the user. When this button is
clicked or otherwise selected, the function supplied as the clicked argument is
called. If it returns a value, that value is returned from ui.interact.
Buttons created with this function contain another widget, specifically the
next widget to be added. As a convenience, one can use ui.textbutton to create
a button with a text label. See also ui.imagebutton, which creates a button in
the form of an image.
unhovered - A function that is called with no arguments when the button loses
focus. It's also called at least once per interaction, when a button is not
focused at the start of the interaction. The return value is currently ignored,
but should be None.
role - The role this button undertakes. This can be the empty string, or
"selected_".
Note that code in the clicked, hovered, and unhovered methods is run inside
the current interaction. This means that the screen is not cleared while this
code is run. Displayables may be added or removed from the current
interaction, provided renpy.restart_interaction is called to let Ren'Py know
that the interaction has been changed. You should not run code that causes a
new interaction from inside these functions, except inside a new context using
renpy.call_in_new_context, renpy.invoke_in_new_context, or
ui.callsinnewcontext.
166
Renpy Programming Manual
This is a widget that can shrink the size allocated to the next widget added. If
maxwidth or maxheight is not None, then the space allocated to the child in
the appropriate direction is limited to the given amount.
Please note that this only works with child widgets that can have a limited
area allocated to them (like text), and not with ones that use a fixed area (like
images).
maxwidth - The maximum width of the child widget, or None to not affect
width.
maxheight - The maximum height of the child widget, or None ot not affect
height.
Wraps its child in a Transform, allowing the child to be rotated, zoomed, and
alpha-modified. Parameters are as for Transform.
Displays a viewport on the screen. A viewport restricts the size of its child,
and allows the child to be displayed at an offset.
child_size - The x and y size of the area the child is asked to render. If either is
None, defaults to the size of this viewport.
set_adjustments - If true, the range and page size of the adjustments will be set
by this viewport.
167
Renpy Programming Manual
mousewheel - If true, the mouse wheel can be used to scroll the viewport.
draggable - If true, the mouse can be used to drag around the viewport.
In general, viewports are only useful when the xmaximum and ymaximum
properties are specified. You'll also want to set clipping=True on the style,
although this is part of the default viewport style.
Multiple-Child Widgets
Function: ui.fixed (**properties):
This creates a layout that places widgets at fixed locations relative to the
origin of the enclosing widget. The layout takes up the entire area allocated to
it. New widgets are added to this widget until the next call to ui.close.
This creates a layout that places widgets in an evenly spaced grid. New
widgets are added to this grid until ui.close is called. Widgets are added by
going from left to right within a single row, and down to the start of the next
row when a row is full. All cells must be filled (that is, exactly col * rows
widgets must be added to the grid.)
The children of this widget should have a fixed size that does not vary based
on the space allocated to them. Failure to observe this restriction could lead to
really odd layouts, or things being rendered off screen. This condition is
relaxed in the appropriate dimension if xfill or yfill is set.
Each cell of the grid is exactly the same size. By default, the grid is the
smallest size that can accommodate all of its children, but it can be expanded
to consume all available space in a given dimension by setting xfill or yfill to
True, as appropriate. (Otherwise, xfill and yfill are inherited from the style.)
168
Renpy Programming Manual
transpose - If True, grid will fill down columns before filling across rows.
This creates a layout that places widgets next to each other, from left to right.
New widgets are added to this hbox until ui.close is called.
spacing - The number of pixels to leave between widgets. If None, take the
amount of spacing from the style.
This creates a layout that places widgets next to each other, from top to
bottom. New widgets are added to this vbox until ui.close is called.
spacing - The number of pixels to leave between widgets. If None, take the
amount of spacing from the style.
This positions child widgets so that they surround a parent widget. It takes a
single argument, places, which controls where each child widget is placed.
Places is expected to be iterable, and each element should be in the list:
'c' means center, 't' top, 'tl' top left, 'br' bottom right, and so on. A side should
be given the same number of children as the number of entries in the places
list.
The top and bottom children are rendered with a 0 requested height, while the
left and right children are rendered with a 0 requested width. It is therefore
suggested that you enforce a minimum width on the children that are placed in
these slots.
169
Renpy Programming Manual
The center widget is rendered before the others. Other than that, the order
widgets are rendered in is undefined.
No-Child Widgets
Function: ui.autobar (range, start, end, time, **properties):
Creates a bar (with a range of range) that automatically moves from start to
end in time seconds.
This creates a bar widget. The bar widget can be used to display data in a bar
graph format, and optionally to report when the user clicks on a location in
that bar.
style - The style of this bar. As of 6.2.0, there are four styles that you can use:
The width and height should be set with the xmaximum and ymaximum
properties. For best results, if clicked is set then width should be at least twice
as big as range.
This loads an image, and displays it as a widget. The image may be the name
of a file containing the image, or an arbitrary displayable.
This creates a button that contains two images. The first is the idle image,
which is used when the mouse is not over the image, while the second is the
170
Renpy Programming Manual
hover image, which is used when the mouse is over the image. If the button is
clicked or otherwise selected, then the clicked argument is called. If it returns
a value, that value is returned from ui.interact.
idle_image - The file name of the image used when this button is idle (doesn't
have the mouse pointer over it, or focus from keyboard or joystick). Must be
specified.
hover_image - The file name of the image used when this button is hovered
(the mouse pointer is over it, or the user has focused it with keyboard or
joystick). Must be specified.
image_style - The style that is applied to the images that are used as part of the
imagebutton.
role - The role this button undertakes. This can be the empty string, or
"selected_".
insensitive_image - If specified, the file name of the image used when this
button is disabled (clicked is None).
activate_image - If specified, the file name of the image used when this button
is activated (the mouse button is being held down over it, or equivalents for
keyboard and joystick).
171
Renpy Programming Manual
This displays a text area that accepts input from the user. Only ASCII is input
reliably, although some non-ASCII languages may also work on some
platforms.
length - If not None, a limit on the number of characters that can be input.
allow - If not None, a string containing the characters that are allowed.
button - If not None, then this should be a button. The input is only active
when this button is focused.
changed - If not None, then this function is called when the text is changed.
If changed is None, then the text is returned as the result of ui.interact() when
enter is pressed. Otherwise, this cannot cause ui.interact() to terminate.
This is a pseudo-widget that adds a keymap to the screen. This function takes
as keyword arguments the names of bindings or keysyms. These keywords
should be given as their arguments a function, which is called with zero
arguments when an appropriate keysym is pressed.
172
Renpy Programming Manual
menuitems - A list of tuples that are the items to be added to this menu. The
first element of a tuple is a string that is used for this menuitem. The second
element is the value to be returned from ui.interact if this item is selected, or
None if this item is a non-selectable caption.
location - Some serializable and hashable object that represents the location of
this menu in the game. (Normally, this is the name of the statement executing
the menu.) If provided, then this logs which menuitems have been chosen, and
changes the style of those menuitems to the choice_seen_style.
This widget displays nothing on the screen. Why would one want to do this?
If a widget requires contents, but you don't have any contents to provide it. It
can also be used to create empty space, by giving non-zero width and heigh
arguments.
This is a pseudo-widget that adds the pause behavior to the screen. The pause
behavior is to return the supplied result when the given number of seconds
elapses. This widget should not be added to any other widget, but should
instead be only added to the screen itself.
Please note that this widget will always pause for the given amount of time. If
you want a pause that can be interrupted by the user, add in a saybehavior.
result - The result that will be retuned after the delay time elapses.
This is a pseudo-widget that adds the say behavior to the screen. The say
behavior is to return True if the left mouse is clicked or enter is pressed. It
also returns True in various other cases, such as if the current statement has
already been seen. This widget should not be added to any other widget, but
should instead be only added to the screen itself.
If afm is present, it is a block of text, that's given to the auto forwarding mode
algorithm to determine the auto-forwarding timeout.
173
Renpy Programming Manual
There should only be one saybehavior shown at a time, otherwise they will
fight for focus.
Changes
The dismiss parameter was changed in 5.6.1 from a single keybinding to a list
of keybindings.
Adding this behavior to the screen causes ui.interact to return result when
there is no sound playing on the named music channel.
label - The text that will be displayed on the screen. It uses font properties.
The label can also be a list containing both text strings in widgets, in the case
of a widget, the widget is displayed as if it was text of the enclosing font. The
height of the area allocated is that of the font, with the width being taked from
a render of the widget.
slow - If True, the text will be typed at the screen at a rate determined by the
slow_cps property, if set, or the "Text Speed" preference. If None (the
default), then it will be typed at a speed determined by the slow_cps property.
If False, then it will appear instantly.
slow_speed - If slow is True, then this is the number of cps the text is
displayed at, overriding the preference.
slow_done - If not None and slow is True, this is a callback that is called when
we're done displaying text on the screen.
This sets up a timer that will call function after seconds seconds have elapsed.
If repeat is true, then the function is called every seconds seconds thereafter.
174
Renpy Programming Manual
args and kwargs are the positional and keyword arguments supplied to the
function, respectively.
Management Functions
Function: ui.add (w, make_current=False, once=False):
The ui.at function takes a position or motion, and applies it to the next widget
created using a ui function.
Clears the current layer of widgets. Not particularly useful in practice, and
basically duplicative of renpy.scene.
This closes the currently open widget or layer. If a widget is closed, then we
start adding to its parent, or the layer if no parent is open. If a layer is closed,
we return to the previously open layer. An error is thrown if we close the last
open layer.
Displays the current scene to the user, waits for a widget to indicate a return
value, and returns that value to the user. As a side-effect, disables fast skip
mode when executed.
175
Renpy Programming Manual
roll_forward - The value returned if the user tries to roll forward. This is
normally used in conjunction with renpy.roll_forward_info and
renpy.checkpoint.
clear - If True, the transient layer will be cleared at the end of the interaction.
This causes widgets to be added to the named layer, until a matching call to
ui.close.
This removes the displayable d from the current layer. This can only remove
things from the layer directly, not from a displayable.
This specifies the image tag for the next widget to be added to a layer. If the
next widget to be created is not added to a layer, this is ignored. When a tag is
specified, previous widgets with the same tag are removed from the layer.
This function returns a function that, when called, calls the supplied label in a
new context. Additional positional and keyword arguments are passed in to
the called label.
176
Renpy Programming Manual
This function returns a function that, when called, jumps the game to the
given label, ending the current interaction in the process. It's best used to
supply the clicked argument to the various button widgets.
This function returns a function that, when called, exits the current context,
and in the parent context jumps to the named label. It's intended to be used as
the clicked argument to a button.
This function returns a function that, when called, returns the supplied value.
It's best used to supply the clicked argument to the various button widgets.
Adjustment
Function: ui.adjustment (range=1, value=0, step=None, page=0, changed=None,
adjustable=True, ranged=None):
Adjustment objects are used to represent a numeric value that can vary
between 0 and a defined number. They also contain information on the steps
the value can be adjusted by.
range is the limit of the range of the value. This may be an integer or a float.
step is the size of the steps the value can be adjusted by. The default for this
value depends on page and range. If page is set, this defaults to 1/10 page. If
range is a float, it defaults to 1/20th of the range, otherwise it defaults to 1
pixel.
page is the size of a page, used when the bar is in paging mode. If not set,
defaults to 1/10th of the range.
177
Renpy Programming Manual
These four arguments correspond to fields on the adjustment object. The fields
can be safely set before anything using the adjustment has been rendered.
After that, they should be treated as read-only.
Call this to set the value of the adjustment to value. This will redraw all
displayables affected by this change.
178
Renpy Programming Manual
Configuration Variables
Much of the the configuration of Ren'Py is done using configuration variable.
These variables, when assigned in a python block, change the behavior of the
interpreter. As configuration variables aren't saved, and many need to be set
before the GUI initializes, it makes sense to set all configuration variables
inside init blocks. An example setting of variables is:
init -1 python:
config.screen_width = 640
config.screen_height = 480
Commonly Used
Variable: config.archives = [ ]
If set to True, developer mode is enabled. (Note that this is set to True by the
default script template.)
This controls the functionality of the help system invoked by the help button
on the main and game menus, or by pressing f1 or command-?.
(new in 6.8.0)
179
Renpy Programming Manual
This is a map used to translate text in the game menu into your language. See
Localizing Ren'Py for how to use it, and here for a list of available
translations.
If not None, this is expected to be the filename of an image giving an icon that
is used for the window on Linux and Mac OS X. This should be a large image,
with 8-bit alpha.
If not None, this is expected to be the filename of an image giving an icon that
is used for the window on Windows. This should be a 32x32 image with 1-bit
alpha. (Opaque images work the best.)
This is used to generate the default directory in which games and persistent
information are saved. The directory name generated depends on the platform:
Windows: %APPDATA%/RenPy/save_directory
Mac OS X: ~/Library/RenPy/save_directory
Linux/Other: ~/.renpy/save_directory
This should be set in a python early block, as the save directory name must be
known before init code runs, as persistent information is made available to init
code.
This directory may be overridden by user invocation. Code that needs to know
the save directory should read config.savedir instead. (new in 6.7.0)
180
Renpy Programming Manual
Occasionally Used
Variable: config.adv_nvl_transition = None
A transition that is used when showing NVL-mode text directly after ADV-
mode text.
A transition that is used after loading, when entering the loaded game.
If not None, the name of a save file to automatically load when Ren'Py starts
up. This is intended for developer use, rather than for end users. Setting this to
"1" will automatically load the game in save slot 1. (new in 6.10.0)
If not None, this causes Ren'Py to automatically define images. When not set
to None, this should be set to a list of separators. (For example, [ ' ', '_',
'/' ].) Ren'Py will scan through the list of files on disk and in archives. When
it finds a file ending with .png or .jpg, it will strip the extension, and break it
apart at the separators, to create an image name. If the name consists of at
least two components, and no image with that name already is defined, Ren'Py
will define that image to refer to a filename.
(new in 6.10.0)
Variable: config.automatic_images_strip = []
A list of strings giving prefixes that are stripped out when defining automatic
images. This can be used to remove directory names, when directories contain
images. (new in 6.10.2)
181
Renpy Programming Manual
If True, Ren'Py will print the contents of the image cache to standard output
(wherever that goes) whenever the contents of the image cache change.
If not None, this sets the default auto-forward-mode timeout. If not None, then
this is the time in seconds we should delay when showing 250 characters. 0 is
special-cased to be infinite time, disabling auto-forward mode. (new in 6.11.0)
This sets the default value of the fullscreen preference. This should be True or
False. If None, this is ignored, allowing other code to set the default value.
(It's usually set to False in options.rpy.)
The file saves/persistent in the game directory must be deleted for this to take
effect.
If not None, this sets the default number of characters per second to show. 0 is
special cased to mean an infinite number of characters per second. (It's usually
set to 0 in options.rpy.)
182
Renpy Programming Manual
The file saves/persistent in the game directory must be deleted for this to take
effect.
This is called when _window is True, and no window has been shown on the
screen. (That is, no call to renpy.shown_window has occured.) It's expected to
show an empty window on the screen, and return without causing an
interaction.
The transition that is used to display the main menu after the game ends
normally, either by invoking return with no place to return to, or by calling
renpy.full_restart.
The transition that is used to display the main menu after the end of the
splashscreen.
If not None, this is a sound file that is played when entering the game menu
without clicking a button. (For example, when right-clicking during the
game.)
If not None, this variable should give a transition that will be used when
entering the game menu.
If not None, this is a sound file that is played when exiting the game menu
without clicking a button. (For example, when right-clicking inside the game
menu.)
If not None, this variable should give a transition that will be performed when
exiting the game menu.
183
Renpy Programming Manual
This is a map from (font, bold, italics) to (font, bold, italics), used to replace a
font with one that's specialized as having bold and/or italics. For example, if
you wanted to have everything using an italic version of "Vera.ttf" use
"VeraIt.ttf" instead, you could write config.font_replacement_map["Vera.ttf",
False, True] = ("VeraIt.ttf", False, False). Please note that these mappings
only apply to specific variants of a font. In this case, requests for a bold italic
version of vera will get a bold italic version of vera, rather than a bold version
of the italic vera.
If not None, this is the upper limit on the number of frames Ren'Py will
attempt to display per second.
The transition that is used to display the main menu after leaving the game
menu. This is used when the load and preferences screens are invoked from
the main menu, and it's also used when the user picks "Main Menu" from the
game menu.
This is used to customize the choices on the game menu. Please read Main
and Game Menus for more details on the contents of this variable.
A function that is called with the argument to a hyperlink when that hyperlink
is clicked. Defaults to a function that inteprets the argument as a label, which
is called in a new context when the hyperlink is clicked. The default function
also dispatches arguments beginning with "http:" as urls, opening a web
browser for them.
184
Renpy Programming Manual
If not None, a function that is called when a hyperlink gains or loses focus.
When focus is gained, this function is called with a single argument, the
argument of the hyperlink. When focus is lost, the function is called with
None as its argument.
Variable: config.image_cache_size = 8
This is used to set the size of the image cache, as a multiple of the screen size.
This is mostly a suggestion, as if Ren'Py ever needs to display more than this
amount of images at once, it will cache them all. But it will stop predictively
loading images when the cache is filled beyond this, and it will try to drop
images from the cache until it shrinks below this size. If this is too small, there
will be more disk access as images are loaded and re-loaded. If this is too
large, memory usage will be increased as images are kept in memory.
The transition used when entering the game menu from the main menu, as is
done when clicking "Load Game" or "Preferences".
This is used to give the main menu that is shown to the user when the game
first starts. It is a list of tuples, where the first element of each tuple is the title
of the menu button, and the second element is a label that we jump to when
that button is selected. (This jump exits the context in which the start menu
executes.) The second element may also be a function, in which case it is
called when the item is selected, in the menu context. The third element in
each tuple is an expression, which is evaluated each time the main menu is
displayed. If the expression evaluates to false, the menu choice is disabled.
185
Renpy Programming Manual
Variable: config.menu_clear_layers = []
A list of layer names (as strings) that are cleared when entering the game
menu. (new in 6.10.2)
The _window_subtitle variable is set to this value when entering the main or
game menus. (new in 6.7.1)
This variable controls the use of user-defined mouse cursors. If None, the
system mouse is used, which is usually a black-and-white mouse cursor.
Otherwise, this should be a dictionary giving the mouse animations for
various mouse types. Keys used by the default library include "default", "say",
"with", "menu", "prompt", "imagemap", "pause", "mainmenu", and
"gamemenu". The "default" key should always be present. The values in the
dictionary should be list of frames making up the mouse cursor. Each frame is
an (image, x-offset, y-offset) tuple. Image is a filename of an image, while x-
and y- offset are the offsets of the hotspot within the image. The frames are
played back at 20hz, and the animation loops after all frames have been
shown. Please note that to show a frame more than once, it must be repeated
in a frame list. That is implemented efficiently.
A transition that is used when showing ADV-mode text directly after NVL-
mode text.
Variable: config.overlay_functions = [ ]
186
Renpy Programming Manual
Variable: config.thumbnail_height = 75
The height of the thumbnails that are taken when the game is saved. These
thumbnails are shown when the game is loaded. Please note that the thumbnail
is shown at the size it was taken at, rather than the value of this setting when
the thumbnail is shown to the user.
The default is set by the load_save layout, and so may differ from these
values.
The width of the thumbnails that are taken when the game is saved. These
thumbnails are shown when the game is loaded. Please note that the thumbnail
is shown at the size it was taken at, rather than the value of this setting when
the thumbnail is shown to the user.
The default is set by the load_save layout, and so may differ from these
values.
The transition used by the window hide statement when no transition has been
explicitly specified.
Variable: config.window_overlay_functions = []
A list of overlay functions that are only called when the window is shown.
(new in 6.10.0)
The transition used by the window show statement when no transition has been
explicitly specified.
187
Renpy Programming Manual
Variable: config.all_character_callbacks = [ ]
A list of callbacks that are called by all characters. This list is prepended to the
list of character-specific callbacks.
If set to False, the user is not able to skip over the text of the game.
Variable: config.args = [ ]
A list of command line arguments supplied to the game. These are prefixed by
--arg on the command line that launches Ren'Py.
If not None,this variable gives a number of seconds that Ren'Py will pause at
an in-game menu before picking a random choice from that menu. We'd
expect this variable to always be set to None in released games, but setting it
to a number will allow for automated demonstrations of games without much
human interaction.
Roughly, the number of interactions that will occur before an autosave occurs.
To disable autosaving, set config.has_autosave to False, don't change this
variable.
188
Renpy Programming Manual
Variable: config.clear_layers = []
A list of names of layers to clear when entering the main and game menus.
(new in 6.7.0)
If not None, this is expected to be a command line for an editor that is invoked
when the launch_editor (normally shift-E) key is pressed. The following
substitutions make sense here:
The separator used between filenames when lists of files are provided to the
editor.
If not None, this is expected to be a command line for an editor that is invoked
on transient files, such as lint results, parse errors, and tracebacks.
Substitutions are as for config.editor.
189
Renpy Programming Manual
This is the amount of time in seconds to spend fading the old track out before
a new music track starts. This should probably be fairly short, so the wrong
music doesn't play for too long.
If not None, this is a function that is called with the file name when a file
needs to be opened. It should return a file-like object, or None to load the file
using the usual Ren'Py mechanisms. Your file-like object must implement at
least the read, seek, tell, and close methods. (new in 6.10.0)
This is the number of steps that Ren'Py will let the user interactively rollback.
Set this to 0 to disable rollback entirely, although we don't recommend that, as
rollback is useful to let the user see text he skipped by mistake.
A function that is called when the hide statement is executed. This should take
the same arguments as renpy.hide.
190
Renpy Programming Manual
A list of functions that are called (without any arguments) when an interaction
is started or restarted.
This variable contains a keymap giving the keys and mouse buttons assigned
to each possible operation. Please see the section on Keymaps for more
information.
Variable: config.label_overrides = {
}
This variable gives a way of causing jumps and calls of labels in Ren'Py code
to be redirected to other labels. For example, if you add a mapping from
"start" to "mystart", all jumps and calls to "start" will go to "mystart" instead.
Variable: config.layer_clipping = {
}
Controls layer clipping. This is a map from layer names to (x, y, height,
width) tuples, where x and y are the coordinates of the upper-left corner of the
layer, with height and width giving the layer size.
This variable gives a list of all of the layers that Ren'Py knows about, in the
order that they will be displayed to the screen. (The lowest layer is the first
entry in the list.) Ren'Py uses the layers "master", "transient", and "overlay"
internally, so they should always be in this list.
191
Renpy Programming Manual
This is a list of functions that are called, with no arguments, when lint is run.
The functions are expected to check the script data for errors, and print any
they find to standard output (using the python print statement is fine in this
case).
If True, the start of an interaction will be delayed until all images used by that
interaction have loaded. (Yeah, it's a lousy name.)
If not None, this is expected to be a filename. Much of the text shown to the
user by say or menu statements will be logged to this file.
If not None, this function is called when an attempt to load an image fails. It
may return None, or it may return an image manipulator. If an image
manipulator is returned, that image manipulator is loaded in the place of the
missing image.
Variable: config.mouse_hide_time = 30
The mouse is hidden after this number of seconds has elapsed without any
mouse input. This should be set to longer then the expected time it will take to
read a single screen, so mouse users will not experience the mouse appearing
then disappearing between clicks.
This is a list of all of the overlay layers. Overlay layers are cleared before the
overlay functions are called. "overlay" should always be in this list.
192
Renpy Programming Manual
Variable: config.predict_statements = 10
This is the number of statements, including the current one, to consider when
doing predictive image loading. A breadth-first search from the current
statement is performed until this many statements is considered, and any
image referenced in those statements is potentially predictively loaded. Setting
this to 0 will disable predictive loading of images.
Should the user be allowed to rollback the game? If set to False, the user
cannot interactively rollback. (The feature still works for loading savegames
when the script changes.)
When there are more than this many statements in the rollback log, Ren'Py
will consider trimming the log.
If not None, then this is a function that is given the text found in strings in the
say and menu statements. It is expected to return new (or the same) strings to
replace them.
A list of functions that are called, without arguments, before the second and
later interactions caused by a line of dialogue with pauses in it. Used to
sustain voice through pauses.
193
Renpy Programming Manual
The complete path to the directory in which the game is saved. This should
only be set in a python early block. See also config.save_directory, which
generates the default value for this if it is not set during a python early block.
If not None, this is interpreted as a script version. The library will use this
script version to enable some compatibility features, if necessary. If None, we
assume this is a latest-version script.
This is normally set in a file added by the Ren'Py launcher when distributions
are built.
A list of directories that are searched for images, music, archives, and other
media, but not scripts. This is initialized to a list containing "common" and the
name of the game directory, which changes depending on the name of the exe
file. This variable is not used to load scripts, as scripts will be loaded before it
can be set.
Variable: config.skip_delay = 75
The amount of time that dialogue will be shown for, when skipping statements
using ctrl, in milliseconds. (Although it's nowhere near that precise in
practice.)
194
Renpy Programming Manual
If True, the library will display a skip indicator when skipping through the
script.
The sample rate that the sound card will be run at. If all of your wav files are
of a lower rate, changing this to that rate may make things more efficent.
A list of functions that are called (without any arguments) when an interaction
is started. These callbacks are not called when an interaction is restarted.
Variable: config.top_layers = [ ]
This is a list of names of layers that are displayed above all other layers, and
do not participate in a transition that is applied to all layers. If a layer name is
listed here, it should not be listed in config.layers.
This variable gives a list of all of the transient layers. Transient layers are
layers that are cleared after each interaction. "transient" should always be in
this list.
If not None, this should be a function that is called when a with statement
occurs. This function can be responsible for putting up transient things on the
195
Renpy Programming Manual
screen during the transition. The function is called with a single argument,
which is the transition that is occuring. It is expected to return a transition,
which may or may not be the transition supplied as its argument.
196
Renpy Programming Manual
Store Variables
This is a list of special store variables that control aspects of gameplay. These
are variables that are placed in the store (the default scope of python code),
and so can be updated during the course of the game. You must be careful to
ensure that the values of these variables can be pickled. (For example, one
should create a function with a different name inside an init block, and then
assign it to one of these variables.)
Variable List
Variable: adv = ...
This is the template adv-mode character, and the default character used when
we are in adv-mode.
The function that's called to display the menu. It should take the same
arguments as renpy.display_menu. Assigning nvl_menu to this is often done
in nvl mode.
Controls if the mouse is visible. This is automatically set to true when entering
the standard game menus.
This is the character that is used as a base for dialogue spoken by characters
with names given as a just a string. This is used by the say function.
This is the character that will say narration (that is, say statements consisting
of only a single string).
197
Renpy Programming Manual
This is used to predict the images used by say. It's called with the same two
arguments, and is expected to return a list of displayables used.
A function that is called when the say statement is called with a string for a
name. The default behavior of this function creates a copy of the name_only
object with the supplied name, and then uses that to display the dialogue. The
function takes two arguments, given the name of the character and the line of
dialogue.
When true, overlay functions will not be called and the overlay will not be
displayed. Defaults to true, but is set to false upon entering the out-of-game
menus.
198
Renpy Programming Manual
Variable: _window_subtitle =
Overlays
Overlays are used to display information above the scene currently displayed.
The overlay is regenerated each time an interaction with the user begins,
making it suitable for displaying to the user things like statistics or dates. The
overlay is generally displayed whenever transient things (like dialogue,
thoughts and menus) are.
python hide:
def date_overlay():
if date:
ui.image(date + ".png",
xpos=1.0, xanchor="right",
ypos=0.0, yanchor="top")
config.overlay_functions.append(date_overlay)
199
Renpy Programming Manual
200
Renpy Programming Manual
Saving, Loading, and Rollback can all be seen as operations that affect the
game state. Saving is an operation that persists the game state out to disk,
Loading consists of restoring the game state from disk, and Rollback reverts
the game state to what it was at a previous point in time. This game state
consists of two parts: The user state consists of variables and objects that have
been changed by the user, while the internal state consists of information used
by Ren'Py directly.
These items are automatically saved, loaded, and rolled back when the
appropriate commands are invoked by the user. You do not need do anything
for this state to be handled, and there is no way to prevent these things from
being saved.
User State. The other kind of state that Ren'Py can save and restore is user
state. User state consists of all variables that have been changed after the end
of the init phase, and all objects transitively reachable from such variables.
201
Renpy Programming Manual
$ a = 1
$ b = [ ]
$ state.love_love_points = a + 1
In this example, the variables `a` and `b` are changed by the code outside of
the init block (assuming that code executes), while state is not changed. In the
code outside of the init block, `a` is assigned a different integer object, while
`b` is assigned a new empty list. While a field on the object `state` refers to
has changed, `state` itself still refers to the same object, and not considered to
have changed. (Hence, state and its associated object are not considered part
of user state.)
User state is gathered by first finding all variables that have changed outside
of init blocks. Ren'Py then finds all objects reachable from one of those
variables through some combination of field access, iteration, or iteration over
items (as in a dictionary). This combination of variable and object values
comprises the user state.
It's important to ensure that every object in the user state can be pickled
(serialized) by the python pickle module. Most python constructs can be
pickled, including booleans, integers, floating-point numbers, strings, lists,
tuples, dictionaries, and most objects. You can also refer to your own classes
and functions, provided that they are defined in a python block (not a python
hide block) inside an init block, and always exist with the same name in later
versions of the script. There are some python objects that cannot be pickled,
such as files, iterators, and generators. These objects should not be used
outside of python hide blocks.
While these rules may seem to be complex, it's hoped that in practice they can
be reduced to a simple heuristic: Any variable changed outside of an init
block, and any object reachable from such a variable, will be saved, loaded,
and rolled back properly.
State that isn't Saved. There is some state kept by Ren'Py that is not part of
the interpreter state. This includes:
202
Renpy Programming Manual
As a result, config variables and styles should be set up in init blocks, and
then left alone for the rest of the game. As the image statement can only be
run from inside an init block, it is impossible to set up a mapping from image
name to displayable outside of an image block. To ensure compatibility
between script version, once an image name or style is present in a released
version of the game, it should be present in all future released versions of the
game.
Details. As the game is played, Ren'Py logs all changes to user and interpreter
state. When the game is saved, it writes this log out to disk, alongside the
current state. When the game is loaded back in, the variables are reset to what
the were when the init code in the current version of the script finished
running. The saved user state is then merged with this, with saved user state
overriding any variable that was also assigned in the init code. Finally, a
rollback is triggered.
The rollback that is triggered on load ends when it can find a statement that
has the same name as it had when it was encountered in the log. When the
script hasn't changed, all statements have the same name, so the effect of the
rollback is to bring control back to the start of the statement that was
executing when the user saved. When the script has changed, however, the
only statements that retain their names are statements that have an explicit
name specified. (These statements are labels, menu statements with an explicit
name, and call ... from ... statements.) The game will rollback to the start of
the most recent statement that exists in both the old and new games.
When a rollback occurs, both user and interpreter state are restored to what
they were when the statement that is being rolled back to began executing.
The statement is then executed again, and play continues normally.
Please note that we can only roll back the current statement, and not the return
sites listed on the return stack. If the name of a return site changes, we will not
be able to return from a procedure call, and the script will crash. If a return
site has an explicit name, however, that name is returned to even if the script
change. Because of this, it's important that every call site in a released game
have a from clause associated with it, giving a name for the return site that can
appear in both old scripts.
Finally, if allowed, rollback can be invoked explicitly by the user. When such
a rollback occurs, we first look for a previous statement that is a checkpoint
(checkpoints are say and menu statements, as well as python blocks that called
renpy.checkpoint). Once a checkpoint is found, we look for a statement which
has a name that exists in the current script (this is normally the same
statement). We then rollback to that statement and begin executing again.
203
Renpy Programming Manual
What this means is that when a rollback occurs, the game is usually reverted
to the start of the say or menu statement that executed before the currently
executing statement.
There is one variable that controls the behavior of loading and saving:
Variable: save_name =
This is a name that will be associated with save files. It's expected that the
game will update this on a regular basis with the name of the section of the
script that is currently executing. When a save file is shown to the user, this
name will be shown with it. Alternatively, never change this and no save
name will be shown.
Running code after a load. If the after_load label exists, then it is called after
a load has occured. It is responsible for updating variables that may have
changed between script versions, and performing any other action that may
need to be taken in response to the load. When a return statement is executed,
execution is transferred to the point where the game was saved.
Please note that when calling after_load, the return stack is not safe, and hence
the user should not be allowed to save before control returns from after_load.
To be safe, this means the after_load code should not be interactive.
Load/Save Functions
The following functions are useful for code that wants to manage loading and
saving on its own.
Returns true if filename can be loaded (by the load/save mechanism), or false
otherwise. This is a very basic check, mostly ensuring that the file exists.
This scans the savegames that we know about and returns information about
them. It returns a list of tuples, where each tuple represents one savegame and
consists of:
204
Renpy Programming Manual
The regexp matches at the start of the filename, and filters the list.
Causes the load/save mechanism to load filename. This function never returns.
Renames the save old to the save new, overwriting any existing save named
new.
filename - A string, giving the filename to save in. Note that this does not
correspond to any particular file on disk, but should be treated as an arbitrary
game identifier. Normal save slots are base-10 representations of integers,
while other names will not show up in the file-picker.
extra_info - Additional information saved with the game. This is usually the
value of save_name.
This scans a single savegame, and returns information about it. If a savegame
with the filename name does not exist, this function returns None. Otherwise,
it returns a triple consisting of:
This function should be called before renpy.save, to take the screenshot that
will be used as part of a savegame. This is called automatically when entering
the game menu, but it may make sense to call it manually if you force a save.
205
Renpy Programming Manual
Unlinks (deletes) the save file with the given name. Throws an exception if
the file can't be deleted.
206
Renpy Programming Manual
Persistent Data
Ren'Py also supports persistent data, which is saved data that is not associated
with a particular point in a game. Persistent data is data that is accessed
through the fields of the persistent object, which is bound to the variable
persistent.
The persistent variable is bound to the special persistent object. All data
reachable through fields on persistent is saved whenver Ren'Py terminates,
and loaded when Ren'Py resumes. The persistent object is special in that an
access to an undefined field on it will have a None value, rather than causing
an exception.
if not persistent.gallery_unlocked:
show background
centered "You haven't unlocked this gallery yet."
$ renpy.full_restart()
When the user gets an ending that causes the gallery to be unlocked, the flag
must be set to True:
$ persistent.gallery_unlocked = True
Multi-Game Persistence
Multi-Game persistence is a feature that lets you share information between
Ren'Py games. This may be useful if you plan to make a series of games, and
want to have them share information.
207
Renpy Programming Manual
Creates a new MultiPersistent object. This should only be called inside an init
block, and it returns a new MultiPersistent object corresponding to key.
key a key that is used to access the multipersistent data. To prevent conflicts,
we suggest that the key be suffixed by a domain you own... so if you owned
renpy.org, you could use the key "demo.renpy.org".
Saves a MultiPersistent object to disk. Changes are not persisted until this
method is called.
label start:
# ...
$ mp.beat_part_1 = True
$ mp.save()
label start:
if mp.beat_part_1:
e "I see you've beaten part 1, so welcome back!"
else:
e "Hmm, you haven't played part 1, why not try it first?"
Data Location. The place where the data is stored varies based on the
operating system being used:
Windows: %APPDATA%/RenPy/persistent
Mac OS X: ~/Library/RenPy/persistent
Linux/Other: ~/.renpy/persistent
208
Renpy Programming Manual
Obfuscating the script is practically automatic. Every time the game runs, any
.rpy file in the game directory is written out as an .rpyc file. These .rpyc files
are enough to run the game, so simply running the game once (to create the
.rpyc files) and then deleting (or more appropriately, moving away) the .rpy
files will leave you with a runnable game with an obfuscated script. As a
bonus, the .rpyc files are already parsed, improving game load time. (If a
directory contains .rpy and .rpyc files with the same stem, the newer one of
them is chosen, meaning all games get this performance improvement.)
Images can be archived using the Ren'Py launcher. Just choose "Archive
Images" from the "Tools" menu, and Ren'Py will create an archive containing
your images. It will also add a script file that contains code telling Ren'Py
where to look for the archived images.
When building distributions, you can use the option to exclude files to exclude
.rpy files.
209
Renpy Programming Manual
Localizing Ren'Py
While Ren'Py is by default set up to operate in an English speaking
environment, it is not limited to such settings. Assuming a proper font is
loaded, Ren'Py scripts can contain any language expressible in Unicode.
There are two things in the Ren'Py library that may need to be translated into a
user's language. The first is the main menu. There is no explicit support for
doing this, but as the config.main_menu variable supports changing the text of
the main menu, it also supports translating said text.
The second thing that needs to be translated is the game menu. The
config.translations dictionary is used to translate text in the game menu into
your language. If a key in this map corresponds to the English text that would
be displayed, the value corresponding to that key is displayed again. For
example:
init:
$ config.translations = {
"Yes" : u"HIja'",
"No" : u"ghobe'",
# etc.
}
The u characters prefixed to the strings on the right, while not strictly
necessary in this case, are used to tell Python that the string is in Unicode
rather than ASCII. This is useful if your language uses non-ascii characters.
The _ Function
Translation actually occurs using a function, named _, to look up the
translation of a string. The default function uses config.translations as
described above, but _ can be re-defined to use an alternate means of
determining the translation.
Function: _ (s):
210
Renpy Programming Manual
Any function that takes a **properties parameter can be given the properties
described below, including prefixed properties, but not all properties are
understood by all functions. These functions may also be given a style
parameter. A style may be specified by supplying the style object directly, or
by supplying a string giving the style name.
$ ui.text("Hello, World", xalign=0.5, yalign=0.5, size=42,
style='default')
$ ui.text('How are you doing?', style=style.centered_text)
$ ui.saybehavior()
$ ui.interact()
Styles
Each Displayable has a default style that is used when no style is explicitly
given. Displayables used by Ren'Py are often given unique styles, which allow
their look to be customized using the style system.
A style can be accessed as a field on the style object. Prefixed properties are
fields on styles, which allow values to be assigned to them. Styles should only
be created and changed inside init blocks.
init:
$ style.button_text.size = 22
$ style.button_text.hover_size = 28
New styles can be created by using the Style function. These styles should be
assigned to one or more fields on the style object at the time of creation.
Constructs a new style, with the given style as its parent. It's expected that the
result of this call will be assigned to a field of the style object.
For compatibility purposes, styles may also be created using the style.create
function.
211
Renpy Programming Manual
parent - The parent of the new style, as a string. This is either 'default' or
something more specific.
This causes all styles to be rebuilt, making it possible to change styles outside
of init code. There are several caveats:
Style Methods. Style objects have methods that may be useful when
customizing styles.
This removes all property customizations from the style it is called on.
Indexed Styles. Indexed styles are accessed by indexing a style with a value.
If an indexed style does not exist, indexing creates it. Indexed styles are
lightweight, allowing there to be a large number of them. The parent of an
indexed style is the style it was indexed off of.
212
Renpy Programming Manual
init python:
# Creates the new indexed style button['Foo']
style.button['Foo'].background = "#f00"
style.button['Foo'].xalign = 1.0
label example:
python:
# Accesses style button['Foo']
ui.textbutton('Foo', style=style.button['Foo'],
clicked=ui.returns('Foo'))
ui.interact()
Property Prefixes
The style system lets us specify new values for properties of a displayable
depending on the situation that displayable is in. There are two components of
the situation. The displayable may be selected or unselected, and it may be
activated, focused, unfocused, or unfocusable. A displayable is activated when
the button containing it is clicked, and returns to a previous state if the clicked
function returns None. Prefixed properties let one set the value of properties
for some subset of these situations.
(no prefix) * * * * * * * *
activate_ * *
hover_ * * * *
idle_ * *
insensitive_ * *
selected_ * * * *
selected_activate *
213
Renpy Programming Manual
selected_hover_ * *
selected_idle_ *
selected_insensiti
*
ve_
Resolving Conflicts
If we have multiple prefixes that would assign to the same property in the
same situation at the same time, then we take the more specific one, where a
more specific is defined as being lower in the above chart. This is the case
when more then one prefix is given for a property in the call to a function that
takes properties as arguments.
When assignment occurs at distinct points in time, then the value of the
property for a given situation is determined the last assignment performed.
This is the case when we have assignment to style properties.
When styles inherit properties, inheritance is first through the indexed form of
a style, then the unindexed form of that style, then the indexed form of that
style's parent, then the unindexed form of the parent, and so on. Specifically,
if style.mm_button inherits from style.button inherits from style.default, then
the components of style.mm_button["Start Game"] are taken from:
1. style.mm_button["Start Game"]
2. style.mm_button
3. style.button["Start Game"]
214
Renpy Programming Manual
4. style.button
5. style.default["Start Game"]
6. style.default
with the property taken from the lowest numbered style with that property
defined.
List of Styles
The styles that are available to be customized vary depending on the layouts
and themes being used. To get a complete tree of styles, including a brief
explantion of what each is used for, hit shift+D inside your game to get to the
developer menu, then pick "Style Hierarchy". (Note that config.developer
must be set to True to enable access to the developer console.)
215
Renpy Programming Manual
List of Properties
This is a list of properties, loosely grouped by the use of the property.
Text Properties
The following properties are used by Text displayables.
antialias --- If True, the text will be antialiased. Otherwise, it will be left
jagged.
black_color --- This should be an RGBA triple. When an SFont is used, this
is the color the black will be mapped to. This property is ignored when a
truetype font is used. The alpha channel in this color is ignored.
color --- The color in which the text will be displayed on the screen, as an
RGBA tuple. When an SFont is used, this is the color that white in that Sfont
will be displayed as.
first_indent --- This is used to give, in pixels, the indentation of the first line
of text in the text widget. It can be used to indent the first line of a paragraph
of text. (Not that that's a good idea on a computer monitor, better to leave a
blank line between paragraphs.)
font --- The font that will be used to render text. This is either the name of a
file containing a truetype font, or the name of a font. In the former case, the
font is loaded from the file. In the latter case, the filename is used to search
SFonts registered with register_sfont, and truetype fonts found on the system
font directory.
216
Renpy Programming Manual
size --- The size of the font that is used to display the text on the screen.
Please note that the meaning of this can vary from font to font, and bears only
a weak relationship with the number of pixels high that the font will be on the
screen.
justify --- If True, additional whitespace is inserted between words so that the
left and right margins of each line are even. This is not performed on the last
line of a paragraph.
language --- The language (really, language family) that's used to display the
text. Right now, this is one of two choices: "western" for western-style text
which is broken at spaces, "eastasian" for Chinese/Japanese text, which can be
broken between characters.
layout --- Controls how line-breaking occurs. This defaults to "greedy", which
attempts to put as much as possible on each line. It may also be "subtitle",
which tries to make the lines even in length.
line_spacing --- This is used to increase or decrease the spacing between lines
of text by a constant number of pixels. A positive value increases, while a
negative value decreases the spacing.
minwidth --- The minimum width in pixels of this text. If the rendered text is
smaller than this, it is right-padded with whitespace until it is at least this
many pixels long.
outlines --- A list of 2 or 4-component tuples, giving the size, color, and
optionally the x and y offsets of outlines around the text. An outline is a block
of text that has been expanded in size by a given number of pixels. The x and
y offsets can be omitted. The first tuple in the list is furthest from the screen,
while the last is closest. (new in 6.8.0)
rest_indent --- This is used to give, in pixels, the indentation of the second
and later lines of a text widget. It can be used to give a hanging indent to
quoted dialogue.
217
Renpy Programming Manual
slow_abortable --- If True, slow text can be aborted by clicking the mouse.
text_align --- This is used to control the horizontal alignment of the lines of
text in the area allocated to the Text widget containing that text. It only really
has any effect if the text is more than one line long. It's a number between 0
and 1, which gives the fraction of empty space that should be to the left of
each line of text. (To center text, it should be 0.5.)
underline --- If true, then this text will be rendered with an underline.
Window Properties
The properties control the look of Windows and Buttons.
background --- A Displayable that is used as the background for the window.
This needs to be a Displayable that always draws exactly the size requested of
it, which usually means either a Solid or a Frame. This can also be None,
which means that there is no background on this window. (All the other
window properties that refer to a background still work. Just think of them as
if their background was transparent.)
foreground --- This is drawn in the same way as the background, except it is
drawn above the contents of the window.
left_margin --- The amount of transparent space left to the left of this
window. If a floating point number, it is scaled to the available width.
right_margin --- The amount of transparent space left to the right of this
window. If a floating point number, it is scaled to the available width.
top_margin --- The amount of transparent space left to the top of this
window. If a floating point number, it is scaled to the available height.
bottom_margin --- The amount of transparent space left to the bottom of this
window. If a floating point number, it is scaled to the available height.
218
Renpy Programming Manual
left_padding --- The amount of space left between the edge of the border and
the left side of the contents of the window. If a float, it is scaled to the width
of the window.
right_padding --- The amount of space left between the edge of the border
and the right side of the contents of the window. If a float, it is scaled to the
width of the window.
top_padding --- The amount of space left between the edge of the border and
the top side of the contents of the window. If a float, it is scaled to the height
of the window.
bottom_padding --- The amount of space left between the edge of the border
and the bottom side of the contents of the window. If a float, it is scaled to the
height of the window.
xfill --- If True, the window will expand to fill all available space in the x
direction. If False, it will shrink to fit its contents.
yfill --- If True, the window will expand to fill all available space in the y
direction. If False, it will shrink to fit its contents.
xminimum --- The minimum size of this window in the x direction, including
margins and padding. If the window would be smaller than this, it is grown to
be at least this size. If a floating point number, it is scaled to the available
width.
yminimum --- The minimum size of this window in the y direction, including
margins and padding. If the window would be smaller than this, it is grown to
be at least this size. If a floating point number, it is scaled to the available
height.
219
Renpy Programming Manual
size_group --- If not None, this should be set to a string. All windows or
buttons with a given string as their size_group are rendered at the same width.
(new in 6.6.0)
clipping - If true and the child is bigger than the maximum size set for this
window, it will be clipped to the size of the window.
Button Properties
These are only applicable to Buttons.
hover_sound --- The sound to play when this widget becomes hovered.
focus_rect --- If not None, this gives as a (x, y, width, height) tuple the focus
rectangle of a button, as an offset from the upper-left corner of the button. For
proper keyboard navigation, the focus rectangles of images are not allowed to
overlap. By setting this and focus_mask on an imagebutton, one can have
imagebuttons that overlap, but yet still support keyboard focus. This should
almost certainly never be set on an individual image, but rather for each
individual button (and it's rare to do even that).
child --- If not None, this displayable is displayed in the place of the child of
this button.
mouse --- If not None, a string giving the name of the mouse cursor that is
used when this button is focused. The name must be listed in config.mouse.
This also works with other focusable displayables.
220
Renpy Programming Manual
Bar Properties
The ui.bar has a few properties that are specific to it, that control the look of
the bars. The bar has gutters on the left and the right. The remaining space is
the space in which the bar can change, with the division of the bar being the
fraction of this space representing the bar's value as a fraction of the range.
When the bar is drawn, the thumb's shadow is drawn first, followed by the left
and right sides of the bar, followed by the thumb.
bar_invert --- If true, the value of the bar is represented on the right/top side
of the bar, rather then the left/bottom side of the bar.
bar_resizing --- If true, we resize the sub-bars, rather than rendering them full
size and then cropping.
left_gutter --- The size of the left gutter of a horizontal bar, in pixels. (Named
fore_gutter internally.)
right_gutter --- The size of the right gutter of a horizontal bar, in pixels.
(Named aft_gutter internally.)
top_gutter --- The size of the top gutter of a vertical bar, in pixels. (Named
fore_gutter internally.)
bottom_gutter --- The size of the bottom gutter of a vertical bar, in pixels.
(Named aft_gutter internally)
left_bar --- A Displayable that is used to draw the left side of a horizontal bar.
This displayable is first rendered at the full size of the bar, and then cropped
so only the left side is visible. (Named fore_bar internally.)
right_bar --- A Displayable that is used to draw the right side of a horizontal
bar. This displayable is first rendered at the full size of the bar, and then
cropped so only the right side is visible. (Named aft_bar internally.)
top_bar --- A Displayable that is used to draw the top of a vertical bar. This
displayable is first rendered at the full size of the bar, and then cropped so
only the top is visible. (Named fore_bar internally.)
221
Renpy Programming Manual
thumb --- If not None, this is a thumb image that is drawn over the break
between the sides of the bar.
thumb_offset --- The amount by which the thumb overlaps the bars, in pixels.
To have the left and right bars continue unbroken, set this to half the width of
the thumb. For compatibility's sake, we take the absolute value of this
property.
unscrollable --- Controls what happens if the bar is unscrollable (if the range
is set to 0, as is the case with a ui.viewport containing a displayable smaller
than itself. There are three possible values:
(new in 6.8.0)
Box Properties
The HBox, VBox, and Fixed displayables are instances of a common
MultiBox displayable. These properties control how these displayables are
laid out.
spacing --- The spacing between elements in the box, in pixels. This is also
used for ui.grid and ui.side. This was formerly known as box_spacing, an alias
which still works.
first_spacing --- If not None, the spacing between the first two elements in
the box, in pixels. This is only used for boxes. This was formerly known as
box_first_spacing, an alias that still works.
xfill --- If True, the box will expand to fill all available space in the x
direction. If False, it will shrink to fit its contents.
222
Renpy Programming Manual
yfill --- If True, the box will expand to fill all available space in the y
direction. If False, it will shrink to fit its contents.
Position Properties
Position properties are applied to displayables that are smaller than the space
allocated to them. They apply to all displayables, and control the placement of
the widget in the space. For example, position properties can be used to
control the placement of a dialogue window on the screen.
Position properties work best when a small displayables is placed into empty
space. This is the case for say windows, and the menus that are displayed as
part of the main menu. Position properties work on other displayables, but the
vagaries of how space is allocated can make some of the results
counterintuitive.
xanchor --- The x-axis location of the anchor, relative to the upper-left corner
of the displayable. This may be an absolute number of pixels, or a floating
point number which is interpreted as a fraction of the size of the displayable.
xpos --- The x-axis location of the position, relative to the upper-left corner of
the available space. This may be an absolute number of pixels, or a floating
point number which is interpreted as a fraction of the size of the available
space.
xalign --- A shortcut for specifying xanchor and xpos at the same time. This
should almost always be assigned a floating point number. As an example,
xanchor=0.5 will center a displayable in the available space.
yanchor --- The y-axis location of the anchor, relative to the upper-left corner
of the displayable. This may be an absolute number of pixels, or a floating
point number which is interpreted as a fraction of the size of the displayable.
ypos --- The y-axis location of the position, relative to the upper-left corner of
the available space. This may be an absolute number of pixels, or a floating
point number which is interpreted as a fraction of the size of the available
space.
yalign --- A shortcut for specifying yanchor and ypos at the same time. This
should almost always be assigned a floating point number.
223
Renpy Programming Manual
xoffset --- An offset, in pixels, that is added to the position computed using
xpos and xanchor.
yoffset --- An offset, in pixels, that is added to the position computed using
ypos and yanchor.
Assuming xpos, ypos, xanchor, and yanchor have all been converted to pixels
if necessary, the position of the upper-left corner of a displayable relative to
the upper-left corner of the area it is laid out in can be expressed as:
224
Renpy Programming Manual
Layouts control the feel of the various screens that make up the game
menu. They control the placement of components on those screen,
and what those components do if they interact.
Themes control the look of buttons, bars, frames, labels, and prompts.
One can customize the main and game menus to add additional
choices to those menus, over and above the ones provided by the
layouts.
Finally, one can use the style system to further customize the look and
layout of the various out-of-game menu screens.
Order of Customizations
225
Renpy Programming Manual
Layouts
Layouts control the feel of the out-of-game menus. There are five main kinds
of layouts:
There are also standalone layouts which do not fall into any of these
categories. While a game needs exactly one of each of the five main kinds of
layouts to function properly, it can have as many standalone layouts as it
needs.
Note that there are combinations of layouts and themes that will not look
reasonable together. This is not a bug... it's impossible to have every layout
work with every other layout and every theme, and still have an unlimited
range of layouts and themes. Caveat factor.
226
Renpy Programming Manual
main_menu layouts
The main_menu layouts are responsible for defining the look of the main
menu. This includes the background of the main menu, and the buttons that
are used to go to the game menu or start a game.
This displays the classic main menu, which stacks the main menu buttons
vertically.
This defines a main menu layout that groups buttons into rows horizontally,
and then stacks those rows vertically.
Variable: config.main_menu_per_group = 2
227
Renpy Programming Manual
ground - The ground image. This is used for parts of the screen that are not
defined.
selected - The selected image. This used for hotspots that are hovered.
hotspots - A list of tuples defining the hotspot. Each tuple consists of:
idle - If not None, an image that is used for images that are not hovered. If this
is None, it defaults to ground. (new in 6.10.1)
Despite the name, this function can take arbitrary displayables (like
Animations) as well as images.
228
Renpy Programming Manual
Navigation layouts
The navigation layouts are responsible for defining the navigation through the
game menu. This includes the background of the game menus and the buttons
that are used to go between game menu screens.
This displays the navigation buttons in horizontal groups, which are then
stacked vertically.
Variable: config.navigation_per_group = 2
229
Renpy Programming Manual
ground - The displayable used for disabled buttons, and areas that are not in a
hotspot.
Despite the name, this function can take arbitrary displayables as well as
images.
load_save layouts
The load_save layouts are responsible for defining the load and save screens.
230
Renpy Programming Manual
This layout displays the the load and save screens as having a certain number
of rows and columns of slots, with a row of navigation buttons on top.
Variable: config.file_page_rows = 5
Variable: config.file_page_cols = 2
Variable: config.file_quick_access_pages = 8
If True, the pager is disabled. This prevents access to pages other than the first
page of files.
If not None, this should be a displayable that will be shown with empty
load/save slots.
231
Renpy Programming Manual
The format used for file times in the file entry slots.
This uses a scrolling area that contains file picker entries. The user picks one
of these entries to load or save a file. There is one big thumbnail to the right of
the screen, which corresponds to the currently hovered entry.
(config.thumbnail_width and config.thumbnail_height control the size of this
thumbnail.)
Variable: config.load_save_slots = 50
Variable: config.load_save_auto_slots = 5
Variable: config.load_save_quick_slots = 5
When not None, this should be a displayable that will be shown in the
thumbnail frame when no save slot has been hovered.
232
Renpy Programming Manual
The format used for file times in the file entry slots.
ground - The displayable used for disabled buttons, and areas that are not in a
hotspot.
233
Renpy Programming Manual
variant - Allows us to define only the save or load screens. This can be
"save", "load", or None to define the save and load screens at once. If a save
screen is defined, a load screen must be defined (perhaps with different
parameters), and vice versa.
Screenshots and slot text are placed inside windows that are laid out relative
to the slot. Adjusting style.file_picker_ss_window controls the screenshot
placement, and adjusting style.file_picker_text_window controls the
placement of per-slot test. It will usually be necessary to adjust these styles, as
the default places both in the upper left.
Hotspot functions may also include the untranslated names of game menu
buttons. If at least one such button is defined, the navigation is not shown, and
the imagemap is expected to define all relevant game menu buttons.
Despite the name, this function can take arbitrary displayables as well as
images. The images or displayables used should be transparent to allow the
navigation to show through, unless the game menu buttons are defined here.
If not None, this should be a displayable that will be shown with empty
load/save slots.
The format used for file times in the file entry slots.
234
Renpy Programming Manual
yesno_prompt layouts
The yesno_prompt layouts are responsible for defining yes/no prompt screens.
This displays the classic yes/no prompt, which is just a prompt above two
buttons.
This layout uses an imagemap to handle prompting the user with yes/no
questions.
ground - The displayable used for disabled buttons, and areas that are not in a
hotspot.
235
Renpy Programming Manual
layout.ARE_YOU_SURE
layout.DELETE_SAVE
layout.OVERWRITE_SAVE
layout.LOADING
layout.QUIT
layout.MAIN_MENU
u"Are you sure you want to return to the main menu?\nThis will lose
unsaved progress."
236
Renpy Programming Manual
Hotspot functions may also include the untranslated names of game menu
buttons. If at least one such button is defined, the navigation is not shown, and
the imagemap is expected to define all relevant game menu buttons.
Despite the name, this function can take arbitrary displayables as well as
images. The images or displayables used should be transparent to allow the
navigation to show through, unless the game menu buttons are defined here.
preferences layouts
The preferences layouts are used to define the preferences screen.
237
Renpy Programming Manual
238
Renpy Programming Manual
ground - The displayable used for disabled buttons, and areas that are not in a
hotspot.
239
Renpy Programming Manual
There are two kinds of hotspots, buttons and bars. The buttons are:
The other type of hotspot is a horizontal bar. The selected images are used for
the full portion of the bar, while the unselected images are used for the empty
part of the bar. The known bars are:
"Music Volume"
"Sound Volume"
"Voice Volume"
"Auto-Forward Time"
"Text Speed"
Hotspot functions may also include the untranslated names of game menu
buttons. If at least one such button is defined, the navigation is not shown, and
the imagemap is expected to define all relevant game menu buttons.
Despite the name, this function can take arbitrary displayables as well as
images. The images or displayables used should be transparent to allow the
navigation to show through, unless the game menu is defined here.
240
Renpy Programming Manual
joystick_preferences layouts
The joystick_preferences layout are used to define the joystick preferences
screen.
standalone layouts
These provide interesting functionality to Ren'Py games, and they stand alone,
so it's possible to call as many of them as you want.
This changes the in-game menus to use buttons defined in the current theme.
241
Renpy Programming Manual
When it comes to defining layouts, there are two important principles you
should follow:
While the default layouts are enable through the use of functions on the
layout object, this is by no means the only way to supply a layout. For a user-
defined layout, it should be enough to place the call to layout.provides in an
init -2 python block, with the rest of the code residing in init blocks or labels
as appropriate.
main_menu layouts
Main_menu layouts need to call:
layout.provides('main_menu')
Main menu layouts are expected to define a main_menu_screen label. This label
is expected to:
242
Renpy Programming Manual
Displays the main menu on the screen. How this is done is generally up
to the layout itself, but we strongly recommend you use
config.main_menu to control the generation of the menu. Note that
the documentation for config.main_menu says that bare strings cause
a jump out of context to occur; use ui.jumpsoutofcontext to
implement this properly. Using config.main_menu ensures that your
layout will work even with extensions (like image galleries) that add
options to the main menu.
navigation layouts
Navigation layouts need to call:
layout.provides('navigation')
This function displays the navigation on the game menu. It's expected to set
the background of the game menu. If screen is not None, it's also expected to
display the navigation buttons defined in config.game_menu, highlighting the
one named in screen.
243
Renpy Programming Manual
load_save layouts
Load/save layouts need to call:
layout.provides('load_save')
Please see the section on load/save functions for the functions that would be
used to actually implement these screens.
yesno_prompt layouts
Yes/no prompt layouts need to call:
layout.provides('yesno_prompt')
screen - The screen button that should be highlighted when this prompt is
shown. If None, then no game menu navigation is shown.
message - The message that is shown to the user to prompt them to answer yes
or no.
This function returns True if the user clicks Yes, or False if the user clicks No.
244
Renpy Programming Manual
preferences layouts
Preferences layouts need to call:
layout.provides('preferences')
joystick_preferences layouts
Joystick preferences layouts need to call:
layout.provides('joystick_preferences')
Example
An example of a new main_menu layout:
init -2 python:
layout.provides('main_menu')
label main_menu_screen:
python:
layout.button(u"Start Game", "mm",
clicked=ui.jumpsoutofcontext('start'), xpos=400, ypos=400)
layout.button(u"Continue Game", "mm",
clicked=_intra_jumps("load_screen", "main_game_transition"), xpos=450,
ypos=430)
245
Renpy Programming Manual
layout.button(u"Preferences", "mm",
clicked=_intra_jumps("preferences_screen", "main_game_transition"),
xpos=500, ypos=460),
layout.button(u"Quit", "mm", clicked=ui.jumps("_quit"),
xpos=550, ypos=490)
ui.interact()
246
Renpy Programming Manual
Themes
Themes provide a simple way of changing the look of the main and game
menus. A single function call applies styles to many of the elements of the
main and game menus, giving a consistent look to the interface.
Theme Functions
These theme functions are
This enables the use of the roundrect theme. By default, this theme styles the
game in a blue color scheme. However, by supplying one or more of the
parameters given below, the color scheme can be changed.
247
Renpy Programming Manual
text_size - The size of text, such as button captions, labels, and prompts.
Defaults to 18 if the screen is 640 pixels wide or less, and 22 otherwise.
Component functions
The following functions exist to allow you to add elements of the roundrect
theme to another theme. The other theme must have been set up before these
functions can be used. Arguments are as for roundrect, except that all must be
specified (no defaulting occurs).
theme.roundrect_labels(text_size, label)
theme.roundrect_frames(less_rounded, frame)
theme.roundrect_buttons(text_size, less_rounded, widget,
widget_hover, widget_text, widget_selected, disabled, disabled_text)
theme.roundrect_large_buttons(text_size, less_rounded, widget,
widget_hover, widget_text, widget_selected, disabled, disabled_text)
theme.roundrect_prompts(text_size, label)
theme.roundrect_bars(widget, widget_hover)
248
Renpy Programming Manual
This function selects a theme that is based on outlining text in different colors.
background - A displayable used for the game and main menu backgrounds.
text_size - The size of large text. (Used for buttons, labels, and prompts.)
Component functions
The following functions exist to allow you to add elements of the outline
theme to another theme. The other theme must have been set up before these
functions can be used. Arguments are as for theme.outline, except that all
must be specified (no defaulting occurs).
theme.outline_frames()
249
Renpy Programming Manual
This is a theme that attempts to emulate the theme used by Ren'Py 6.5.0 when
no theme was explicitly specified.
Theme Modifiers
These are functions that can be called after a theme function, allowing you to
change a portion of a theme.
250
Renpy Programming Manual
in that order.
Custom Theme
It's also possible to define your own Ren'Py theme. A custom theme consists
of Ren'Py code that does the following.
Often, the base styles come in name/name_text pairs. In these cases, name
represents a Button or Window with style name, in which a Text with style
name_text lives.
251
Renpy Programming Manual
Used for frames on top of which the rest of the interface can
comfortably sit.
Used for buttons that are arranged in a group, such that only one of
the buttons in the group can be selected at a time.
Used for large buttons, such as file picker entries, that can contain a
large amount of text and other information.
252
Renpy Programming Manual
Used for labels, which are small text messages that never change.
Used for prompts, longer text messages which may change at runtime.
Used for horizontal and vertical bars, respectively. Bars are generally
intended to indicate a quantity or an amount of progress, but aren't
expected to be adjusted by the user.
Used for horizontal and vertical sliders, respectively. Sliders are bars
that are used to adjust a value.
Used for the backgrounds of the main and game menus, respectively.
253
Renpy Programming Manual
Main Menu
The main menu can be customized by setting the config.main_menu variable.
This variable should be a list of tuples. The first component of each tuple is
the name of the button on the main menu. The second component can be one
of three things:
To jump from the main menu to one of the screens in the game menu, one
should use the _intra_jumps function to specify the appropriate transition.
transition should be a string giving a field on the config object. When this
function is run, that field is accessed, and is used to specify the transition that
is used.
254
Renpy Programming Manual
config.main_menu = [
(u"Start Game", "start", "True"),
(u"Continue Game", _intra_jumps("load_screen",
"main_game_transition"), "True"),
(u"Preferences", _intra_jumps("preferences_screen",
"main_game_transition"), "True"),
(u"Quit", ui.jumps("_quit"), "True")
]
Game Menu
The first thing one may wish to do when modifying the game menu is to add a
screen to it. This is done in two steps. The first is to create the screen, and the
second is to add it to the config.game_menu list so that it can be reached from
the game menu.
So that the user can see it, the screen should be added to config.game_menu.
This is a list of four- or five-component tuples. The first is the name of the
screen. It's used to determine if the button used to reach that screen should be
indicated as selected. The second component is the text used for that button.
The third component is a function that executes when the button is clicked.
Normally, an appropriate function is _intra_jumps(label, transition), where
label is the name of the label of your screen. The fourth component is a string
containing a python expression. If the expression is not true, the button is
insensitive. The optional fifth component is also a string containing a python
expression. If the expression is not true, the button is not shown. (changed in
6.6.2)
255
Renpy Programming Manual
One can customize the screen the game menu jumps to by default by changing
the value of _game_menu_screen. For example, one could set this to
"load_screen" for the first few interactions, and then set it to "save_screen" for
the rest of the game. This is especially useful for a game with no main menu.
If set to None, the user cannot enter the game menu. This is set to None at the
start of the splashscreen, and reset to its old value when the splashscreen
completes.
screen - The screen button that should be highlighted when this prompt is
shown. If None, then no game menu navigation is shown.
message - The message that is shown to the user to prompt them to answer yes
or no.
This function returns True if the user clicks Yes, or False if the user clicks No.
Pre-defined Screens. Layouts define the load screen, save screen, and
preferences screen are define at the load_screen, save_screen, and
preferences_screen, respectively.
256
Renpy Programming Manual
Please see the page on Saving, Loading, and Rollback for a list of functions
that can be used in the load and save screens, and the page on the Preferences
for a list of preferences that can be customized.
Jump to _return to return to the game or the main menu, as appropriate. Jump
to _noisy_return to play config.exit_sound before returning.
config.overlay_functions.append(overlay)
label battle_begin:
menu:
"A battle is about to begin! Would you like to save your
game?"
"Yes.":
$ renpy.game_menu("save_screen")
"No.":
pass
257
Renpy Programming Manual
Compatibility Mode
Ren'Py also supports a compatibility mode that makes layouts and themes
more compatible with how they were used in Ren'Py 6.5.0. This compatibility
mode is automatically enabled when config.script_version is set to (6, 5, 0) or
less. It can also be enabled explicitly by calling layout.compat().
This enables a compatibility mode that sets up themes and styles as they were
used in Ren'Py 6.5.0 and prior versions.
258
Renpy Programming Manual
Preferences
Preferences can be updated using the following variables and functions.
Variable: _preferences.transitions = 2
Variable: _preferences.text_cps = 0
The number of characters per second to show slow text at. 0 means to show
infinitely fast. A sensible range is between 1 and 150. The default value of this
can be set with config.default_text_cps.
Variable: _preferences.afm_time = 0
If True, skipping will skip unseen messages. If False, only seen messages will
be skipped.
Sets the volume of the given mixer to the given volume. mixer is usually 'sfx',
'voice', or 'music', volume ranges between 0 and 1.0.
259
Renpy Programming Manual
Gets the volume of mixer, which is usually 'sfx', 'voice', or 'music'. The
returned volume ranges between 0 and 1.0.
While this functionality has been added to Ren'Py at a user's request (and
because it simplifies the Ren'Py code), it's not altogether clear that it should be
used. Having a common set of keybindings makes games easier to play by
reducing the learning curve of users. It's probably better to build consensus
around a change in keybindings, rather than unilaterally making one game
different from every other game.
Anyway, in Ren'Py keysyms are strings. The first kind of keysym is of the
form 'mouseup_#' or 'mousedown_#', for a number between 1 and 5. These
keysyms are generated by mouse button presses, releases, or turns of the
mouse wheel. For example, "mousedown_1" is generally a press of the left
mouse button, "mouseup_1" is a release of that button, and "mousedown_4" is
a turn of the the mouse wheel to the top.
A second kind of keysym is a joystick keysym. These begin with joy_. They
are defined in config.joystick_keys, and mapped to actual joystick events by
the user.
The final kind of keysym is the symbolic name for the key. This can be any of
the K_ constants taken from pygame.constants. This type of keysym looks
like "K_BACKSPACE", "K_RETURN", and "K_TAB"; a full list of this kind
of keysyms may be found here.
260
Renpy Programming Manual
init:
$ config.keymap['dismiss'].append('t')
$ config.keymap['dismiss'].remove('K_SPACE')
The default keymap is contained inside the python code implementing Ren'Py,
and as of version 6.9.1 is as follows:
config.keymap = dict(
# Say.
rollforward = [ 'mousedown_5', 'K_PAGEDOWN' ],
dismiss = [ 'mouseup_1', 'K_RETURN', 'K_SPACE', 'K_KP_ENTER',
'joy_dismiss' ],
# Pause.
dismiss_hard_pause = [ ],
# Focus.
focus_left = [ 'K_LEFT', 'joy_left' ],
focus_right = [ 'K_RIGHT', 'joy_right' ],
focus_up = [ 'K_UP', 'joy_up' ],
focus_down = [ 'K_DOWN', 'joy_down' ],
# Button.
button_select = [ 'mouseup_1', 'K_RETURN', 'K_KP_ENTER',
'joy_dismiss' ],
# Input.
input_backspace = [ 'K_BACKSPACE' ],
input_enter = [ 'K_RETURN', 'K_KP_ENTER' ],
# Viewport.
viewport_up = [ 'mousedown_4' ],
viewport_down = [ 'mousedown_5' ],
viewport_drag_start = [ 'mousedown_1' ],
viewport_drag_end = [ 'mouseup_1' ],
261
Renpy Programming Manual
bar_activate = [ 'mousedown_1', 'K_RETURN', 'K_KP_ENTER',
'joy_dismiss' ],
bar_deactivate = [ 'mouseup_1', 'K_RETURN', 'K_KP_ENTER',
'joy_dismiss' ],
bar_decrease = [ 'K_LEFT', 'joy_left' ],
bar_increase = [ 'K_RIGHT', 'joy_right' ],
)
262
Renpy Programming Manual
User-Defined Displayables
It's possible for a user to define displayables that extend Ren'Py's behavior.
This section will explain the steps that are involved in defining your own
displayables, and how to use them with Ren'Py.
Displayables must be capable of being serialized. This means that they must
not contain references to objects that are incapable of being serialized. Of
particular note is that the renpy.Render object is incapable of being serialized.
Displayables have a number of methods and fields, not all of which are
documented here. We strongly recommend you use a unique prefix for the
names of fields and methods you add, to minimize the chance of conflicts.
renpy.Displayable
This is the base class for user-defined displayables. It has the following fields
and methods.
Since you will be implementing many of these methods, rather than calling
them, we include the normally hidden self parameter in the definition.
This field should be True if it's possible for the displayable to gain focus, and
false otherwise.
263
Renpy Programming Manual
The __init__ method may be overridden with your own parameter list, but the
default method must be called to properly initialize a Displayable. The
parameters the default methods take are:
focus - if given, a string giving the name of the focus group in the object. The
focus group is used to determine which displayable should be focused after an
interaction. For example, if the third displayable in focus group "foo" has
focus at the end of an interaction, the third displayable in "foo" will have
focus at the start of the next interaction, even if the two displayables are not
the same.
default - determines if this object can be focused by default. This is only used
if no object with the same focus name is found in an interaction.
style - The name of the default style, used to construct a style object that is
placed in the style field.
Called to indicate that this displayable has been given the focus. default is true
if the focus has been given to this displayable at the start of an interaction.
The default implementation sets the style prefix of this displayable and its
children to 'hover_'.
If this returns a non-None value, the current interaction is terminated and the
value is returned.
The default implementation resets the style prefix of this displayable and its
children to 'idle_'.
264
Renpy Programming Manual
Sets the style prefix of this displayable and its children to one of:
"insensitive_", "idle_", "hover_", "activate_", "selected_insensitive_",
"selected_idle_", "selected_hover_", or "selected_activate_".
width, height - The area allocated to this displayable. The created displayable
may be bigger or smaller than this, without consequence.
st - The displayable timebase, the number of seconds this displayable has been
shown for.
at - The animation timebase, the number of seconds an image with the same
tag as this displayable has been shown for.
ev - The pygame event object. This can be read to get the type of event and
other parameters.
x, y - The position of the mouse at the time of the event. This is relative to the
upper-left corner of this displayable, and should be used in preference to
similar data contained in ev.
If this method returns a non-None value, then that value is returned from
ui.interact. If it returns None, processing of the event is continued by the other
265
Renpy Programming Manual
Returns a tuple of (xpos, ypos, xalign, yalign, xoffset, yoffset), that is used to
place this displayable on the screen.
This should be overridden to return a list of all the child displayables fo this
displayable.
This is called once per interaction, to inform the displayable that a new
interaction has begun.
Often, this should call renpy.redraw(self, 0), to make sure that the displayable
is redrawn for each interaction. This is especially useful if the displayable
participates in rollback.
renpy.Render
Since one will not be subclassing renpy.Render, we omit the self parameter
from method descriptions.
Constructs a new render object with the given width and height.
Copies the contents of the source render to this one. Pos is a 2-element tuple
giving the position of the upper-left-hand corner of the source render, relative
to the upper-left-hand corner of this render, in pixels.
Fills the render with the given color, which should be an RGBA tuple.
266
Renpy Programming Manual
Deallocates the memory used by this Render. This must be called on a Render
returned by renpy.render or renpy.Render.subsurface if the render is not
blitted to another Render. Once this is called, the render should not be blitted
to a surface or have any other method called. It is safe to call this on a Render
that has been blitted somewhere, as these calls are ignored.
This is used to indicate that a sub-region of this Render is eligible for being
focused.
This function returns a canvas object that has methods corresponding to the
pygame.draw functions, except that the first argument (the surface) is omitted.
For example, instead of calling pygame.draw.line(surface, (255, 255, 255,
255), (100, 100), (200, 200)), one would call c.line((255, 255, 255, 255), (100,
100), (200, 200)).
Code that uses a canvas may not be portable to non-pygame platforms, should
we choose to support them in the future.
267
Renpy Programming Manual
renpy.Container
The renpy.Container class implements a displayable that positions its children
using style properties, in a manner similar to Fixed and ui.fixed. Unlike the
displayable returned by those functions, renpy.Container supports adding and
removing children, and it may be subclassed to change its behavior (including
the behavior of the render and event methods).
Field: children = []
The last child added to this container and not removed, or None if there are no
children in this container.
Field: offsets = []
A list of (x, y) tuples giving the coordinates of the upper-left corners of the
children of this displayable.
It also has three methods. (We give these without the self parameter, as we
expect them to be called, and only rarely overridden.)
This should be called after add or remove, to indicate that the container has
changed and should be redrawn.
268
Renpy Programming Manual
Utility Functions
Function: renpy.render (displayable, width, height, st, at):
Call this function to get a Render from a displayable. The object returned from
this function should be treated as immutable, as it may be stored in a cache. If
an object with the same width and height has already been rendered (and has
not been invalidated using the renpy.redraw), the cached render will return.
Causes an event to occur in time seconds. The type of the event is undefined.
269
Renpy Programming Manual
Notes
Although we will do our best to avoid breaking code unnecessarily, we
reserve the right to change the displayable API as necessary to support the
future development of Ren'Py. As a result, code using the displayable API
may not be forward-compatible with future versions of Ren'Py.
270
Renpy Programming Manual
Python Modules
It's possible to write python modules, and import them into Ren'Py. These
python modules define their own namespace, which is different from the
namespace in which python-in-Ren'Py executes. Objects defined in python
modules do not participate in rollback, although they may be saved if they are
reachable from the main Ren'Py store.
Python modules may be placed in the game directory, while python packages
are subdirectories of the game directory containing __init__.py files. The only
encoding we support is utf-8.
It's probably easier to not change objects that are created in python modules.
Example
As a trivial example, we could have the following module, which is placed in
magic.py in the game directory.
import renpy.store as store
import renpy.exports as renpy
271
Renpy Programming Manual
In a Ren'Py script file, we can import the module using an import statement:
init:
$ import magic
"1 + 2 = %(result)d"
272
Renpy Programming Manual
Developer Tools
Ren'Py includes a number of features to make a developer's life easier. Many
of them need the variable config.developer to be set to True to operate.
Please see Integrating SciTE with Ren'Py for information about how to use
Ren'Py with the customized SciTE text editor.
See Integrating Crimson Editor with Ren'Py for information on how to use
Ren'Py with Crimson Editor.
Shift+R Reloading
When config.developer is true, hitting shift+R will save the current game,
reload the game script, and reload the game. This will often place you at the
last unchanged statement encountered before shift+R was pressed.
This allows the developer to make script changes with an external editor, and
not have to exit and restart Ren'Py to see the effect of the changes.
Note that game state, which includes variable values and scene lists, is
preserved across the reload. This means that if one of those statements is
changed, it is necessary to rollback and re-execute the statement to see its new
effect.
273
Renpy Programming Manual
Warping to a Line
Ren'Py supports warping to a line in the script, without the developer to play
through the entire game to get there. While this warping technique has a
number of warnings associated with it, it still may be useful in providing a
live preview.
When warping is invoked, Ren'Py does a number of things. It first finds all of
the scene statements in the program. It then tries to find a path from the scene
statements to every reachable statement in the game. It then picks the
reachable statement closest to, but before or at, the given line. It works
backwards from that statement to a scene statement, recording the path it took.
Ren'Py then executes the scene statement and any show or hide statements
found along that path. Finally, it transfers control to the found statement.
There are a number of fairly major caveats to the warp feature. The first is that
it only examines a single path, which means that while the path may be
representative of some route of execution, it's possible that there may be a bug
along some other route. In general, the path doesn't consider game logic, so
it's also possible to have a path that isn't actually reachable. (This is only
really a problem on control-heavy games, espcially those that use a lot of
python code.
274
Renpy Programming Manual
The biggest problem, though, is that no python code is executed before the
statement that is warped to. This means that all variables will be uninitalized,
which can lead to crashes when they are used. To overcome this, one can
define a label `after_warp`, which is called after a warp but before the warped-
to statement executes. The code reached by this label can set up variables in
the program, and then return to the preview.
When using renpy.sh or renpy.py from the SDK to run Ren'Py, you will also
need to give the --game option. For example:
./renpy.sh --game ./the_question/game/ --warp script.rpy:98
275
Renpy Programming Manual
NVL Mode
NVL mode is a mode in which Ren'Py shows more than one line of dialogue
on the screen at once. This is used to better emulate the Japanese visual novel
format, whereas the default settings of Ren'Py emulate the Japanese adventure
format.
To use NVL-mode, one must declare Characters with a kind of `nvl`, or with a
kind that has a kind of `nvl`. For example:
nvl clear
The nvl show transition statement causes a transition to occur from the
previous screen to a screen with the buffer shown. The nvl hide transition
statement causes a transition to occur from a screen with the buffer shown to a
screen without the buffer shown.
As nvl-mode menus are shown without being added to the buffer, we suggest
clearing the buffer (using nvl clear) immediately after each menu.
276
Renpy Programming Manual
Functions
Calling this function erases the bottom line on the NVL-mode screen. If there
are no lines on the NVL-mode screen, does nothing. This can be used to
replace the bottom line with something else, or to re-show it with different
text.
Variables
Variable: config.nvl_page_ctc = None
277
Renpy Programming Manual
If not None, this is a value that all of the styles used in nvl_mode are indexed
by. For example, if nvl_variant is set to "foo", then style.nvl_window["foo"]
will be used instead of style.nvl_window.
278
Renpy Programming Manual
Voice Support
Ren'Py includes support for adding voice acting to a game. This is done
through two additional statements.
The voice "filename" statement plays the voice file given in filename.
The voice sustain statement continues playing the previous voice file.
A voice file is played at the start of the first interaction following a voice
statement. It is terminated at the start of the next interaction, unless a voice
sustain statement is given that continues playing it.
voice "eileen1.ogg"
e "I'm now saying something."
voice "eileen2.ogg"
e "Now I'm saying something else..."
voice sustain
e "And I'll keep saying it!"
Rendering Model
There are three main entities in the Ren'Py rendering model: the current scene
list, the old scene list, and the screen. The first two need a bit of explanation,
but the screen is just the thing rendered on the user's monitor.
279
Renpy Programming Manual
Interactions
Throughout this document, we'll refer to "interactions" with the user. An
interaction is any contiguous time period, including of length zero, in which
we either show something to the user, wait for and get the user's input, or
both. Thus renpy.pause(0) causes a zero-length interaction in which we only
show something to the user, while a say statement (a line of dialogue) starts an
interaction that starts with drawing the dialogue to the screen and continues
until the user clicks his mouse, which is potentially forever.
Scene Lists
Scene lists are data structures with all of the information necessary to draw a
scene to the screen. In particular, they have layers, each of which has an
ordered list of images to display. There can be any number of layers, but by
default there are two layers: the master layer and the transient layer.
Master Layer
The master layer contains all of the images which typically span multiple
interactions. The background image and character graphics will go on the
master layer, for example.
Transient Layer
The transient layer contains images which span only a single interaction with
the user. The most common thing on the transient layer is rendered dialogue
and narration.
Ordering
For each layer, the images on it have a z-ordering. The user can explicitly
specify the z-ordering of images, but more commonly they just get the
implicit z-ordering of incrementing the z-order for every new image placed on
the layer.
Drawing
Drawing to the screen is performed during an interaction with the user, and
only then.
280
Renpy Programming Manual
Once an interaction is finished, the current scene list is copied to the old scene
list.
The scene statement (if used to specify an image) and show statement both
(by default) place images on the master layer of the current scene list, but do
not trigger an interaction. Thus you can think of them as queuing up images to
display.
with
with None
The with statement when given the argument of None is a special case. It does
not cause an interaction, neither does it specify a transition. It merely copies
the current scene list onto the old scene list and returns. (This can be used to
transition from things that were never drawn into the screen.)
with clause
is equivalent to:
with None
statement args
with transition
281
Renpy Programming Manual
say
The say statement causes an interaction which last until the user terminates it
(with the keyboard or mouse), except if auto-reading is enabled, in which case
the interaction lasts for the auto-read duration. In particular, anything which
was shown prior to a say statement will be displayed at the start of the say
statement.
282
Renpy Programming Manual
User-Defined Statements
User-defined statements allow you to add your own statements to Ren'Py.
This makes it possible to add things that are not supported by the current
syntax of Ren'Py. User-defined statements are currently limited to a single
line, and may not contain blocks.
name is either a space-separated list of names that begin the statement, or the
empty string to define a new default statement (the default statement will
replace the say statement).
parse is a function that takes a lexer object. This function should parse the
statement, and return an object. This object is passed as an argument to all the
other functions. The lexer argument has the following methods:
283
Renpy Programming Manual
predict is a function that is called to predict the images used by the statement.
It is passed a single object, the argument returned from parse. It should return
a list of displayables used by the statement.
lint is called to check the statement. It is passed a single object, the argument
returned from parse. It should call renpy.error to report errors.
next is called to determine the next statement. It is passed a single object, the
argument returned from parse. It should either return a label, or return None if
execution should continue to the next statement.
Checks the text tags in s for correctness. Returns an error string if there is an
error, or None if there is no error.
Example
The creates a new statement "line" that allows lines of text to be specified
without quotes.
python early:
def parse_smartline(lex):
who = lex.simple_expression()
what = lex.rest()
return (who, what)
def execute_smartline(o):
who, what = o
renpy.say(who, what)
def lint_smartline(o):
who, what = o
try:
eval(who)
except:
renpy.error("Character not defined: %s" % who)
tte = renpy.lint.check_text_tags(what)
if tte:
renpy.error(tte)
284
Renpy Programming Manual
renpy.statements.register("l", parse=parse_smartline,
execute=execute_smartline, lint=lint_smartline)
285
Renpy Programming Manual
Environment Variables
The following environment variables control the behavior of Ren'Py:
RENPY_SCALE_FACTOR
If set, this is parsed as a floating point number, and the display screen is
scaled by that amount. For example, if RENPY_SCALE_FACTOR is
set to "0.5", everything is half normal size.
RENPY_SCALE_FAST
If set and Ren'Py starts scaling the display screen, the display screen
will use nearest-neighbor filtering rather than slower but higher-quality
bilinear filtering. It should generally be unnecessary to set this.
RENPY_DISABLE_JOYSTICK
If set, joystick detection is disabled. Use this if a faulty joystick is
causing Ren'Py to advance when not desired.
RENPY_DISABLE_FULLSCREEN
If set, Ren'Py will refuse to go into fullscreen mode.
RENPY_DISABLE_SOUND
This prevents sound playback from occuring. If this variable contains
"pss", sound playback will be disabled. If it contains "mixer", volume
control will be disabled. A value of "pss,mixer" will disable both.
RENPY_SOUND_BUFSIZE
This controls the sound buffer size. Values larger than the default
(2048) can prevent sound from skipping, at the cost of a larger delay
from when a sound is invoked to when it is played.
RENPY_NOMIXER
If set, prevents Ren'Py from trying to control the system audio mixer.
RENPY_EDITOR
The default value of config.editor.
RENPY_EDITOR_FILE_SEPARATOR
The default value of config.editor_file_separator.
RENPY_EDITOR_TRANSIENT
The default value of config.editor_transient.
RENPY_SCREENSHOT_PATTERN
A pattern used to create screenshot filenames. It should contain a
single %d substitution in it. For example, setting this to
"screenshot%04d.jpg" will cause Ren'Py to write out jpeg screenshots
rather than the usual pngs.
RENPY_LESS_MEMORY
This causes Ren'Py to reduce its memory usage, in exchange for
reductions in speed.
RENPY_LESS_UPDATES
This causes Ren'Py to reduce the number of screen updates that occur.
286
Renpy Programming Manual
RENPY_LESS_MOUSE
This causes Ren'Py to disable the mouse at all times.
RENPY_BASE
This environment variable is exported by Ren'Py to processes run by it.
It contains the full path to the directory containing renpy.exe, renpy.sh,
or renpy.app.
As Ren'Py uses SDL, its behavior can also be controlled by the SDL
environment variables.
At startup, Ren'Py will look in the Ren'Py directory (the one containing
renpy.exe or renpy.py) for the file "environment.txt". If it exists, it will be
evaluated as a python file, and the values defined in that file will be used as
the default values of environment variables. (new in 6.9.0)
287
Renpy Programming Manual
Function Index
Note that due to a limitation of mediawiki, underscores are replaced by spaces
on this page.
Alpha
anim.Blink
anim.Edge
anim.Filmstrip
anim.SMAnimation
anim.State
anim.TransitionAnimation
Animation
At
Bar
Button
Character
Character.copy
color
ComposeTransition
ConditionSwitch
CropMove
define.move transitions
Dissolve
DynamicCharacter
DynamicDisplayable
FactorZoom
Fade
Fixed
Frame
HBox
im.Alpha
im.AlphaMask
im.Composite
im.Crop
im.FactorScale
im.Flip
im.Grayscale
im.Image
im.Map
im.matrix
im.matrix.brightness
im.matrix.contrast
288
Renpy Programming Manual
im.matrix.desaturate
im.matrix.hue
im.matrix.identity
im.matrix.invert
im.matrix.opacity
im.matrix.saturation
im.matrix.tint
im.MatrixColor
im.ramp
im.Recolor
im.Rotozoom
im.Scale
im.Sepia
im.Tile
im.Twocolor
Image
ImageDissolve
ImageReference
layout.button menu
layout.classic joystick preferences
layout.classic load save
layout.classic main menu
layout.classic navigation
layout.classic preferences
layout.classic yesno prompt
layout.compat
layout.defaults
layout.grouped main menu
layout.grouped navigation
layout.imagemap load save
layout.imagemap main menu
layout.imagemap navigation
layout.imagemap preferences
layout.imagemap yesno prompt
layout.joystick preferences
layout.navigation
layout.one column preferences
layout.provides
layout.scrolling load save
layout.two column preferences
layout.yesno prompt
LiveComposite
Motion
Move
289
Renpy Programming Manual
MoveTransition
Movie
MultipleTransition
Null
nvl erase
Pan
ParameterizedText
Particles
Pause
Pixellate
Position
renpy.block rollback
renpy.cache pin
renpy.cache unpin
renpy.call in new context
renpy.can load
renpy.checkpoint
renpy.choice for skipping
renpy.clear game runtime
renpy.context
renpy.context nesting level
renpy.copy images
renpy.count displayables in layer
renpy.current interact type
renpy.curried call in new context
renpy.curry
renpy.display menu
renpy.display say
renpy.dynamic
renpy.easy displayable
renpy.exists
renpy.file
renpy.free memory
renpy.full restart
renpy.game menu
renpy.get all labels
renpy.get at list
renpy.get filename line
renpy.get game runtime
renpy.get placement
renpy.get reshow say
renpy.get roll forward
renpy.get transition
renpy.has label
290
Renpy Programming Manual
renpy.hide
renpy.image
renpy.imagemap
renpy.input
renpy.invoke in new context
renpy.in rollback
renpy.jump
renpy.jump out of context
renpy.last interact type
renpy.layer at list
renpy.list saved games
renpy.load
renpy.loadable
renpy.load module
renpy.log
renpy.movie cutscene
renpy.movie start displayable
renpy.movie stop
renpy.music.get playing
renpy.music.play
renpy.music.queue
renpy.music.register channel
renpy.music.set mixer
renpy.music.set music
renpy.music.set pan
renpy.music.set queue empty callback
renpy.music.set volume
renpy.music.stop
renpy.partial
renpy.pause
renpy.play
renpy.pop return
renpy.predict
renpy.predict display say
renpy.quit
renpy.random.choice
renpy.random.randint
renpy.random.random
renpy.redraw
renpy.register bmfont
renpy.register mudgefont
renpy.register sfont
renpy.rename save
renpy.render
291
Renpy Programming Manual
renpy.Render (constructor)
renpy.reshow say
renpy.restart interaction
renpy.rollback
renpy.roll forward info
renpy.save
renpy.scan saved game
renpy.scene
renpy.seen audio
renpy.seen image
renpy.seen label
renpy.show
renpy.showing
renpy.shown window
renpy.show display say
renpy.sound.is playing
renpy.sound.play
renpy.sound.queue
renpy.sound.set mixer
renpy.sound.set pan
renpy.sound.set volume
renpy.sound.stop
renpy.take screenshot
renpy.timeout
renpy.transition
renpy.unlink save
renpy.watch
renpy.with statement
Revolve
RotoZoom
ShowingSwitch
SizeZoom
SnowBlossom
Solid
SplineMotion
Style
Style.clear
style.create
style.rebuild
Style.set parent
Style.take
Text
theme.ancient
theme.image buttons
292
Renpy Programming Manual
theme.image labels
theme.outline
theme.roundrect
theme.roundrect red
Transform
ui.add
ui.adjustment
ui.at
ui.autobar
ui.bar
ui.button
ui.callsinnewcontext
ui.clear
ui.close
ui.detached
ui.fixed
ui.frame
ui.gamemenus
ui.grid
ui.hbox
ui.image
ui.imagebutton
ui.imagemap
ui.input
ui.interact
ui.jumps
ui.jumpsoutofcontext
ui.keymap
ui.layer
ui.menu
ui.null
ui.pausebehavior
ui.remove
ui.returns
ui.saybehavior
ui.side
ui.sizer
ui.soundstopbehavior
ui.tag
ui.text
ui.textbutton
ui.timer
ui.transform
ui.vbox
293
Renpy Programming Manual
ui.viewport
ui.window
VBox
Viewport
Window
Zoom
294