You are on page 1of 226

Welcome to Ren'Py's documentation!

We're in the process of rewriting Ren'Py's documentation. While what we have here is the most
up-to-date documentation, it's also very incomplete. To find out more about Ren'Py, please
visit the Ren'Py home page:

http://www.renpy.org/

Much of Ren'Py is only documented in the older documentation, which is stored in the Ren'Py
Wiki:

http://www.renpy.org/wiki/

Getting Started

Quickstart
Welcome to the Ren'Py quickstart manual. The purpose of this manual is to demonstrate how
you can make a Ren'Py game from scratch, in a few easy steps. We'll do this by showing how
to make a simple game, The Question, from scratch. This manual contains a number of
examples, which are included as part of the demo game.

The Ren'Py Launcher

Before you begin making a game, you should first take some time to learn how the Ren'Py
launcher works. The launcher lets you create, manage, edit, and run Ren'Py projects.
Getting Started. To get started you'll want to download Ren'Py.
Once you've downloaded Ren'Py, you'll want to extract it. This can generally be done by right-
clicking on the package file, and picking "Extract" if that's an option, or "Open" if it's not. Follow
the prompts, and you'll have a working copy of Ren'Py.

Note
Please be sure you've extracted Ren'Py to its own directory or folder on disk. If you try to run it from
inside a ZIP file, it won't work properly.

Once you've extracted Ren'Py, you'll need to run it.

On Windows, run the renpyor renpy.exeprogram.


On Mac OS X, run the renpyapplication.
On Linux, run the renpy.shscript.

After running this, the Ren'Py launcher should run.

Choosing and Launching 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".
Creating a new Project. 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..."

"Me" "Um... will you..."


"Me" "Will you be my artist for a visual novel?"

"Silence."
"She is shocked, and then..."

"Sylvie" "Sure, but what is a \"visual novel?\""

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.
This example shows some of the commonly-used Ren'Py statements.
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.
When strings contain double-quote characters, those characters need to be preceded by a
backslash. This is done in the last line of our example.
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.

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..."

m "Um... will you..."


m "Will you be my artist for a visual novel?"

"Silence."
"She is shocked, and then..."

s "Sure, but what is a \"visual novel?\""

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.

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"

image sylvie smile = "sylvie_smile.png"


image sylvie surprised = "sylvie_surprised.png"

define s = Character('Sylvie', color="#c8ffc8")


define m = Character('Me', color="#c8c8ff")

label start:
scene bg meadow
show sylvie smile

"I'll ask her..."

m "Um... will you..."


m "Will you be my artist for a visual novel?"

show sylvie surprised

"Silence."
"She is shocked, and then..."

show sylvie smile


s "Sure, but what is a \"visual novel?\""

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.
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.

label leaving:

s "I'll get right on it!"

hide sylvie

"..."

m "That wasn't what I meant!"

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.

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

s "Oh, hi, do we walk home together?"


m "Yes..."
"I said and my voice was already shaking."

scene bg meadow
with fade

"We reached the meadows just outside our hometown."


"Autumn was so beautiful here."
"When we were children, we often played here."
m "Hey... ummm..."

show sylvie smile


with dissolve

"She turned to me and smiled."


"I'll ask her..."
m "Ummm... will you..."
m "Will you be my artist for a visual novel?"

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 fadewhich fades the
screen to black, and then fades in the new screen.
When a transition is placed after multiple scene, show, or hide statements, it applies to them
all at once. If you were to write:

scene bg meadow
show sylvie smile
with dissolve

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
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

To do this repositioning, add an at-clause to a show statement. The at clause takes a position,
and shows the image at that position. Ren'Py includes several pre-defined positions: leftfor
the right side of the screen, rightfor the right side, centerfor centered horizontally (the
default), and truecenterfor centered horizontally and vertically.
A user can define their own positions, and event complicated moves, but that's outside of the
scope of this quickstart.

Music and Sound

Most games play music in the background. In Ren'Py, music files automatically loop until they
are stopped by the user. Music is played with the play music statement.

play music "illurock.ogg"

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

Music can be stopped with the stop music statement, which can also optionally take a fadeout
clause.

stop music

Sound effects can be played with the play sound statement:

play sound "effect.ogg"

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.

Ending the Game

You can end the game by running the return statement, without having called anything. Before
doing this, it's best to put something in the game that indicates that the game is ending, and
perhaps giving the user an ending number or ending name.

".:. Good Ending."

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.

Menus, Labels, and Jumps

The menu statement lets you present a choice to the user:

s "Sure, but what's a \"visual novel?\""

menu:
"It's a story with pictures.":
jump vn

"It's a hentai game.":


jump hentai
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
with dissolve

"--- years later ---"

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 and If Statements

While simple (and even fairly complex) games can be made using only using menus and jump
statements, after a point it becomes necessary to store the user's choices in variables, and
access them again later. This is what Ren'Py's python support is for.
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

m "Why it's a game with lots of sex."


s "You mean, like a boy's love game?"
s "I've always wanted to make one of those."
s "I'll get right on it!"

jump marry
jump marry

And check it later:

"And so, we became a visual novel creating team."


"We made games and had a lot of fun making them."

if bl_game:
"Well, apart from that boy's love game she insisted on making."

"And one day..."

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.

Releasing Your Game

Once you've made a game, there are a number of things you should do before releasing it:

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.
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. Consider asking friends to help beta-test your game, as often a tester
can find problems you can't.
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!
Please also add your released game to our games database, so we can keep track of the
Ren'Py games being made.

Script of The Question

You can view the full script of ''The Question'' here.

Where do we go from here?

This Quickstart has barely scratched the surface of what Ren'Py is capable of. For simplicity's
sake, we've omitted many features Ren'Py supports. To get a feel for what Ren'Py is capable
of, we suggest playing through the demo, and having Eileen demonstrate these features to
you.

You may also want to read the rest of this (complex) manual, as it's the definitive guide to
Ren'Py.
On the Ren'Py website, there's the a FAQ giving answers to common questions, and a
Cookbook giving useful code smippets. If you have questions, we suggest asking them at the
Lemma Soft Forums, the official forum of Ren'Py. This is the central hub of the Ren'Py
community, and we welcome new users, and the questions they bring.
Thank you for choosing the Ren'Py visual novel engine. We look forward to seeing what you
can create with it!

The Ren'Py Language

Language Basics

Before we can describe the Ren'Py language, we must first describe the structure of a Ren'Py
script. This includes how a files are broken into blocks made up of lines, and how those lines
are broken into the elements that make up statements.

Files

The script of a Ren'Py game is made up of all the files found under the game directory ending
with the .rpy extension. Ren'Py will consider each of these files (in unicode order), and will use
the contents of the files as the script.
Generally, there's no difference between a script broken into multiple files, and a script that
consists of one big file. Control can be transferred between files by jumping to or calling a
label in another file. This makes the division of a script up into files a matter of personal style -
some game-makers prefer to have small files (like one per event, or one per day), while others
prefer to have one big script.
To speed up loading time, Ren'Py will compile the .rpyfiles into .rpyc files when it starts up.
When a .rpyfile is changed, the .rpycfile will be updated when Ren'Py starts up. However, if a
.rpyc file exists without a corresponding .rpyfile, the .rpycfile will be used. This can lead to
problems if a .rpyfile is deleted without deleting the .rpyc file.

Comments

A Ren'Py script file may contain comments. A comment begins with a hash mark ('#'), and
ends at the end of the line containing the comment. As an exception, a comment may not be
part of a string.

# This is a comment.
show black # this is also a comment.

"# This isn't a comment, since it's part of a string."

Ren'Py ignores comments, so the script is treated like the comment wasn't there.

Logical Lines

A script file is broken up into logical lines. A logical line always begins at the start of a line in
the file. A logical line ends at the end of a line, unless:

The last character on the line is a backslash ('\').


The line contains an open parenthesis character ('(', '{', or '['), that hasn't been matched
by the cooresponding close parenthesis character (')', '}', or ']', respectively).
The end of the line occurs during a string.

Once a logical line ends, the next logical line begins at the start of the next line.
Most statements in the Ren'Py language consist of a single logical line, while some statements
consist of multiple lines.

"This is one logical line"

"Since this line contains a string, it continues


even when the line ends."

$ a = [ "Because of parenthesis, this line also",


"spans more than one line." ]

Empty logical lines are ignored.

Indentation and Blocks

Indentation is the name we give to the space at the start of each logical line that's used to line
up Ren'Py statements. In Ren'Py, indentation must consist only of spaces.

Indentation is used to group statements into blocks. A block is a group of lines, and often a
group of statements. The rules for dividing a file into blocks are:

A block is open at the start of a file.


A new block is started whenever a logical line is indented past the previous logical line.
All logical lines inside a block must have the same indentation.
A block ends when a logical line is encountered with less indentation than the lines in the
block.

Indentation is very important to Ren'Py, and cause syntax or logical errors when it's incorrect.
At the same time, the use of indentation to convey block structure provides us a way of
indicating that structure without overwhelming the script text.

"This statement, and the if statement that follows, is part of a block."

if True:

"But this statement is part of a new block."

"This is also part of that new block."


"This is part of the first block, again."

Elements of Statements

Ren'Py statements are made of a few basic parts.

Keyword
A keyword is a word that must literally appear in the source code. They're used to
introduce statements and properties.
Names begining with a single underscore (_) are reserved for Ren'Py internal use, unless
otherwise documented. When a name begins with __ but doesn't end with __, it is changed
to a file-specfic version of that name.
Name
A name begins with a letter or underscore, which is followed by zero or more letters,
numbers, and underscores. For our purpose, unicode characters between U+00a0 and
U+fffd are considered to be letters.
Image Name
An image name consists of one or more names, separated by spaces. The name ends at
the end of the statement, or when a keyword is encountered.
An image name consists of one or more names, separated by spaces. The first component
of the image name is called the image tag. The second and later components of the name
are the image attributes.
For example, take the image name mary beach night happy. The image tag is mary, while
the image attributes are mary, beach, and night.
String
A string begins with a quote character (one of ", ', or `), contains some sequence of
characters, and ends with the same quote character.
The backslash character () is used to escape quotes, special characters such as % (written
as %) and { (written as {). It's also used to include newlines, using the n sequence.
Inside a Ren'Py string, consecutive whitespace is compressed into a single whitespace
character, unless a space is preceded by a backslash.

'Strings can\'t contain their delimiter, unless you escape it.'

Simple Expression
A simple expression is a Python expression, used to include Python in some parts of the
Ren'Py script. A simple expression begins with:

A name.
A string.
A number.
Any python expression, in parenthesis.
This can be followed by any number of:

A dot followed by a name.


A parenthesised python expression.
As an example, 3, (3 + 4), foo.bar, and foo(42)are all simple expressions. But 3 + 4is
not, as the expression ends at the end of a string.
At List
An at list is a list of simple expressions, separated by commas.
Python Expression
A python expression is an arbitrary python expression, that may not include a colon. These
are used to express the conditions in the if and while statements.

Common Statement Syntax

Most Ren'Py statements share a common syntax. With the exception of the say statement, they
begin with a keyword that introduces the statement. This keyword is followed by a parameter,
if the statement takes one.
The parameter is then followed by one or more properties. Properties may be supplied in any
order, provided each property is only supplied once. A property starts off with a keyword. For
most properties, the property name is followed by one of the syntax elements given above.
If the statement takes a block, the line ends with a colon (:). Otherwise, the line just ends.

Python Expression Syntax

Note
It may not be necessary to read this section thoroughly right now. Instead, skip ahead, and if you
find yourself unable to figure out an example, or want to figure out how things actually work, you
can go back and review this.

Many portions of Ren'Py take python expressions. For example, defining a new Character
involves a call to the Character function. While Python expressions are very powerful, only a
fraction of that power is necessary to write a basic Ren'Py game.
Here's a synopsis of python expressions.

Integer
An integer is a number without a decimal point. 3and 42are integers.
Float
A float (short for floating-point number) is a number with a decimal point. .5, 7., and 9.0
are all floats.
String
Python strings begin with " or ', and end with the same character. \ is used to escape the
end character, and to introduce special characters like newlines (\n). Unlike Ren'Py strings,
python strings can't span lines.
True, False, None
There are three special values. Trueis a true value, Falseis a false value. Nonerepresents
the absence of a value. For example,
Tuple
Tuples are used to represent containers where the number of items is important. For
example, one might use a 2-tuple (also called a pair) to represent width and height, or a 4-
tuple (x, y, width, height) to represent a rectangle.
Tuples begin with a left-parenthesis (, consist of zero or more comma-separated python
expressions, and end with a right-parenthesis ). As a special case, the one-item tuple must
have a parenthesis following the item. For example:

()
(1,)
(1, "#555")
(32, 24, 200, 100)
List
Lists are used to represent containers where the number of items may vary. A list begins
with a [, contains a comma-separated list of expressions, and ends with ]. For example:

[]
[1]
[ 1, 2 ]
[ 1, 2, 3 ]

Variable
Python expressions can use variables, that store values defined using the define statement
or python statements. A variable begins with a letter or underscore, and then has zero or
more letters, numbers, or underscores. For example:

name
love_love_points
trebuchet2_range

Variables beginning with _ are reserved for Ren'Py's use, and shouldn't be used by user
code.
Field Access
Python modules and objects have fields, which can be accessed with by following an
expression (usually a variable) with a dot and the field name. For example:

config.screen_width

Consists of a variable (config) followed by a field access (screen_width).


Call
Python expressions can call a function which returns a value. They begin with an
expression (usually a variable), followed by a left-parenthesis, a comma-separated list of
arguments, and a right-parenthesis. The argument list begins with the position arguments,
which are python expressions. These are followed by keyword arguments, which consist of
the argument name, and equals sign, and an expression. In the example example:

Character("Eileen", type=adv, color="#0f0")

we call the Character function. It's given one positional argument, the string "Eileen". It's
given two keyword argument: typewith the value of the advvariable, and colorwith a
string value of "#0f0".
Constructors are a type of function which returns a new object, and are called the same
way.

When reading this documentation, you might see a function signature like:

Sample(name, delay, position=(0, 0), **properties)


A sample function that doesn't actually exist in Ren'Py, but is used only in documentation.

This function:

Has the name "Sample"


Has two positional parameters, a name and a delay. In a real function, the types of these
parameters would be made clear from the documentation.
Has one keyword argument, position, which has a default value of (0, 0).
Since the functions ends with **properties, it means that it can take style properties as
additional keyword arguments. Other special entries are *args, which means that it takes an
arbitrary number of postional parameters, and **kwargs, which means that the keyword
arguments are described in the documentation.
Python is a lot more powerful than we have space for in this manual. To learn Python in more
detail, we recommend starting with the Python tutorial, which is available from python.org.
While we don't think a deep knowledge of Python is necessary to work with Ren'Py, learning
about python expressions is helpful.

Dialogue and Narration

Text is fundamental to visual novels, and generally quite important to storytelling-based


games. This text may consist of dialogue labeled with the character that is saying it, and
narration, which does not have a speaker. (For convenience, we will lump both dialogue and
narration together as dialogue, except where the differences are important.) It's also
important that the user be able to customize the look of dialogue to suit their game.
In Ren'Py, most dialogue is written using say statements. The look of dialogue may be
customized on a per-character basis by using Character objects.

Say Statement

The say statement is used for dialogue and narration. Since it's almost always the most
frequently used statement in Ren'Py scripts, the say statement has a syntax that minimizes the
overhead in writing it. Some example say statements are:

"This is narration."

"Eileen" "This is dialogue, with an explicit character name."

e "This is dialogue, using a character object instead."

The first form of the say statement consists of a string by itself. This form is used for narration,
with the narration being the contents of the string.
The second form consists of two strings. The first string is the name of the character who is
speaking, and the second is the dialogue being spoken.

The final form is consists of a simple expression followed by a string. The simple expression
should evaluate to either a string giving a character name, or a Character object. In the latter
case, the character object is used to control how the dialogue is shown.
Although the precise details of what a say statement does is controlled by the character object
used, the usual effect of a say statement is to display dialogue on the screen until the user
clicks to dismiss it, then to remove that dialogue on the screen.
Certain characters have special meaning to Ren'Py, and so can't be used in dialogue strings.
The {character begins a text tag, and the [character begins a substitution. To use them in
dialogue, double them. It may also be necessary to precede a quote with a backslash to
prevent it from closing the string. For example:

"I walked past a sign saying, \"Let's give it 100%!\""

Defining Character Objects


By creating a Character object and using it in a say statement, you can customize the look
(and to some extent, the behavior) of dialogue. Characters are created by using the define
statement to assign a Character to a variable. For example:

define e = Character("Eileen",
who_color="#c8ffc8")

Once this is done, the character can be used in a say statement:

e "Hello, world."

Character is a python function, that takes a large number of keyword arguments. These
keyword arguments control the behavior of the character.

Character(name, kind=adv, **args)


Creates and returns a Character object, which controls the look and feel of dialogue and
narration.

name
If a string, the name of the character for dialogue. When nameis None, display of the
name is omitted, as for narration.
kind
The Character to base this Character off of. When used, the default value of any
argument not supplied to this Character is the value of that argument supplied to
kind. This can be used to define a template character, and then copy that character
with changes.

Linked Image An image tag may be associated with a Character. This allows a say
statement involving this character to display an image with the tag, and also allows Ren'Py
to automatically select a side image to show when this character speaks.

image
A string giving the image tag that is linked with this character.

Prefixes and Suffixes. These allow a prefix and suffix to be applied to the name of the
character, and to the text being shown. This can be used, for example, to add quotes
before and after each line of dialogue.

what_prefix
A string that is prepended to the dialogue being spoken before it is shown.
what_suffix
A string that is appended to the dialogue being spoken before it is shown.
who_prefix
A string that is prepended to the name of the character before it is shown.
who_suffix
A string that is appended to the name of the character before it is shown.

Changing Name Display. These options help to control the display of the name.

dynamic
If true, then nameshould be a string containing a python expression. That string will be
evaluated before each line of dialogue, and the result used as the name of the
character.
Controlling Interactions. These options control if the dialogue is displayed, if an
interaction occurs, and the mode that is entered upon display.

condition
If given, this should be a string containing a python expression. If the expression is
false, the dialogue does not occur, as if the say statement did not happen.
interact
If true, the default, an interaction occurs whenever the dialogue is shown. If false, an
interaction will not occur, and additional elements can be added to the screen.
mode
A string giving the mode to enter when this character speaks. See the section on
modes for more details.
callback
A function that is called when events occur while the character is speaking. See the
section on character callbacks fore more information.

Click-to-continue. A click-to-continue indicator is displayed once all the text has finished
displaying, to prompt the user to advance.

ctc
A Displayable to use as the click-to-continue indicator, unless a more specific
indicator is used.
ctc_pause
A Displayable to use a the click-to-continue indicator when the display of text is
paused by the {p} or {w} text tags.
ctc_timedpause
A Displayable to use a the click-to-continue indicator when the display of text is
paused by the {p=} or {w=} text tags. When None, this takes its default from
ctc_pause, use Null()when you want a ctc_pause but no ctc_timedpause.
ctc_position
Controls the location of the click-to-continue indicator. If "nestled", the indicator is
displayed as part of the text being shown, immediately after the last character. If
"fixed", the indicator is added to the screen, and its position is controlled by the
position style properties.

Screens. The display of dialogue uses a screen. These arguments allow you to select that
screen, and to provide arguments to it.

screen
The name of the screen that is used to display the dialogue.

Keyword arguments beginning with show_have the prefix stripped off, and are passed to
the screen as arguments. For example, the value of show_side_imagewill become the
value of the side_imagevariable in the screen.
Some useful show_variables implemented by the default screens are:

show_side_image
When given a Displayable, shows that displayable when the dialogue is shown. The
position of that displayable is controlled by its position properties. This is often used to
show an image of the speaking character to the side of the dialogue.
show_two_window
If true, restructures the layout so that the name of the character is placed in one
window, and the dialogue text in a second window.
Styling Text and Windows. Keyword arguments beginning with who_, what_, and
window_`have their prefix stripped, and are used to style the character name, the spoken
text, and the window containing both, respectively.
For example, if a character is given the keyword argument who_color="#c8ffc8", the color
of the character's name is changed, in this case to green. window_background="frame.png"
sets the background of the window containing this character's dialogue.
The style applied to the character name, spoken text, and window can also be set this way,
using the who_style, what_style, and window_stylearguments, respectively.

Say with Image Attributes

When a character is defined with an associated image tag, say statement involving that
character may have image attributes placed between the character name and the second
string.
In this form, if an image with the given tag is showing, Ren'Py will issue a show command
involving the character tag and the attributes. If the image is not shown, Ren'Py will store the
attributes for use by side images, but will not show an image.

For example, the code:

define e = Character("Eileen", image="eileen")

label start:

show eileen mad


e "I'm a little upset at you."

e happy "But it's just a passing thing."

is equivalent to:

define e = Character("Eileen")

label start:

show eileen mad


e "I'm a little upset at you."

show eileen happy


e "But it's just a passing thing."

To cause a transition to occur whenever the images are changed in this way, set
config.say_attribute_transitionto a transition.

Example Characters

Here are a few example characters:

# A character that has its dialogue enclosed in parenthesis.


define e = Character("Eileen", what_prefix='"', what_suffix='"')

# A character that pulls its name from a variable.


define p = Character("player_name", dynamic=True)

Special Characters
A few character names are defined by default, and are used automatically in certain
situations. Intentionally redefining these characters can change the behavior of Ren'Py, but
accidentally using them can be a problem.

adv
The default kind of character used by Character. This sets up a character such that one
line is displayed on the screen at a time.
nvl
A kind of Character that causes dialogue to be displayed in NVL-mode, with multiple lines
of text on the screen at once.
narrator
The character that's used to display narration, by say statements without a character
name.
name_only
A character that is used to display dialogue in which the character name is given as a
string. This character is copied to a new character with the given name, and then that new
character is used to display the dialogue.

Displaying Images

The defining aspect of a visual novel, lending its name to the form, are the visuals. Ren'Py
contains four statements that control the display of images, and a model that determines the
order in which the images are displayed. This makes it convenient to display images in a
manner that is suitable for use in visual novels and other storytelling games.
The four statements that work with images are:

image- defines a new image.


show- shows an image on a layer.
scene- clears a layer, and optionally shows an image on that layer.
hide- removes an image from a layer.

As abrupt changes of image can be disconcerting to the user, Ren'Py has the withstatement,
which allows effects to be applied when the scene is changed.

Concepts

Image

An image is something that can be show to the screen using the show statement. An image
consists of a name and a displayable. When the image is shown on a layer, the displayable
associated with it is displayed on that layer.
An image name consists of one or more names, separated by spaces. The first component of
the image name is called the image tag. The second and later components of the name are
the image attributes.

For example, take the image name mary beach night happy. The image tag is mary, while the
image attributes are beach, night, and happy.
A displayable is something that can be shown on the screen. The most common thing to show
is a static image, which can be specified by giving the filename of the image, as a string. In the
example above, we might use "mary_beach_night_happy.png"as the filename. However, an
image may refer to any displayable Ren'Py supports, not just static images. Thus, the same
statements that are used to display images can also be used for animations, solid colors, and
the other types of displayables.

Layer

A layer is a list of displayables that are shown on the screen. Ren'Py supports multiple layers,
including user-defined layers. The order of the layers is fixed within a game (controlled by the
config.layersvariable), while the order of displayables within a layer is controlled by the
order in which the scene and show statements are called, and the properties given to those
statements.
The following layers are defined as part of Ren'Py:

master
This is the default layer that is used by the scene, show, and hide statements. It's generally
used for backgrounds and character sprites.
transient
The default layer used by ui functions. This layer is cleared at the end of each interaction.
screens
This layer is used by the screen system.
overlay
The default layer used when a ui function is called from within an overlay function. This
layer is cleared when an interaction is restarted.

Additional layers can be defined by updating config.layers, and the various other layer-
related config variables. Using renpy.layer_at_list(), one or more transforms can be
applied to a layer.

Image Statement

An image statement is used to define an image. An image statement consists of a single


logical line beginning with the keyword image, followed by an image name, an equals sign (=),
and a displayable. For example:

image eileen happy = "eileen_happy.png"


image black = "#000"
image bg tiled = LiveTile("tile.jpg")

image eileen happy question = VBox(


"question.png",
"eileen_happy.png",
)

The image statement must be run at init-time, before game code runs. When not contained
inside an init block, image statements are run at init-time, as if they were placed inside an init
block of priority 0.
See also the ATL variant of the image statement.

Show Statement

The show statement is used to display an image on a layer. A show statement consists of a
single logical line beginning with the keyword show, followed by an image name, followed by
zero or more properties.
If the show statement is given the exact name of an existing image, that image is the one that
is shown. Otherwise, Ren'Py will attempt to find a unique image that:

Has the same tag as the one specified in the show statement.
Has all of the attributes given in the show statement.
If an image with the same tag is already showing, shares the largest number of attributes
with that image.

If a unique image cannot be found, an exception occurs.


If an image with the same image tag is already showing on the layer, the new image replaces
it. Otherwise, the image is placed above all other images in the layer. (That is, closest to the
user.) This order may be modified by the zorder and behind properties.
The show statement does not cause an interaction to occur. For the image to actually be
displayed to the user, a statement that causes an interaction (like the say, menu, pause, and
with statements) must be run.

The show statement takes the following properties:

as
The as property takes a name. This name is used in place of the image tag when the
image is shown. This allows the same image to be on the screen twice.
at
The at property takes one or more comma-separated simple expressions. Each expression
must evaluate to a transform. The transforms are applied to the image in left-to-right
order.
If no at clause is given, Ren'Py will retain any existing transform that has been applied to
the image. If no transform exists, the image will be displayed using the defaulttransform.
behind
Takes a comma-separated list of one or more names. Each name is taken as an image
tag. The image is shown behind all images with the given tags that are currently being
shown.
onlayer
Takes a name. Shows the image on the named layer.
zorder
Takes an integer. The integer specifies the relative ordering of images within a layer, with
larger numbers being closer to the user. This isn't generally used in Ren'Py code, but can
be useful when porting code from other engines.

Assuming we have the following images defined:

image mary night happy = "mary_night_happy.png"


image mary night sad = "mary_night_sad.png"
image moon = "moon.png"

Some example show statements are:

# Basic show
show mary night sad

# Since 'mary night happy' is showing, the following statement is


# equivalent to:
# show mary night happy
show mary happy

# Show an image on the right side of the screen.


show mary night happy at right

# Show the same image twice.


show mary night sad as mary2 at left

# Show an image behind another.


show moon behind mary, mary2

# Show an image on a user-defined layer.


show moon on user_layer

Show Expression. A variant of the show statement replaces the image name with the
keyword expression, followed by a simple expression. The expression must evaluate to a
displayable, and the displayable is shown on the layer. To hide the displayable, a tag must be
given with the as statement.
For example:

show expression "moon.png" as moon

Scene Statement

The scene statement removes all displayables from a layer, and then shows an image on that
layer. It consists of the keyword scene, followed by an image name, followed by zero or more
properties. The image is shown in the same way as in the show statement, and the scene
statement takes the same properties as the show statement.
The scene statement is often used to show an image on the background layer. For example:

scene bg beach

Scene Expression. Like the show statement, the scene statement can take expressions
instead of image names.
Clearing a layer. When the image name is omitted entirely, the scene statement clears all
displayables from a layer without showing another displayable.

Hide Statement

The hide statement removes an image from a layer. It consists of the keyword hide, followed
by an image name, followed by an optional property. The hide statement takes the image tag
from the image name, and then hides any image on the layer with that tag.
Hide statements are rarely necessary. If a sprite represents a character, then a hide statement
is only necessary when the character leaves the scene. When the character changes her
emotion, it is preferable to use the show statement instead, as the show statement will
automatically replace an image with the same tag.
The hide statement takes the following property:

onlayer
Takes a name. Hides the image from the named layer.

For example:

e "I'm out of here."

hide eileen
You should never write:

hide eileen
show eileen happy

Instead, just write:

show eileen happy

With Statement

The with statement is used to apply a transition effect when the scene is changed, making
showing and hiding images less abrupt. The with statement consists of the keyword with,
followed by a simple expression that evaluates either to a transition object or the special value
None.

The transition effect is applied between the contents of the screen at the end of the previous
interaction (with transient screens and displayables hiddden), and the current contents of the
scene, after the show and hide statements have executed.
The with statement causes an interaction to occur. The duration of this interaction is controlled
by the user, and the user can cause it to terminate early.
For a full list of transitions that can be used, see the chapter on transitions.

An example of the with statement is:

show bg washington
with dissolve

show eileen happy at left


show lucy mad at right
with dissolve

This causes two transitions to occur. The first with statement uses the dissolvetransition to
change the screen from what was previously shown to the washington background. (The
dissolvetransition is, by default, defined as a .5 second dissolve.)

The second transition occurs after the Eileen and Lucy images are shown. It causes a dissolve
from the scene consisting solely of the background to the scene consisting of all three images
- the result is that the two new images appear to dissolve in simultaneously.

With None

In the above example, there are two dissolves. But what if we wanted the background to
appear instantly, followed by a dissolve of the two characters? Simply omitting the first with
statement would cause all three images to dissolve in - we need a way to say that the first
should be show instantly.

The with statement changes behavior when given the special value None. The with None
statement causes an abbreviated interaction to occur, without changing what the user sees.
When the next transition occurs, it will start from the scene as it appears at the end of this
abbreviated interaction.
For example, in the code:

show bg washington
with None
show eileen happy at left
show lucy mad at right
with dissolve

Only a single transition occurs, from the washington background to the scene consisting of all
three images.

With Clause of Scene, Show, and Hide Statements

The show, scene, and hide statements can take an optional with clause, which allows a
transition to be combined with showing or hiding an image. This clause follows the statements
at the end of the same logical line. It begins with the keyword with, followed by a simple
expression.
The with clause is equivalent to preceding the line with a with Nonestatement, and following it
by a with statement containing the text of the with clause. For example:

show eileen happy at left with dissolve


show lucy mad at right with dissolve

is equivalent to:

with None
show eileen happy at left
with dissolve

with None
show lucy mad at right
with dissolve

In-Game Menus

In many visual novels, the player is asked to make choices that control the outcome of the
story. The Ren'Py language contains a menus statement that makes it easy to present choices
to the user.
Here's an example of a menu statement:

menu:
"What should I do?"

"Drink coffee.":
"I drink the coffee, and it's good to the last drop."

"Drink tea.":
$ drank_tea = True

"I drink the tea, trying not to make a political statement as I do."

"Genuflect.":
jump genuflect_ending

label after_menu:

"After having my drink, I got on with my morning."


The menu statement begins with the keyword menu. This may be followed by a label name, in
which case it's equivalent to preceding the menu with that label. For example:

menu drink_menu:
...

The menu statement is followed by an indented block. This block may contain a say statement,
and must contain at least one menu choice. If the say statement is present, it is displayed on
the screen at the same time as the menu.
Menu Choices. A menu choice is an option the user can select from the in-game menu. A
menu choice begins with a string. The string may be followed by an if-clause, which makes the
choice conditional. The menu choice ends with a colon, and must be followed by a block of
Ren'Py statements.
When the choice is selected, the block of code is run. If execution reaches the end of this block
of code, it continues with the statement after the end of the menu statement.

An if-clause consists of the keyword if, followed by a python expression. The menu choice is
only displayed if the expression is true. In the following menu:

menu:
"Go left.":
...
"Go right.":
...
"Fly above." if drank_tea:
...

The third choice will only be presented if the drank_tea variable is true.

Text, Displayables, Transforms, and Transitions

Text
Ren'Py contains several ways of displaying text. The say and menu are primarily concerned
with the display of text to the user. The user interface often contains text, displayed using the
text, textbutton, and label screen language statements. These functions, along with others,
create Text()displayables, and show them on the screen.

The Text displayable is responsible for managing the process of showing the text to the user.
The text displayable performs actions in the following order:

1. Translating text.
2. Interpolating data into the text.
3. Styling the text using styles and text tags.
4. Laying out the styled text.
5. Drawing the text to the screen.

This chapter discusses the process of text display in Ren'Py.

Escape Characters

There are three special characters that can control the way Ren'Py displays text. A creator
needs to be aware of these characters to ensure that their writing is not accidentally
misinterpreted by the engine.

(backslash)
The backslash character is used to introduce when writing a Ren'Py or Python string. Some
common escape codes are:

\" (backslash-doublequote)
Includes a doublequote in a double-quoted string.
\' (backslash-quote)
Includes a single quote in a single-quoted string.
\ (backslash-space)
Includes an additional space in a Ren'Py string. By default, Ren'Py script text collapses
adjacent whitespace into a single space character.
\n (backslash-n)
Includes a newline character in the text.
\\ (backslash-backslash)
Includes a backslash character in the text.

[ (left bracket)
The left bracket is used to introduce interpolation of a value into the text. To include a
single left bracket in your text, double it - write [[.
{ (left brace)
The left brace is used to introduce a text tag. To include a left brace in your text, double it
- write {{.

Interpolating Data

Ren'Py supports interpolating data into the text string before it is displayed. For example, if the
player's name is stored in the playernamevariable, one could write a line of dialogue like:

g "Welcome to the Nekomimi Institute, [playername]!"

Ren'Py will interpolate variables found in the global store. When using a text widget in a
screen, Ren'Py will also interpolate screen local variables. (This can be overridden by
supplying an explicit scope argument to the Text displayable.)
Ren'Py isn't limited to interpolating simple variables. It can also interpolate fields and
components of tuples. So it's possible to have code like:

g "My first name is [player.names[0]]."

It's possible to apply formatting codes when displaying numbers. This code will display a
floating point number to two decimal places:

$ percent = 100.0 * points / max_points


g "I like you [percent:.2] percent!"

Ren'Py's string interpolation is taken from the PEP 3101 string formatting syntax. Ren'Py uses
[ to introduce string formatting because { was taken by text tags.
Along with the !s and !r conversion flags supported by Python, Ren'Py supports a !q conversion
flag. The !q conversion flag ensures that text tags are properly quoted, so that displaying a
string will not introduce unwanted formatting constructs. For example:
g "Don't pull a fast one on me, [playername!q]."

Styling and Text Tags

In Ren'Py, text gains style information in two ways. The first is from the style that is applied to
the entire block of text. Please see the section about the style system for more details,
especially the section on text style properties.
The second way is through text tags. Text tags are suitable for styling a portion of text block, or
a small fraction of the text blocks in the program. If you find yourself applying the same text
tags to every line of text, consider using a style instead.
There are two text tags. Some text tags are self-closing, while others require a closing tag.
When multiple closing tags are used, they should be closed last open, first closed order -
Ren'Py will reject incorrect nesting. For example:

# This line is correct.


"Plain {b}Bold {i}Bold-Italic{/i} Bold{/b} Plain"

# This line is incorrect, and will cause an error or incorrect


# behavior.
"Plain {b}Bold {i}Bold-Italic{/b} Italic{/i} Plain"

Some text tags take an argument. In that case, the tag name is followed by an equals sign (=),
and the argument. The argument may not contain the right-brace (}) character. The meaning
of the argument varies based on the text tag.

General Text Tags

Tags that apply to all text are:

a
The anchor tag creates a hyperlink between itself and its closing tag. While the behavior
of the hyperlink is controlled by the hyperlink_functionsstyle property, the default
handler has the following behavior.

Hyperlinks are rendered using the style.hyperlink_textstyle.


If the argument begins with the text "http://", clicking on it opens the url in a web
browser. Otherwise, the argument is interpreted as a label, which is called in a new
context. This allows hyperlinks to be used to define terms.
Apart from the change in style, there is no specific behavior when a hyperlink is
hovered.

label test:

e "Why don't you visit {a=http://renpy.org}Ren'Py's home page{/a}?"

e "The {a=define_trebuchet}trebuchet{/a} is at the gates."

return

label define_trebuchet:

e "A trebuchet is a kind of siege engine."


e "It uses a lever to fling things at targets."
e "Like us!"

return
b
The bold tag renders the text between itself and its closing tag in a bold font.

"An example of {b}bold test{/b}."

color
The color text tag renders the text between itself and its closing tag in the specified color.
The color should be in #rgb, #rgba, #rrggbb, or #rrggbbaa format.

"{color=#f00}Red{/color}, {color=#00ff00}Green{color}, {color=#0000ffff}Blue{/color}"

cps
The characters per second tag sets the speed of text display, for text between the tag and
its closing tag. If the argument begins with an asterisk, it's taken as a multiplier to the
current text speed. Otherwise, the argument gives the speed to show the text at, in
characters per second.

"{cps=20}Fixed Speed{/cps} {cps=*2}Double Speed{/cps}

font
The font tag renders the text between itself and its closing tag in the specified font. The
argument is the filename of the font to use.

"Try out the {font=mikachan.ttf}mikachan font{/font}."

i
The italics tag renders the text between itself and its closing tag in italics.

"Visit the {i}leaning tower of Pisa{/i}."

k
The kerning tag is a tag that adjust the kerning of characters between itself and its closing
tag. It takes as an argument a floating point number giving the number of pixels of kerning
to add to each kerning pair. (The number may be negative to decrease kerning.)

"{k=-.5}Negative{/k} Normal {k=.5}Positive{/k}"

image
The image tag is a self-closing tag that inserts an image into the text. The image should be
the height of a single line of text. The argument should be either the image filename, or
the name of an image defined with the image statement.

g "Good to see you! {image=heart.png}"

s
The strikethrough tag draws a line through text between itself and its closing tag.

g "It's good {s}to see you{/s}."


rb
The ruby bottom tag marks text between itself and its closing tag as ruby bottom text. See
the section on Ruby Text for more information.

rt
The ruby top tag marks text between itself and its closing tag as ruby top text. See the
section on Ruby Text for more information.

size
The size tag changes the size of text between itself and its closing tag. The argument
should be an integer, optionally preceded by + or -. If the argument is just an integer, the
size is set to that many pixels high. Otherwise, the size is increased or decreased by that
amount.

"{size=+10}Bigger{/size} {size=-10}Smaller{/size} {size=24}24 px{/size}."

space
The space tag is a self-closing tag that inserts horizontal space into a line of text. As an
argument, it takes an integer giving the number of pixels of space to add.

"Before the space.{space=30}After the space."

u
The underline tag underlines the text between itself and its closing tag.

g "It's good to {u}see{/u} you."

vspace
The vspace tag is a self-closing tag that inserts vertical space between lines of text. As an
argument, it takes an integer giving the number of pixels of space to add.

"Line 1{vspace=30}Line 2"

Dialogue Text Tags

Text tags that only apply to dialogue are:

fast
If the fast tag is displayed in a line of text, then all text before it is displayed instantly, even
in slow text mode. The fast tag is a self-closing tag.

g "Looks like they're{nw}"


show trebuchet
g "Looks like they're{fast} playing with their trebuchet again."

nw
The no-wait tag is a self-closing tag that causes the current line of dialogue to
automatically dismiss itself once the end of line has been displayed.

g "Looks like they're{nw}"


show trebuchet
g "Looks like they're{fast} playing with their trebuchet again."
p
The paragraph pause tag is a self-closing tag that terminates the current paragraph, and
waits for the user to click to continue. If it is given an argument, the argument is
interpreted as a number, and the wait automatically ends after that many seconds have
passed.

"Line 1{p}Line 2{p=1.0}Line 3"

w
The wait tag is a self-closing tag that waits for the user to click to continue. If it is given an
argument, the argument is interpreted as a number, and the wait automatically ends after
that many seconds have passed.

"Line 1{w} Line 1{w=1.0} Line 1"

User-Defined Text Tags

Ren'Py also supports user-defined text tags. A user-defined text tag is a text tag where the tag
name is empty. In this case, the argument is taken to be the name of a style. The text between
this tag and the closing tag has the following properties set to those defined in the style:

antialias
font
size
bold
italic
underline
strikethrough
color
black_color
kerning

Non-English Languages

The default font for Ren'Py contains characters for English and many other languages. For size
reasons, it doesn't contain the characters required to render other languages, including
Chinese, Japanese, and Korean. In order to support these language, a project must first change
the default font, using code like:

init python:
style.default.font = "mikachan.ttf"

Ren'Py should then support most world languages without further configuration. However,
Korean can be written with or without spacing between words. Ren'Py has a special mode to
support Korean with spaces, which can be enabled with the code:

init python:
style.default.language = "korean-with-spaces"

Finally, ideographic languages provide a large number of opportunities for line breaking. To
enable a faster line-breaking algorithm, use the code:

init python:
style.default.layout = "greedy"
The faster line-breaking algorithm is not be necessary unless the game is displaying huge
amounts of text, such as in NVL-mode.

Ruby Text

Ruby text (also known as furigana or interlinear annotations) is a way of placing small text
above a character or word. There are several steps required for your game to support Ruby
text.
First, you must set up styles for the ruby text. The following style changes are required:

1. The line_leadingproperty must be used to leave enough vertical space for the ruby
text.
2. A new named style must be created. The properties of this style, such as sizeshould be
set in a fashion appropriate for ruby text.
3. The yoffset of the new style should be set, in order to move the ruby text above the
baseline.
4. The ruby_stylefield of the text's style should be set to the newly-created style.

For example:

init python:
style.default.line_leading = 12

style.ruby_style = Style(style.default)
style.ruby_style.size = 12
style.ruby_style.yoffset = -20

style.default.ruby_style = style.ruby_style

Once Ren'Py has been configured, ruby text can be included using the rt and rb text tags. The
rt tag is used to mark one or more characters to be displayed as ruby text. If the ruby text is
preceded by text enclosed in the rb tag, the ruby text is centered over that text. Otherwise, it is
centered over the preceding character.
For example:

e "Ruby can be used for furigana ({rt}{/rt} {rt}{/rt})."

e "It's also used for translations ({rb}{/rb}{rt}Tokyo{/rt})."

It's the creator's responsibility to ensure that ruby text does not leave the boundaries of the
text. It may be necessary to add leading or spaces to the left and right of the text to prevent
these errors from occurring.

Fonts

Ren'Py supports Truetype and Image-Based fonts.


A Truetype font is specified by giving the name of the font file. The file must be present in the
game directory, or one of the archive files.
Ren'Py also supports Truetype collections that define more than one font. When accessing a
collection, use the 0-based font index, followed by an at-sign and the file name. For example,
"0@font.ttc" is the first font in a collection, "1@font.ttc" the second, and so on.

Font Replacement
The config.font_replacement_mapvariable is used to map fonts. The combination of font
filename, boldness, and italics is mapped to a similar combination. This allows a font with
proper italics to be used instead of the automatically-generated italics.
Once such mapping would be to replace the italic version of the Deja Vu Sans font with the
official oblique version. (You'll need to download the oblique font from the web.)

init python:
config.font_replacement_map["DejaVuSans.ttf", False, True] = ("DejaVuSans-Oblique.ttf"

This mapping can improve the look of italic text.

Image-Based Fonts

Image based fonts can be registered by calling one of the following registration functions.
Registering an image-based font requires the specification of a name, size, boldness,
italicness, and underline. When all of these properties match the registered font, the
registered font is used.

renpy.register_bmfont(name=None, size=None, bold=False, italics=False,


underline=False, filename=None)
This registers a BMFont with the given details. Please note that size, bold, italic, and
underline are all advisory (used for matching), and do not change the appearance of the
font.
Please see the BMFont home page for the tool that creates BMFonts. Ren'Py expects that
the filename parameter will be to a file in the BMFont text format, that describes a 32-bit
font. The Alpha channel should contain the font information, while the Red, Green, and
Blue channels should be set to one. The image files, kerning, and other control
information is read out of the BMFont file.
We recommend including Latin and General Punctuation as part of your BMFont, to ensure
all of the Ren'Py interface can render.

name
The name of the font being registered, a string.
size
The size of the font being registered, an integer.
bold
The boldness of the font being registered, a boolean.
italics
The italicness of the font being registered, a boolean.
underline
An ignored parameter.
filename
The file containing BMFont control information.

renpy.register_mudgefont(name=None, size=None, bold=False, italics=False,


underline=False, filename=None, xml=None, spacewidth=10, default_kern=0, kerns={})
This registers a MudgeFont with the given details. Please note that size, bold, italic, and
underline are all advisory (used for matching), and do not change the appearance of the
font.
Please see the MudgeFont home page for the tool that creates MudgeFonts. Ren'Py
assumes that character codes found in the MudgeFont xml file are unicode character
numbers, and ignores negative character codes.

name
The name of the font being registered, a string.
size
The size of the font being registered, an integer.
bold
The boldness of the font being registered, a boolean.
italics
The italicness of the font being registered, a boolean.
underline
An ignored parameter.
filename
The file containing the MudgeFont image, a string. The image is usually a TGA file, but
could be a PNG or other format that Ren'PY supports.
xml
The xml file containing information generated by the MudgeFont tool.
spacewidth
The width of a space character, an integer in pixels.
default_kern
The default kern spacing between characters, in pixels.
kerns
A map from two-character strings to the kern that should be used between those
characters.

renpy.register_sfont(name=None, size=None, bold=False, italics=False,


underline=False, filename=None, spacewidth=10, default_kern=0, kerns={},
charset=u'!"#$%&'()*+, -./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
This registers an SFont with the given details. Please note that size, bold, italic, and
underline are all advisory (used for matching), and do not change the appearance of the
font.
More information about SFont.

name
The name of the font being registered, a string.
size
The size of the font being registered, an integer.
bold
The boldness of the font being registered, a boolean.
italics
The italicness of the font being registered, a boolean.
underline
An ignored parameter.
filename
The file containing the sfont image, a string.
spacewidth
The width of a space character, an integer in pixels.
default_kern
The default kern spacing between characters, in pixels.
kerns
A map from two-character strings to the kern that should be used between those
characters.
charset- The character set of the font. A string containing characters in
the order in which they are found in the image. The default character set for a SFont
is:

! "#$%&'()*+,-./0123456789:;<=>?
@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
` abcdefghijklmnopqrstuvwxyz{|}~

As BMFont is the most complete of the three image font formats Ren'Py supports, it's the one
recommended for new projects. An example of BMFont use is:

init python:
renpy.register_bmfont("bmfont", 22, filename="bmfont.fnt")

define ebf = Character('Eileen', what_font="bmfont", what_size=22)

label demo_bmfont:

ebf "Finally, Ren'Py supports BMFonts."

Font Groups

When creating a multilingual game, it may not be possible to find a single font that covers
every writing system the game use while projecting the the mood the creator intends. To
support this, Ren'Py supports font groups that can take characters from two or more fonts and
combine them into a single font.
To create a font group, create a FontGroup object and call the .add method on it once or
more. a FontGroup can be used wherever a font name can be used. The add method takes the
start and end of a range of unicode character points, and the first range to cover a point is
used.
For example:

init python:
style.default.font = FontGroup().add("english.ttf", 0x0020, 0x007f).add("japanese.ttf"

FontGroup()
A group of fonts that can be used as a single font.
add(font, start, end)
Associates a range of characters with a font.

start
The start of the range. This may be a single-character string, or an integer giving
a unicode code point.
end
The end of the range. This may be a single-character string, or an integer giving a
unicode code point.

When multiple .add() calls include the same character, the first call takes precedence.
This returns the FontGroup, so that multiple calls to .add() can be chained together.

Text Displayable

Text can also be used as a displayable, which allows you to apply transforms to text, displaying
it as if it was an image and moving it around the screen.

Text(text, slow=None, scope=None, substitute=None, slow_done=None, **properties)


A displayable that displays text on the screen.

text
The text to display on the screen. This may be a string, or a list of strings and
displayables.
slow
Determines if the text is displayed slowly, being typed out one character at the time. If
None, slow text mode is determined by the slow_cpsstyle property. Otherwise, the
truth value of this parameter determines if slow text mode is used.
scope
If not None, this should be a dictionary that provides an additional scope for text
interpolation to occur in.
substitute
If true, text interpolation occurs. If false, it will not occur. If None, they are controlled
by config.new_substitutions.

Slow Text Concerns

Ren'Py allows the creator or user to indicate that text should be displayed slowly. In this case,
Ren'Py will render the text to a texture, and then draw rectangles from the texture to the
screen.

Unfortunately, this means that it's possible to get rendering artifacts when characters overlap.
To minimize these rendering artifacts, ensure that the line_leadingand line_spacing
properties are large enough that lines do not overlap. If the bottoms of characters on the first
line are clipped, espeically if line_spacing is negative, consider increasing
line_overlap_split.

Horizontal artifacts are also possible when characters are kerned together, but these artifacts
are less severe, as they exist for only a single frame.
Artifacts aren't a problem for static text, like the text in menus and other parts of the user
interface.
Translations

Ren'Py supports the automatic translation of text. The translation occurs whenever text is
displayed, and before text interpolation occurs.
Ren'Py reads translations out of .rpt files. A .rpt file is a text file containing lines beginning with
the following characters:

#
Lines beginning with the hash mark are comment lines, that are ignored.

<
Lines beginning with a less-than followed by a space are translation source lines, giving
strings to be translated.

>
Lines beginning with a greater-than followed by a space are translation lines, giving the
translation of the previous translation source.

Inside a translation line, newlines are escaped with \n, and backslashes are escaped with \\.
By default, Ren'Py reads translations out of a file called translations.rpt, if it exists. The
Language()action can be used to change the translation file.

Creating Translation Files

Ren'Py has support for automatically creating translation files. Taking advantage of this is a
three-step process.

1. Create an empty translation file, such as translations.rpt, in the game directory.


2. Set the RENPY_UPDATE_TRANSLATIONS environment variable to a non-empty string.
3. Play through the game until all text is seen.

Ren'Py will add an entry to the translations file for each unit of text shown. This text can then
be translated.

Text Overflow Logging

Ren'Py can log cases where text expands outside of the area allocated for it. To enable text
overflow logging, the following steps are necessary.

1. Set the config.debug_text_overflowvariable to true.


2. Set the xmaximumand ymaximumstyle properties on either the Text displayable, or a
container enclosing it.
3. Run the game.

Whenever text is displayed that overflows the available area, Ren'Py will log an error to the
text_overflow.txtfile.

Displayables

A displayable is an object that can be shown to the user. Ren'Py displayables can be used in
many ways.

Assignment to an image name using the image statement.


Added to a screen using the screen language add statement.
Assignment to certain config variables.
Assignment to certain style properties.

When a Ren'Py function or variable expects a displayable, there are four things that can be
provided:

An object of type Displayable, created by calling one of the functions given below.
A string with a dot (.) in it. Such a string is interpreted as a filename by Image().
A color. A color may either be given as a hexidecimal color string in "#rgb", "#rgba",
"#rrggbb", or "#rrggbbaa" form, or an (r, g, b, a) tuple, where each component is an
integer between 0 and 255. Colors are passed to Solid().
An image name. Any other string is interpreted as a reference to an image defined with
the image statement.

Images

The most commonly used displayable is Image, which loads a file from disk and displays it.
Since Image is so commonly used, when a string giving a filename is used in a context that
expects a displayable, an Image is automatically created. The only time it's necessary to use
Image directly is when you want to create an image with style properties.

Image(filename, **properties)
Loads an image from a file. filenameis a string giving the name of the file.
filenameshould be a JPEG or PNG file with an appropriate extension.

# These two lines are equivalent.


image logo = "logo.png"
image logo = Image("logo.png")

# Using Image allows us to specify a default position as part of


# an image.
image logo right = Image("logo.png", xalign=1.0)

Loading an Image from from a file on disk and decoding it so it can be drawn to the screen
takes a long amount of time. While measured in the tenths or hundreds of seconds, the
duration of the loading process is long enough that it can prevent an acceptable framerate,
and become annoying to the user.
Since an Image is of a fixed size, and doesn't change in response to input, game state, or the
size of the area available to it, an Image can be loaded before it is needed, and placed into an
area of memory known as the image cache. Once an Image is decoded and in the cache, it
can be quickly drawn to the screen.
Ren'Py attempts to predict the images that will be used in the future, and loads them into the
image cache before they are used. When space in the cache is needed for other images,
Ren'Py will remove images that are no longer being used.
By default, Ren'Py will predictively cache up to 8 screens worth of image data. (If your screen
is 800x600, then a screen's worth of data is one 800x600 image, two 400x600 images, and so
on.) This can be changed with the :var:config.image_cache_size configuration variable.

Although the precise amount is dependent on implementation details and there is significant
overhead, as a rule of thumb, each pixel in the image cache consumes 4 bytes of main
memory and 4 bytes of video memory.

Image-Like Displayables

We call these displayables image-like because they take up a rectangular area of the screen,
and do not react to input. These differ from normal images by varying their size to fill an area
(Frame, LiveTile, and Solid), or by allowing the user to specify their size (LiveComposite,
LiveCrop, Null). They are not image manipulators.
Image-like displayables take Position Style Properties.

Frame(image, xborder, yborder, tile=False, **properties)


A displayable that resizes an image to fill the available area, while preserving the width
and height of its borders. is often used as the background of a window or button.

Using a frame to resize an image to double its size.

image
An image manipulator that will be resized by this frame.
left
The size of the border on the left side.
top
The size of the border on the top.
right
The size of the border on the right side. If None, defaults to left.
bottom
The side of the border on the bottom. If None, defaults to top.
tile
If true, tiling is used to resize sections of the image, rather than scaling.

# Resize the background of the text window if it's too small.


init python:
style.window.background = Frame("frame.png", 10, 10)

LiveCrop(rect, child, **properties)


This created a displayable by cropping childto rect, where rectis an (x, y, width, height)
tuple.

image eileen cropped = LiveCrop((0, 0, 300, 300), "eileen happy")

LiveTile(child, style='tile', **properties)


Tiles childuntil it fills the area allocated to this displayable.

image bg tile = LiveTile("bg.png")

Null(width=0, height=0, **properties)


A displayable that creates an empty box on the screen. The size of the box is controlled by
widthand height. This can be used when a displayable requires a child, but no child is
suitable, or as a spacer inside a box.

image logo spaced = HBox("logo.png", Null(width=100), "logo.png")

Solid(color, **properties)
A displayable that fills the area its assigned with color.

image white = Solid("#fff")

Dynamic Displayables

Dynamic displayables display a child displayable based on the state of the game. They do not
take any properties, as layout is controlled by the properties of the child displayable they
return.

ConditionSwitch(*args, **kwargs)
This is a displayable that changes what it is showing based on python conditions. The
positional argument should be given in groups of two, where each group consists of:

A string containing a python condition.


A displayable to use if the condition is true.
The first true condition has its displayable shown, at least one condition should always be
true.

image jill = ConditionSwitch(


"jill_beers > 4", "jill_drunk.png",
"True", "jill_sober.png")

DynamicDisplayable(function, *args, **kwargs)


A displayable that can change its child based on a Python function, over the course of an
interaction.

function
A function that is called with the arguments:

The amount of time the displayable has been shown for.


The amount of time any displayable with the same tag has been shown for.
Any positional or keyword arguments supplied to DynamicDisplayable.
and should return a (d, redraw) tuple, where:

dis a displayable to show.


redrawis the amount of time to wait before calling the function again, or None to
not call the function again before the start of the next interaction.
functionis called at the start of every interaction.

As a special case, functionmay also be a python string that evaluates to a displayable. In


that case, function is run once per interaction.

# If tooltip is not empty, shows it in a text. Otherwise,


# show Null. Checks every tenth of a second to see if the
# tooltip has been updated.
init python:
def show_tooltip(st, at):
if tooltip:
return tooltip, .1
else:
return Null()

image tooltipper = DynamicDisplayable(show_tooltip)

ShowingSwitch(*args, **kwargs)
This is a displayable that changes what it is showing based on the images are showing on
the screen. The positional argument should be given in groups of two, where each group
consists of:

A string giving an image name, or None to indicate the default.


A displayable to use if the condition is true.
A default image should be specified.
One use of ShowingSwitch is to have side images change depending on the current
emotion of a character. For example:

define e = Character("Eileen",
show_side_image=ShowingSwitch(
"eileen happy", Image("eileen_happy_side.png", xalign=1.0, yalign=1.0),
"eileen vhappy", Image("eileen_vhappy_side.png", xalign=1.0, yalign=1.0),
None, Image("eileen_happy_default.png", xalign=1.0, yalign=1.0),
)
)

Applying Transforms to Displayables

The At function produces a displayable from a displayable and one or more transforms.

At(d, *args)
Given a displayable d, applies each of the transforms in argsto it. The transforms are
applied in left-to-right order, so that the outermost transform is the rightmost argument.

transform birds_transform:
xpos -200
linear 10 xpos 800
pause 20
repeat

image birds = At("birds.png", birds_transform)

Layout Boxes

Layout boxes are displayables that lay out their children on the screen. They can lay out the
children in a horizontal or vertical manner, or can lay them out using the standard positioning
algorithm.
The box displayables take any number of positional and keyword arguments. Positional
arguments should be displayables that are added to the box as children. Keyword arguments
are style properties that are applied to the box.
Boxes take Position Style Properties and Box Style Properties.

Fixed(*args, **properties)
A box that fills the screen. Its members are laid out from back to front, with their position
properties controlling their position.

HBox(*args, **properties)
A box that lays out its members from left to right.

VBox(*args, **properties)
A layout that lays out its members from top to bottom.

# Display two logos, to the left and right of each other.


image logo hbox = HBox("logo.png", "logo.png")

# Display two logos, one on top of the other.


image logo vbox = VBox("logo.png", "logo.png")

# Display two logos. Since both default to the upper-left


# corner of the screen, we need to use Image to place
# those logos on the screen.
image logo fixed = Fixed(
Image("logo.png", xalign=0.0, yalign=0.0),
Image("logo.png", xalign=1.0, yalign=1.0))

Effects

These displayables are used to create certain visual effects.

AlphaBlend(control, old, new, alpha=False)


This transition uses a controldisplayable (almost always some sort of animated
transform) to transition from one displayable to another. The transform is evaluated. The
newdisplayable is used where the transform is opaque, and the olddisplayable is used
when it is transparent.

alpha
If true, the image is composited with what's behind it. If false, the default, the image is
opaque and overwrites what's behind it.

Image Manipulators

An image manipulator is a displayable that takes an image or image manipulator, performs an


operation to it, and stores the result of that operation in the image cache. Since image
manipulators can be predicted like images, they can perform expensive operations without
incuring a display-time overhead.
Image manipulators are limited to storing image data to the cache. This means that their
result is of a fixed size, known in advance, and they can't change in response to game state or
input. Generally, image manipulators can only take images or other image manipulators as
input.

An image manipulator can be used any place a displayable can, but not vice-versa. An Image()
is a kind of image manipulator, so an Image can be used whenever an image manipulator is
required.
Many image manipulators provide the same functionality as other displayables. Most of these
exist so they can be provided as input to other image manipulators, and so the game-maker
can choose between cache memory usage and work done at render-time. There's also an
element of historical accident here - many of these image manipulators predate their
equivalents.

im.AlphaMask(base, mask, **properties)


An image manipulator that takes two image manipulators, baseand mask, as arguments. It
replaces the alpha channel of basewith the red channel of mask.
This is used to provide an image's alpha channel in a second image, like having one jpeg
for color data, and a second one for alpha. In some cases, two jpegs can be smaller than a
single png file.

im.Composite(size, *args, **properties)


This image manipulator composites multiple images together to form a single image.
The sizeshould be a (width, height) tuple giving the size of the composed image.
The remaining positional arguments are interpreted as groups of two. The first argument
in a group should be an (x, y) tuple, while the second should be an image manipulator. The
image produced by the image manipulator is composited at the location given by the
tuple.

image girl clothed happy = im.Composite(


(300, 600),
(0, 0), "girl_body.png",
(0, 0), "girl_clothes.png",
(100, 100), "girl_happy.png"
)

im.Crop(im, rect)
An image manipulator that crops rect, a (x, y, width, height) tuple, out of im, an image
manipulator.

image logo crop = im.Crop("logo.png", (0, 0, 100, 307))


im.FactorScale(im, width, height=None, bilinear=True, **properties)
An image manipulator that scales im(a second image manipulator) to widthtimes its
original width, and heighttimes its original height. If heightis ommitted, it defaults to
width.
If bilinearis true, then bilinear interpolation is used for the scaling. Otherwise, nearest
neighbor interpolation is used.

image logo doubled = im.FactorScale("logo.png", 1.5)

im.Flip(im, horizontal=False, vertical=False, **properties)


An image manipulator that flips im(an image manipulator) vertically or horizontally.
verticaland horizontalcontrol the directions in which the image is flipped.

image eileen flip = im.Flip("eileen_happy.png", vertical=True)

im.Grayscale(im, **properties)
An image manipulator that creats a desaturated version of the image manipulator im.

im.Scale(im, width, height, bilinear=True, **properties)


An image manipulator that scales im(an image manipulator) to widthand height.
If bilinearis true, then bilinear interpolation is used for the scaling. Otherwise, nearest
neighbor interpolation is used.

image logo scale = im.Scale("logo.png", 100, 150)

im.Sepia(im, **properties)
An image manipulator that creates a sepia-toned version of the image manipulator im.

im.Tile(im, size=None, **properties)


An image manipulator that tiles the image manipulator im, until it is size.

size
If not None, a (width, height) tuple. If None, this defaults to (config.screen_width,
config.screen_height).

im.MatrixColor

The im.MatrixColor image manipulator is an image manipulator that uses a matrix to control
how the colors of an image are transformed. The matrix used can be an im.matrix object,
which encodes a 5x5 matrix in an object that supports matrix multiplication, and is returned by
a series of functions. im.matrix objects may be multiplied together to yield a second object
that performs both operations. For example, the code:

image city blue = im.MatrixColor(


"city.jpg",
im.matrix.desaturate() * im.matrix.tint(0.9, 0.9, 1.0))

first desaturates the image, and then tints it blue. When the intermediate image is not needed,
multiplying matrices is far more efficient, in both time and image cache space, than using two
im.MatrixColors.

im.MatrixColor(im, matrix, **properties)


An image operator that uses matrixto linearly transform the image manipulator im.
Matrixshould be a list, tuple, or im.matrix()that is 20 or 25 elements long. If the object
has 25 elements, then elements past the 20th are ignored.
When the four components of the source color are R, G, B, and A, which range from 0.0 to
1.0; the four components of the transformed color are R', G', B', and A', with the same
range; and the elements of the matrix are named:

[ a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t ]

the transformed colors can be computed with the formula:

R' = (a * R) + (b * G) + (c * B) + (d * A) + e
G' = (f * R) + (g * G) + (h * B) + (i * A) + j
B' = (k * R) + (l * G) + (m * B) + (n * A) + o
A' = (p * R) + (q * G) + (r * B) + (s * A) + t

The components of the transformed color are clamped to the range [0.0, 1.0].

im.matrix()
Constructs an im.matrix object from matrix. im.matrix objects support The operations
supported are matrix multiplication, scalar multiplication, element-wise addition, and
element-wise subtraction. These operations are invoked using the standard mathematical
operators (*, *, +, and -, respectively). If two im.matrix objects are multiplied, matrix
multiplication is performed, otherwise scalar multiplication is used.
matrixis a 20 or 25 element list or tuple. If it is 20 elements long, it is padded with (0, 0, 0,
0, 1) to make a 5x5 matrix, suitable for multiplication.

im.matrix.brightness(b)
Returns an im.matrix that alters the brightness of an image.

b
The amount of change in image brightness. This should be a number between -1 and
1, with -1 the darkest possible image and 1 the brightest.

im.matrix.colorize(black_color, white_color)
Returns an im.matrix that colorizes a black and white image. black_colorand
white_colorare Ren'Py style colors, so they may be specfied as strings or tuples of (0-255)
color values.

# This makes black colors red, and white colors blue.


image logo colored = im.MatrixColor(
"bwlogo.png",
im.matrix.colorize("#f00", "#00f"))
im.matrix.contrast(c)
Returns an im.matrix that alters the contrast of an image. cshould be greater than 0.0,
with values between 0.0 and 1.0 decreasing contrast, and values greater than 1.0
increasing contrast.

im.matrix.desaturate()
Returns an im.matrix that desaturates the image (makes it grayscale). This is equivalent to
calling im.matrix.saturation(0).

im.matrix.hue(h)
Returns an im.matrix that rotates the hue by hdegrees, while preserving luminosity.

im.matrix.identity()
Returns an identity matrix, one that does not change color or alpha.

im.matrix.invert()
Returns an im.matrix that inverts the red, green, and blue channels of the image without
changing the alpha channel.

im.matrix.opacity(o)
Returns an im.matrix that alters the opacity of an image. An oof 0.0 is fully transparent,
while 1.0 is fully opaque.

im.matrix.saturation(level, desat=(0.2126, 0.7152, 0.0722))


Returns an im.matrix that alters the saturation of an image. The alpha channel is
untouched.

level
The amount of saturation in the resulting image. 1.0 is the unaltered image, while 0.0
is grayscale.
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.

im.matrix.tint(r, g, b)
Returns an im.matrix that tints an image, without changing the alpha channel. 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 ris .5, and the value of the red channel is 100,
the transformed color will have a red value of 50.)

Transforms

A transform can be applied to a displayable to yield another displayable. The built-in


transforms are used to control where an object is placed on the screen, while user-defined
transforms can cause more complex effects, like motion, zoom, and rotation.
Transforms can be applied by giving the at clause to the scene and show statements. The
following code applies the "right" transform to the eileen happy displayable.:

show eileen happy at right

Multiple transforms can be applied by separating them with commas. These transforms are
applied from left-to-right, with the rightmost transform taking precendece in the case of
conflicts.

show eileen happy at halfsize, right

A displayable always has a transform associated with it. If no transform is given, the prior
transform is used. When the transform is changed, undefined values are taken from the prior
transform, or from defaultif there is no prior transform.

Default Transforms

Ren'Py ships with a number of transforms defined by default. These transforms position things
on the screen. Here's a depiction of where each default transform will position an image.

+-----------------------------------------------------------+
|topleft, reset top topright|
| |
| |
| |
| |
| truecenter |
| |
| |
| |
| |
|left center, default right|
+-----------------------------------------------------------+

The offscreenleft and offscreenright transforms position images off the screen. These
transforms can be used to move things off the screen (remember to hide them afterwards, to
ensure that they do not consume resources).
The transforms are:

center
Centers horizontally, and aligns to the bottom of the screen.

default
Centers horizontally, and aligns to the bottom of the screen. This can be redefined to
change the default placement of images shown with the show or scene statements.

left
Aligns to the bottom-left corner of the screen.

offscreenleft
Places the displayable off the left side of the screen, aligned to the bottom of the screen.
offscreenright
Places the displayable off the left side of the screen, aligned to the bottom of the screen.

reset
Resets the transform. Places the displayable in the top-left corner of the scren, and also
eliminates any zoom, rotation, or other effects.

right
Aligns to the bottom-right corner of the screen.

top
Centers horizontally, and aligns to the top of the screen.

topleft
Aligns to the top-left corner of the screen.

topright
Aligns to the top-right corner of the screen.

truecenter
Centers both horizontally and vertically.

Creator-Defined Transforms

A creator can define a transform using the animation and transformation language, or the
Transformfunction.

Transitions

Transitions can be used as part of the with statement, as well as in other parts of Ren'Py, to
apply effects to changes in the scene. Ren'Py comes with a small number of pre-defined
transitions, which can be given directly to the with statement. It also includes transition classes,
which can be used to create new transitions.

Pre-Defined Transitions

Pre-defined transitions can be given directly to the with statement. For example:

show bg washington
with dissolve

fade
Takes 0.5 seconds to fade to black, and then 0.5 seconds to fade to the new screen. An
instance of the Fade()transition class.

dissolve
Takes 0.5 seconds to dissolve from the old to the new screen. An instance of the
Dissolve()transition class.

pixellate
Pixellates the old scene for .5 seconds, and the new scene for another .5 seconds. An
instance of the Pixellate()transition class.

move
Takes 0.5 seconds to the move images that have changed location to their new locations.
An instance of the MoveTransition()transition class.

moveinright
Also: moveinleft, moveintop, moveinbottom
These move entering images onto the screen from the appropriate side, taking 0.5
seconds to do so.

moveoutright
Also: moveoutleft, moveouttop, moveoutbottom
These move leaving images off the screen via the appropriate side, taking 0.5 seconds to
do so.

ease
Also: easeinright, easeinleft, easeintop, easeinbottom, easeoutright,
easeoutleft, easeouttop, easeoutbottom
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.

zoomin
This zooms in entering images, taking 0.5 seconds to do so.

zoomout
This zooms out leaving images, taking 0.5 seconds to do so.

zoominout
This zooms in entering images and zooms out leaving images, taking 0.5 seconds to do so.

vpunch
When invoked, this transition shakes the screen vertically for a quarter second.

hpunch
When invoked, this transition shakes the screen horizontally for a quarter second.

blinds
Transitions the screen in a vertical blinds effect lasting 1 second. An instance of the
ImageDissolve()transition class.

squares
Transitions the screen in a squares effect lasting 1 second.

wipeleft
Also: wiperight, wipeup, wipedown
Wipes the scene in the given direction. Instances of the CropMove()transition class.

slideleft
Also: slideright, slideup, slidedown
Slides the new scene in the given direction. Instances of the CropMove()transition class.
slideawayleft
Also: slideawayright, slideawayup, slideawaydown
Slides the new scene in the given direction. Instances of the CropMove()transition class.

irisin
Also: irisout
Use a rectangular iris to display the new screen, or hide the old screen. Instances of the
CropMove()transition class.

Transition Classes

Transition classes are functions that can be called to create new transitions. These functions
are parameterized, allowing entire families of transitions to be created.
Calling transition classes can be done as part of the with statement. For example:

# A very long dissolve.


with Dissolve(10.0)

If we find ourselves calling the same transition class repeatedly, we can use the define
statement to assign the transition to a variable:

define annoytheuser = Dissolve(1.0)

label start:
show bg washington
with annoytheuser

AlphaDissolve(control, delay=0.0, alpha=False, reverse=False)


Returns a transition that uses a control displayable (almost always some sort of animated
transform) to transition from one screen to another. The transform is evaluated. The new
screen is used where the transform is opaque, and the old image is used when it is
transparent.

control
The control transform.
delay
The time the transition takes, before ending.
alpha
If true, the image is composited with what's behind it. If false, the default, the image is
opaque and overwrites what's behind it.
reverse
If true, the alpha channel is reversed. Opaque areas are taken from the old image,
while transparent areas are taken from the new image.

ComposeTransition(trans, before, after)


Returns a transition that composes up to three transitions. If not None, the beforeand
aftertransitions are applied to the old and new scenes, respectively. These updated old
and new scenes are then supplied to the transtransition.

# Move the images in and out while dissolving. (This is a fairly expensive transition.)
define moveinoutdissolve = ComposeTransition(dissolve, before=moveoutleft, after=moveinr

CropMove(time, mode="slideright", startcrop=(0.0, 0.0, 0.0, 1.0), startpos=(0.0, 0.0),


endcrop=(0.0, 0.0, 1.0, 1.0), endpos=(0.0, 0.0), topnew=True)
Returns a transition that works by cropping a scene and positioning it on the screen. This
can be used to implement a variety of effects, all of which involved changing rectangular
slices of scenes.

time
The time the transition takes.
mode
The name of the mode of the transition. There are three groups of modes: wipes,
slides, and other. This can also be "custom", to allow a custom mode to be defined.
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".

The following parameters are only respected if the mode is "custom". Positions are
relative to the size of the screen, while the crops are relative to the size of the image. So a
crop of (0.25, 0.0, 0.5, 1.0) takes the middle half of an image.

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.
endcrop
The ending rectangle that is cropped out of the top image. A 4-element tuple
containing x, y, width, and height.
endpos
The ending place that the top image is drawn to the screen at, a 2-element tuple
containing x and y.
topnew
If true, the scene that is cropped and moved (and is on top of the other scene) is the
new scene. If false, it is the old scene.

define wiperight = CropMove(1.0, "wiperight")


define wipeleft = CropMove(1.0, "wipeleft")
define wipeup = CropMove(1.0, "wipeup")
define wipedown = CropMove(1.0, "wipedown")

define slideright = CropMove(1.0, "slideright")


define slideleft = CropMove(1.0, "slideleft")
define slideup = CropMove(1.0, "slideup")
define slidedown = CropMove(1.0, "slidedown")

define slideawayright = CropMove(1.0, "slideawayright")


define slideawayleft = CropMove(1.0, "slideawayleft")
define slideawayup = CropMove(1.0, "slideawayup")
define slideawaydown = CropMove(1.0, "slideawaydown")

define irisout = CropMove(1.0, "irisout")


define irisin = CropMove(1.0, "irisin")

Dissolve(time, alpha=False, time_warp=None)


Returns a transition that dissolves from the old scene to the new scene.

time
The time the dissolve will take.
alpha
If true, the dissolve will alpha-composite the the result of the transition with the
screen. If false, the result of the transition will replace the screen, which is more
efficient.
time_warp
A function that adjusts the timeline. If not None, this should be a function that takes a
fractional time between 0.0 and 1.0, and returns a number in the same range.

Fade(out_time, hold_time, in_time, color="#000")


Returns a transition that takes out_timeseconds to fade to a screen filled with color, holds
at that screen for hold_timeseconds, and then takes in_timeto fade to then new screen.

# Fade to black and back.


define fade = Fade(0.5, 0.0, 0.5)

# Hold at black for a bit.


define fadehold = Fade(0.5, 1.0, 0.5)

# Camera flash - quickly fades to white, then back to the scene.


define flash = Fade(0.1, 0.0, 0.5, color="#fff")

ImageDissolve(image, time, ramplen=8, reverse=False, alpha=True, time_warp=None)


Returns a transition that dissolves the old scene into the new scene, using an image to
control the dissolve process. This means that white pixels will dissolve in first, and black
pixels will dissolve in last.

image
A control image to use. This must be either an image file or image manipulator. The
control image should be the size of the scenes being dissolved.
time
The time the dissolve will take.
ramplen
The length of the ramp to use. This must be an integer power of 2. When this is the
default value of 8, when a white pixel is fully dissolved, a pixel 8 shades of gray darker
will have completed one step of dissolving in.
reverse
If true, black pixels will dissolve in before white pixels.
alpha
If true, the dissolve will alpha-composite the the result of the transition with the
screen. If false, the result of the transition will replace the screen, which is more
efficient.
time_warp
A function that adjusts the timeline. If not None, this should be a function that takes a
fractional time between 0.0 and 1.0, and returns a number in the same range.

define circirisout = ImageDissolve("circiris.png", 1.0)


define circirisin = ImageDissolve("circiris.png", 1.0, reverse=True)
define circiristbigramp = ImageDissolve("circiris.png", 1.0, ramplen=256)

MoveTransition(delay, enter=None, leave=None, old=False, layers=['master'],


time_warp=None, enter_time_warp=None, leave_time_warp=None)
Returns a transition that interpolates the position of images (with the same tag) in the old
and new scenes.

delay
The time it takes for the interpolation to finish.
enter
If not None, images entering the scene will also be moved. The value of entershould
be a transform that is applied to the image to get its starting position.
leave
If not None, images leaving the scene will also be move. The value of leaveshould be
a transform that is applied to the image to get its ending position.
old
If true, the old image will be used in preference to the new one.
layers
A list of layers that moves are applied to.
time_warp
A time warp function that's applied to the interpolation. This takes a number between
0.0 and 1.0, and should return a number in the same range.
enter_time_warp
A time warp function that's applied to images entering the scene.
enter_time_warp
A time warp function that's applied to images leaving the scene.

MultipleTransition(args)
Returns a transition that allows multiple transitions to be displayed, one after the other.

args
A list containing an odd number of items. The first, third, and other odd-numbered
items must be scenes, and the even items must be transitions. A scene can be one of:
items must be scenes, and the even items must be transitions. A scene can be one of:

A displayable.
False, to use the old scene.
True, to use the new scene.
Almost always, the first argument will be False and the last True.

The transitions in argsare applied in order. For each transition, the old scene is the screen
preceding it, and the new scene is the scene following it. For example:

define logodissolve = MultipleTransition(


False, Dissolve(0.5)
"logo.jpg", NoTransition(1.0),
"logo.jpg", dissolve,
True)

This example will dissolve to logo.jpg, wait 1 second, and then dissolve to the new scene.

Pause(delay)
Returns a transition that only displays the new screen for delayseconds. It can be useful
as part of a MultipleTransition.

Pixellate(time, steps)
Returns a transition that pixellates out the old screen, and then pixellates in the new
screen.

time
The total time the transition will take, in seconds.
steps
The number of steps that will occur, in each direction. Each step creates pixels about
twice the size of those in the previous step, so a 5-step pixellation will create 32x32
pixels.

Transition Families

Transition families are functions that define a large family of related transitions.

define.move_transitions(prefix, delay, time_warp=None, in_time_warp=None,


out_time_warp=None, old=False, layers=['master'], **kwargs)
This defines a family of move transitions, similar to the move and ease transitions. For a
given prefix, this defines the transitions:

prefix- A transition that takes delayseconds to move images that changed positions
to their new locations.
prefixinleft, prefixinright, prefixintop, prefixinbottom - Transitions that take delay
seconds to move images that changed positions to their new locations, with newly
shown images coming in from the appropriate side.
prefixoutleft, prefixoutright, prefixouttop, prefixoutbottom - Transitions that take
delayseconds to move images that changed positions to their new locations, with
newly hidden images leaving via the appropriate side.

time_warp, in_time_warp, out_time_warp


Time warp functions that are given a time from 0.0 to 1.0 representing the fraction of
the move complete, and return a value in the same range giving the fraction of a
the move complete, and return a value in the same range giving the fraction of a
linear move that is complete.
This can be used to define functions that ease the images around, rather than moving
them at a constant speed.
The three argument are used for images remaining on the screen, newly shown
images, and newly hidden images, respectively.
old
If true, the transitions to move the old displayables, rather than the new ones.
layers
The layers the transition will apply to.

# This defines all of the pre-defined transitions beginning


# with "move".
init python:
define.move_transitions("move", 0.5)

Animation and Transformation Language

The Animation and Transformation Language (ATL) provides a high-level way of choosing a
displayable to show, positioning it on the screen, and applying transformations such as
rotation, zoom, and alpha-modification. These can be changed over time, and in response to
events.
The Python equivalent of an ATL transform is the Transform()displayable. There is no way to
create an ATL transform programatically.

Ren'Py Script Statements

ATL Code can be included as part of three Ren'Py script statements.

Transform Statement

The transform statement creates a transform that can be supplied as part of an at clause. The
syntax of the transform statement is:

atl_transform ::= "transform" name "(" parameters ")" ":"


atl_block

The transform statement must 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.
Namemust be a python identifier. The transform created by the ATL block is bound to this
name.:

transform left_to_right:
xalign 0.0
linear 2.0 yalign 1.0
repeat

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:

atl_image ::= "image" image_name ":"


atl_block

image eileen animated:


"eileen_happy.png"
pause 1.0
"eileen_vhappy.png"
pause 1.0
repeat

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 ::= stmt_scene ":"


atl_block
atl_show ::= stmt_show ":"
atl_block

scene bg washington:
zoom 2.0

show eileen happy:


xalign 1.0

ATL Syntax and Semantics

An ATL block consists of one or more logical lines, all at the same indentation, and indented
relative to the statement containing the block. Each logical line in an ATL block must contain
one or more ATL statements.
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 (":").
By default, statements in a block are executed in the order in which they appear, starting with
the first statement in the block. Execution terminates when the end of the block is reached.
Time statements change this, as described in the appropriate section below.
Execution of a block terminates when all statements in the block have terminated.
If an ATL statement requires evaluation of an expression, such evaluation occurs when the
transform is first added to the scene list. (Such as when using a show statement or ui function.)

ATL Statements

The following are the ATL statements.

Interpolation Statement
The interpolation statement is the main way that ATL controls transformations.

atl_interp ::= ( 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 the interpolation statement is used to select 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 interpolation should take.
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.
The interpolation statement can then contain a number of other clauses. When a property and
value are present, then the value is the value the property will obtain at the end of the
statement. The value can be obtained in several ways:

If the value is followed by one or two knots, then spline motion is used. The starting point
is the value of the property at the start of the interpolation, the end point is the property
value, and the knots are used to control the spline.
If the interpolation statement contains a "clockwise" or "counterclockwise" clause,
circular motion is used, as described below.
Otherwise, the value is linearly interpolated between the start and end locations, using
the completion fraction.

If a simple expression is present, it should evaluate to a transform with only a single


interpolation statement, without a warper, splines, or circular motion. The properties from the
transform are processed as if they were included in this statement.
Some sample interpolations are:

show logo base:


# Show the logo at the upper right side of the screen.
xalign 1.0 yalign 0.0

# Take 1.0 seconds to move things back to the left.


linear 1.0 xalign 0.0

# Take 1.0 seconds to move things to the location specified in the


# truecenter transform. Use the ease warper to do this.
ease 1.0 truecenter

# Just pause for a second.


pause 1.0

# Set the location to circle around.


alignaround (.5, .5)

# Use circular motion to bring us to spiral out to the top of


# the screen. Take 2 seconds to do so.
linear 2.0 yalign 0.0 clockwise circles 3
# Use a spline motion to move us around the screen.
linear 2.0 align (0.5, 1.0) knot (0.0, .33) knot (1.0, .66)

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

The time statement is a simple control statement. It contains a single simple_expression, which
is evaluated to give a time, expressed as seconds from the start of execution of the containing
block.

atl_time ::= "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.
Time statements are implicitly preceded by a pause statement with an infinite time. This
means that if control would otherwise reach the time statement, it waits until the time
statement would take control.
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

An expression statement is a simple statement that starts with a simple expression. It then
contains an optional with clause, with a second simple expression.

atl_expression ::= simple_expression ("with" simple_expression)?

There are three things the first simple expression may evaluate to:

If it's a transform, that transform is executed. With clauses are ignored when a transform
is supplied.
If it's an integer or floating point number, it's taken as a number of seconds to pause
execution for.
Otherwise, the expression is interpreted to be a displayable. This displayable replaces
the child of the transform when this clause executes, making it useful for animation. If a
with clause is present, the second expression is evaluated as a transition, and the
transition is applied to the old and new displayables.

image atl example:


# Display logo_base.png
"logo_base.png"
# Pause for 1.0 seconds.
1.0

# Show logo_bw.png, with a dissolve.


"logo_bw.png" with Dissolve(0.5, alpha=True)

# Run the move_right tranform.


move_right

Pass Statement

atl_pass ::= "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

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.)

atl_repeat ::= "repeat" (simple_expression)?

The repeat statement must be the last statement in a block.:

show logo base:


xalign 0.0
linear 1.0 xalign 1.0
linear 1.0 xalign 0.0
repeat

Block Statement

The block statement is a complex statement that contains a block of ATL code. This can be
used to group statements that will repeat.

atl_block_stmt ::= "block" ":"


atl_block

label logo base:


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

The choice statement is a complex statement that defines one of a set of potential choices.
Ren'Py will pick one of the choices in the set, and execute the ATL block associated with it, and
Ren'Py will pick one of the choices in the set, and execute the ATL block associated with it, and
then continue execution after the last choice in the choice set.

atl_choice ::= "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_expressionis 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

The parallel statement is used to define a set of ATL blocks to execute in parallel.

atl_parallel ::= "parallel" ":"


atl_block

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:
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

The event statement is a simple statement that causes an event with the given name to be
produced.

atl_event ::= "event" name

When an event is produced inside a block, the block is checked to see if an event handler for
the given name exists. If it does, control is transferred to the event handler. Otherwise, the
event propagates to any containing event handler.
On Statement

The On statement is a complex statement that defines an event handler. On statements are
greedily grouped into a single statement.

atl_on ::= "on" name ":"


atl_block

The on statement is used to handle events. When an event is handled, handling of any other
event ends and handing of the new event immediately starts. When an event handler ends
without another event occuring, the defaultevent is produced (unless were already handing
the defaultevent).

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.
The contains expression variant takes an expression, and sets that expression as the child of
the transform. This is useful when an ATL transform wishes to contain, rather than include, a
second ATL transform.

atl_contains ::= "contains" expression

transform an_animation:
"1.png"
pause 2
"2.png"
pause 2
repeat

image move_an_animation:
contains an_animation

# If we didn't use contains, we'd still be looping and


# would never reach here.
xalign 0.0
linear 1.0 yalign 1.0

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.

atl_counts ::= "contains" ":"

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.

atl_function ::= "function" expression

The functions have the same signature as those used with Transform():

The first argument is a transform object. Transform properties can be set on this object.
The second argument is the shown timebase, the number of seconds since the function
began executing.
The third argument is the the animation timebase, which is the number of seconds
something with the same tag has been on the screen.
If the function returns a number, it will be called again after that number of seconds has
elapsed. (0 seconds means to call the function as soon as possible.) If the function
returns None, control will pass to the next ATL statement.

init python:
def slide_function(trans, st, at):
if st > 1.0:
trans.xalign = 1.0
return None
else:
trans.xalign = st
return 0

label start:
show logo base:
function slide_function
pause 1.0
repeat

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
Pause, then jump to the new value. If t == 1.0, t = 1.0. Otherwise, t' = 0.0.
linear
Linear interpolation. t' = t
ease
Start slow, speed up, then slow down. t' = .5 - math.cos(math.pi * t) / 2.0
easein
Start fast, then slow down. t' = math.cos((1.0 - t) * math.pi / 2.0
easeout
Start slow, then speed up. t' = 1.0 - math.cos(t * math.pi / 2.0)

New warpers can be defined using the renpy.atl_warper decorator, in a python early block. It
should be placed in a file that is parsed before any file that uses the warper. The code looks
like:

python early hide:

@renpy.atl_warper
def linear(t):
return t

List of Transform Properties

The following transform properties exist.


When the type is given as position, it may be an int, renpy.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
Type : (position, position)
Default : (0, 0)
The position, relative to the top-left corner of the containing area.

xpos
Type : position
Default : 0
The horizontal position, relative to the left side of the containing area.

ypos
Type : position
Default : 0
The vertical position, relative to the top of the containing area.

anchor
Type : (position, position)
Default : (0, 0)
The anchor position, relative to the top-left corner of the displayable.

xanchor
Type : position
Type : position
Default : 0
The horizontal anchor position, relative to the left side of the displayable.

yanchor
Type : position
Default : 0
The vertical anchor position, relative to the top of the displayable.

align
Type : (float, float)
Default : (0.0, 0.0)
Equivalent to setting pos and anchor to the same value.

xalign
Type : float
Default : 0.0
Equivalent to setting xpos and xanchor to this value.

yalign
Type : float
Default : 0.0
Equivalent to setting ypos and yanchor to this value.

xcenter
Type : float
Default : 0.0
Equivalent to setting xpos to the value of this property, and xanchor to 0.5.

ycenter
Type : float
Default : 0.0
Equivalent to setting ypos to the value of this property, and yanchor to 0.5.

rotate
Type : float or None
Default : None
If None, no rotation occurs. Otherwise, the image will be rotated by this many degrees
clockwise. Rotating the displayable causes it to be resized, according to the setting of
rotate_pad, below. This can cause positioning to change if xanchor and yanchor are not
0.5.

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.
that contains the transformed displayable. This is more suited to fixed rotations.

zoom
Type : float
Default : 1.0
This causes the displayable to be zoomed by the supplied factor.

xzoom
Type : float
Default : 1.0
This causes the displayable to be horizontally zoomed by the supplied factor. A negative
value causes the image to be flipped horizontally.

yzoom
Type : float
Default : 1.0
This causes the displayable to be vertically zoomed by the supplied factor. A negative
value causes the image to be flipped vertically.

alpha
Type : float
Default : 1.0
This controls the opacity of the displayable.

around
Type : (position, position)
Default : (0.0, 0.0)
If not None, specifies the polar coordinate center, relative to the upper-left of the
containing area. Setting the center using this allows for circular motion in position mode.

alignaround
Type : (float, float)
Default : (0.0, 0.0)
If not None, specifies the polar coordinate center, relative to the upper-left of the
containing area. Setting the center using this allows for circular motion in align mode.

angle
Type : float
Get the angle component of the polar coordinate position. This is undefined when the
polar coordinate center is not set.

radius
Type : position
Get the radius component of the polar coordinate position. This is undefined when the
polar coordinate center is not set.

crop
Type : None or (int, int, int, int)
Default : None
If not None, causes the displayable to be cropped to the given box. The box is specified as
a tuple of (x, y, width, height).

corner1
Type : None or (int, int)
Default : None
If not None, gives the upper-left corner of the crop box. This takes priority over crop.

corner2
Type : None or (int, int)
Default : None
If not None, gives the lower right corner of the crop box. This takes priority over crop.

size
Type : None or (int, int)
Default : None
If not None, causes the displayable to be scaled to the given size.

subpixel
Type : boolean
Default : False
If True, causes things to be drawn on the screen using subpixel positioning.

delay
Type : float
Default : 0.0
If this transform is being used as a transition, then this is the duration of the transition.

These properties are applied in the following order:

1. crop, corner1, corner2


2. size
3. zoom, xzoom, yzoom
4. rotate
5. position properties

Circular Motion

When an interpolation statement contains the clockwiseor counterclockwisekeywords, the


interpolation will cause circular motion. Ren'Py will compare the start and end locations and
figure out the polar coordinate center. Ren'Py will then compute the number of degrees it will
take to go from the start angle to the end angle, in the specified direction of rotation. If the
circles clause is given, Ren'Py will ensure that the appropriate number of circles will be made.
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.

External Events

The following events can be triggered automatically:


start
A pseudo-event, triggered on entering an on statement, if no event of higher priority has
happened.
show
Triggered when the transform is shown using the show or scene statement, and no image
with the given tag exists.
replace
Triggered when transform is shown using the show statement, replacing an image with the
given tag.
hide
Triggered when the transform is hidden using the hide statement or its python equivalent.
Note that this isn't triggered when the transform is eliminated via the scene statement or
exiting the context it exists in, such as when exiting the game menu.
replaced
Triggered when the transform is replaced by another. The image will not actually hide
until the ATL block finishes.
hover, idle, selected_hover, selected_idle
Triggered when button containing this transform, or a button contained by this transform,
enters the named state.

Customizing Ren'Py

Styles and Style Properties

Styles allow the look of displayables to be customized. This is done by changing the value of
style properties for displayables. For example, changing the backgroundproperty allows the
background of a window or button to be customized.
Each displayable has a style built-into it. When the displayable is created, either directly or
using the screen system, style properties can be supplied to it, and these styles are used to
update the look of the displayable. In the following example:

image big_hello_word = Text("Hello, World", size=40)

the sizeproperty is supplied to a Text displayable, allowing us to change its text size. This will
customize the look of the text displayable by displaying the text 40 pixels high.
Ren'Py also supports style inheritance. Each displayable takes a styleproperty, that gives the
name of the style to use. If a property is not defined for a style, Ren'Py will look it up in the
named style, that style's parent, and so on. This allows us to customize a named style in a
central place.

A named style exists as a field on the global styleobject. Style properties exist as fields on
styles. So to set the size property of the default style, one can use a python block:

init python:
style.default.font = "mikachan.ttf"
style.default.size = 23
As Ren'Py caches styles, named styles should not be changed outside of init blocks.

Style Property Prefixes

Applying a prefix to a style property indicates allows a displayable to change it's look in
response to its focus or selection status. For example, a button can change its color when the
mouse hovers above it, or to indicate when the choice represented by the button is the
currently selected one.
There are five states a displayable can be it.

insensitive
Used when the user cannot interact with the displayable.
idle
Used when the displayable is neither focused nor selected.
hover
Used when the displayable is focused, but not selected.
selected_idle
Used when the displayable is not focused, and is selected.
selected_hover
Used when the displayable is focused and selected.

Button and Bar displayables (and their variants) update their state, and the state of their
children, in response to events. For example, when the user puts his mouse over an unselected
button, it and all its children will be put into the hover state.
Style property prefixes allow one to set style properties for the different states. There is a
system of implications set up, so that a prefix can imply setting the property for more than one
state.
The implications are:
prefix states implied by prefix
(no prefix) insensitive, idle, hover, selected_idle,
selected_hover
insensitive_ insensitive
idle_ idle, selected_idle
selected_ selected_idle, selected_hover
selected_idle_ selected_idle
selected_hover_ selected_hover

Using a text button, we can show this in action. Text buttons use two styles by default: button
for the button itself, and button_textfor the text inside the button. The backgroundstyle
property sets the background of a button, while the colorproperty sets the color of text.

init python:

# The button background is gray when insensitive, light


# blue when hovered, and dark blue otherwise.
style.button.background = "#006"
style.button.insensitive_background = "#444"
style.button.hover_background = "#00a"

# The button text is yellow when selected, and white


# otherwise.
style.button_text.color = "#fff"
style.button_text.selected_color = "#ff0"

Style Property Values

Each style property expects a specific kind of data. Many of these are standard python types,
but a few are novel. Here are descriptions of the novel kinds of value a style property can
expect.

position
Positions are used to specify locations relative to the upper-left corner of the containing
area. (For positions, the containing area is given by the layout the displayable is in, if one
is given, or the screen otherwise. For anchors, the containing area is the size of the
displayable itself.)
The way a position value is interpreted depends on the type of the value:

int (like 0, 1, 37, or 42)


An integer is intepreted as the number of pixels from the left or top side of the
containing area.
float (like 0.0, 0.5, or 1.0)
A floating-point number is intepreted as a fraction of the containing area. For
example, 0.5 is a point halfway between the sides of the containing area, while 1.0 is
on the right or bottom side.
renpy.absolute (like renpy.absolute(100.25))
A renpy.absolute number is intepreted as the number of pixels from the left or top
side of the screen, when using subpixel-precise rendering.

displayable
Any displayable.
color
Colors in Ren'Py can be expressed as strings beginning with the hash mark (#), followed
by a hex triple or hex quadruple, with each of the three or four elements consisting of a
one or two hexidecimal character color code.
In a triple, the components represent red, green, and blue. In a quadruple, the
components represent red, green, blue, and alpha. For example:

"#f00"and "#ff0000"represent an opaque red color.


"#0f08"and #00ff0080"represent a semi-transparent green color.
The color triples are the same as used in HTML.
Colors can also be represented as a 4-component tuple, with the 4 components being
integers between 0 and 255. The components correspond to red, green, blue, and alpha,
in that order.

(0, 0, 255, 255)represents an opaque blue color.

List of All Style Properties

The style properties control the look of the various displayables. Not all style properties apply
to all displayables, so we've divided them up into groups.

Position Style Properties

These are used to control the position of a displayable inside the area allocated to it by a
layout, or on the screen when not inside a layout.
xpos- position
The position of the displayable relative to the left side of the containing area.

ypos- position
The position of the displayable relative to the right side of the containing area.

pos- tuple of (position, position)


Equivalent to setting xpos to the first component of the tuple, and ypos to the second
component of the tuple.

xanchor- position
The position of the anchor relative to the left side of the displayable.

yanchor- position
The position of the anchor relative to the top side of the displayable.

anchor- tuple of (position, position)


Equivalent to setting xanchor to the first component of the tuple, and yanchor to the
second component of the tuple.

xalign- float
Equivalent to setting xpos and xanchor to the same value. This has the effect of placing
the displayable at a relative location on the screen, with 0.0 being the left side, 0.5 the
center, and 1.0 being the right side.

yalign- float
Equivalent to setting ypos and yanchor to the same value. This has the effect of placing
the displayable at a relative location on the screen, with 0.0 being the top, 0.5 the center,
and 1.0 the bottom.

align- tuple of (float, float)


Equivalent to setting xalign to the first component of the tuple, and yalign to the second.

xcenter- position
Equivalent to setting xpos to the value of this property, and xanchor to 0.5.

ycenter- position
Equivalent to setting ypos to the value of tihis property, and yanchor to 0.5.

xoffset- int
Gives a number of pixels that are added to the horizontal position computed using xpos
and xalign.

yoffset- int
Gives a number of pixels that are added to the vertical position computed using ypos and
yalign.

xmaximum- int
Specifies the maximum horizontal size of the displayable, in pixels.

ymaximum- int
Specifies the maximum vertical size of the displayable in pixels.
maximum- tuple of (int, int)
Equivalent to setting xmaximum to the first component of the tuple, and ymaximum to the
second.

xminimum- int
Sets the minimum width of the displayable, in pixels. Only works with displayables that can
vary their size.

yminimum- int
Sets the minimum height of the displayables, in pixels. Only works with displayables that
can vary their size.

minimum- tuple of (int, int)


Equivalent to setting xminimum to the first component of the tuple, and yminimum to the
second.

xfill- boolean
If true, the displayable will expand to fill all available horizontal space. If not true, it will
only be large enough to contain its children.
This only works for displayables that can change size.

yfill- boolean
If true, the displayable will expand to fill all available horizontal space. If not true, it will
only be large enough to contain its children.
This only works for displayables that can change size.

area- tuple of (int, int, int, int)


The tuple is interpreted as (xpos, ypos, width, height). Attempts to position the displayable
such that it's upper-left corner is at xposand ypos, and its size is widthand height.
It does this by setting the xpos, ypos, xanchor, yanchor, xmaximum, ymaximum,
xminimum, yminimum, xfill, and yfill properties to appropriate values.
This will not work with all displayables and all layouts.

Text Style Properties

antialias- boolean
If True, the default, truetype font text will be rendered anti-aliased.

black_color- color
When rendering an image-based font, black will be mapped to this color. This has no
effect for truetype fonts.

bold- boolean
If True, render the font in a bold style. For a truetype font, this usually involves
synthetically increasing the font weight. It can also cause the font to be remapped, using
config.font_replacement_map.

caret- displayable or None


If not None, this should be a displayable. The input widget will use this as the caret at the
end of the text. If None, a 1 pixel wide line is used as the caret.

color- color
The color the text is rendered in. When using a truetype font, the font is rendered in this
color. When using an image-based font, white is mapped to this color.

first_indent- int
The amount that the first line of text in a paragraph is indented by, in pixels.

font- string
A string giving the name of the font used to render text.
For a truetype font file, this is usually the name of the file containing the font (like
"DejaVuSans.ttf"). To select a second font in a collection, this can be prefixed with a
number and at sign (like "0@font.ttc"or "1@font.ttc"). For an image-based font, this
should be the name used to register the font.

size- int
The size of the font on the screen. While this is nominally in pixels, font files may have
creative interpretations of this value.

italic- boolean
If true, the text will be rendered in italics. For a truetype font, this usually involves
synthetically increasing the font slant. It can also cause the font to be remapped, using
config.font_replacement_map.

justify- boolean
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.

kerning- float
A kerning adjustment, the number of pixels of space that's added between each pair of
characters. (This can be negative to remove space between characters.)

language- string
Controls the language family used to break text into lines. Legal values are:

"unicode"(default)
Uses the unicode linebreaking algorithm, which is suitable for most languages.
"korean-with-spaces"
Used for Korean text delimited by whitespace. This prevents linebreaking between
adjacent Korean characters.
"western
Allows breaking only at whitespace. Suitable for most languages.
"eastasian"
Legacy alias for "unicode".

layout- string
Controls how words are allocated to lines. Legal values are:

"tex"(default)
Uses the Knuth-Plass linebreaking algorithm, which attempts to minimize the
difference in line lengths of all but the last line.
"subtitle"
Uses the Knuth-Plass linebreaking algorithm, but attempts to even out the lengths of
all lines.
"greedy"
A word is placed on the first line that has room for it.
"nowrap"
Do not line-break.

line_leading- int
The number of pixels of spacing to include above each line.

line_overlap_split- int
When in slow text mode, and two lines overlap, this many pixels of the overlap are
allocated to the top line. Increase this if the bottoms of characters on the top line are
clipped.

line_spacing- int
The number of pixels of spacing to include below each line.

min_width- int
Sets the minimum width of each line of that. If a line is shorter than this, it is padded to this
length, with text_align used to specify where such padding is placed.

newline_indent- boolean
If true, the first_indentindentation is used after each newline in a string. Otherwise, the
rest_indentindentation is used.

outlines- list of tuple of (int, color, int, int)


This is a list of outlines that are drawn behind the text. Each tuple specifies an outline, and
outlines are drawn from back to front.
The list contains (size, color, xoffset, yoffset) tuples. Sizeis the amount the font is
expanded by, in pixels. Coloris the color of the outline. xoffsetand yoffsetare the
amount the outline is shifted by, in pixels.
The outline functionality can also be used to give drop-shadows to fonts, by specifiying a
size of 0 and non-zero offsets.
Outlines only work with truetype fonts.

rest_indent- int
Specifies the number of pixels the second and later lines in a paragraph are indented by.

ruby_style- style or None


If not None, this should be a style object. The style that's used for ruby text.

slow_cps- int or True


If a number, shows text at the rate of that many characters per second. If True, shows text
at the speed taken from the "Text Speed" preference.

slow_cps_multiplier- float
The speed of the text is multiplied by this number. This can be used to have a character
that speeks at a faster-than-normal rate of speed.

strikethrough- boolean
If True, a line is drawn through the text.

text_align- float
This is used when a line is shorter than the width of the text displayable. It determines how
much of the extra space is placed on the left side of the text. (And hence, the text
alignment.)
0.0 will yield left-aligned text, 0.5 centered text, and 1.0 right-aligned text.

underline- boolean
If true, an underline will be added to the text.

hyperlink_functions- tuple of (function, function, function)


This is a tuple of three functions relating to hyperlinks in text.
The first item is the hyperlink style function. When called with a single argument, the
argument of the hyperlink, it must return a style object to use for the hyperlink, such as
style.hyperlink_text. Note that a style object is not a string.
The second item is the hyperlink clicked function. This function is called when a hyperlink
is chosen by the user. If it returns a value other than None, the interaction returns that
value.
The third item is the hyperlink focus function. This function is called with the argument of
the hyperlink when the hyperlink gains focus, and with None when it loses focus. If it
returns a value other than None, the interaction returns that value

Window Style Properties

Window properties are used to specify the look of windows, frames, and buttons.

background- displayable or None


A displayable that is used as the background of the window. This is often a Frame(),
allowing the size of the background to scale with the size of the window.
If None, no background is drawn, but other properties function as if the background was
present.

foreground- displayable or None


If not None, this displayable is drawn above the contents of the window.

left_margin- int
The amount of transparent space to the left of the background, in pixels.

right_margin- int
The amount of transparent space to the right of the background, in pixels.

xmargin- int
Equivalent to setting left_margin and right_margin to the same value.

top_margin- int
The amount of transparent space above the background, in pixels.

bottom_margin- int
The amount of transparent space below the background, in pixels.

ymargin- int
Equivalent to setting top_margin and bottom_margin to the same value.

left_padding- int
The amount of space between the background and the left side of the window content, in
pixels.

right_padding- int
The amount of space between the background and the right side of the window content, in
pixels.

xpadding- int
Equivalent to setting left_padding and right_padding to the same value.

top_padding- int
The amount of space between the background and the top side of the window content, in
pixels.

bottom_padding- int
The amount of space between the background and the bottom side of the window content,
in pixels.

ypadding- int
Equivalent to setting top_padding and bottom_padding to the same value.

size_group- string or None


If not None, this should be a string. Ren'Py will render all windows with the same
size_group value at the same size.

Button Style Properties

hover_sound- string
A sound that is played when the button gains focus.

activate_sound- string
A sound that is played when the button is clicked.

mouse- string
The mouse style that is used when the button is focused. This should be one of the styles in
config.mouse.

focus_mask- displayable or True or None


A mask that's used to control what portions of the button can be focused, and hence
clicked on. If it's a displayable, then areas of the displayable that are not transparent can
be focused. If it's True, then the button itself is used as the displayable (so non-transparent
areas of the button can be focused.) Otherwise, the entire button can be focused.

Bar Style Properties

Bars are drawn with gutters on the left and right, that when clicked can cause the bart to move
by a small amount. The remaining space is the portion of the bar that can change, with the
amount on each side proportional to the bar's value as a fraction of the range.
The thumb is an area in the center of the bar that can be dragged by the user.
When a bar is drawn, the thumb's shadow is drawn first. Then the left/bottom and right/top
sides of the bar, followed by the thumb itself.
Note that the valid sides of a bar depend on the value of the bar_vertical property. If it's True,
the top and bottom sides are relevant. Otherwise, the left and right sides are used.
the top and bottom sides are relevant. Otherwise, the left and right sides are used.

bar_vertical- boolean
If true, the bar has a vertical orientation. If false, it has a horizontal orientation.

bar_invert- boolean
If true, the value of the bar is represented on the right/top side of the bar, rather than the
left/bottom side.

bar_resizing- boolean
If true, we resize the sides of the bar. If false, we render the sides of the bar at full size, and
then crop them.

left_gutter- int
The size of the gutter on the left side of the bar, in pixels.

right_gutter- int
The size of the gutter on the right side of the bar, in pixels.

top_gutter- int
The size of the gutter on the top side of the bar, in pixels.

bottom_gutter- int
The size of the gutter on the bottom side of the bar, in pixels.

left_bar- displayable
The displayable used for the left side of the bar.

right_bar- displayable
The displayable used for the right side of the bar.

top_bar- displayable
The displayable used for the top side of the bar.

bottom_bar- displayable
The displayable uses for the bottom side of the bar.

thumb- displayable or None


If not None, this is a displayable that is drawn over the break between the sides of the bar.

thumb_shadow- displayable or None


If not None, this is a displayable that is drawn over the break between the sides of the bar.

thumb_offset- int
The amount that 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 in pixels.

mouse- string
The mouse style that is used when the button is focused. This should be one of the styles in
config.mouse.

unscrollable- string or None


Controls what happens if the bar is unscrollable (if the range is set to 0, as is the case with
a viewport containing a displayable smaller than itself). There are three possible values:

None
Renders the bar normally.
"insensitive"
Renders the bar in the insensitive state. This allows the bat to change its style to
reflect its lack of usefulness.
"hide"
Prevents the bar from rendering at all. Space will be allocated for the bar, but nothing
will be drawn in that space.

Box Style Properties

These are used for the horizontal and vertical box layouts.

spacing- int
The spacing between members of this box, in pixels.

first_spacing- int
If not None, the spacing between the first and second members of this box, in pixels. This
overrides the spacing property.

box_wrap- boolean
If true, then boxes will wrap when they reach the end of a line or column. If false (the
default), they will extend past the end of the line.

Fixed Style Properties

These are used with the fixed layout.

fit_first- bool
If true, then the size of the fixed layout is shrunk to be equal with the size of the first item
in the layout.

Creating New Named Styles

Named styles exists as fields on the global styleobject. To create a new style, create an
instance of the Style class, and assign it to a field on the styleobject.

init python:
style.big_text = Style(style.default)
style.big_text.size = 42

Once created, a named style can be applied to displayables by supplying it's name, or the style
object.

screen two_big_lines:
vbox:
text "This is Big Text!" style "big_text"
text "So is this." style style.big_text

class Style( parent)


Creates a new style object. Style properties can be assigned to the fields of this object.
parent
The styles parent. This can be another style object, or a string.

clear()
This removes all style properties from this object. Values will be inherited from this
object's parent.

set_parent(parent)
Sets the parent of this style object to parent.

take(other)
This takes all style properties from other. othermust be a style object.

Indexed Styles

Indexed styles are lightweight styles that can be used to customize the look of a displayable
based on the data supplied to that displayable. An index style is created by indexing a style
object with a string or integer. If an indexed style does not exist, indexing creates it.

init python:
style.button['Foo'].background = "#f00"
style.button['Bar'].background = "#00f"

An index style is used by supplying the indexed style to a displayable.

screen indexed_style_test:
vbox:
textbutton "Foo" style style.button["Foo"]
textbutton "Bar" style style.button["Bar"]

Style Inheritance

When a property is not defined by a style, it is inherited from the style's parent. When indexing
is involved, properties are inherited first from the unindexed form of the style, then from the
indexed form of the parent, then the unindexed form of the parent, and so on.
For example, when style.mm_button inheritsfrom style.button, which in turn inherits from
style.default, then the properties of style.mm_button["Start Game"]are taken from:

1. style.mm_button["Start Game"]
2. style.mm_button
3. style.button["Start Game"]
4. style.button
5. style.default["Start Game"]
6. style.default

With the property value taken from the lowest numbered style with the property defined.

Style Preferences

It's often desireable to allow the user to customize aspects of the user interface that are best
expressed as styles. For example, a creator may want to give players of his game the ability to
adjust the look, color, and size of the text. Style preferences allow for this customization.
A style preference is a preference that controls one or more style properties. A style
preference has a name and one or more alternatives. At any given time, one of the

alternatives is the selected alternative for the style preference. The selected alternative is
alternatives is the selected alternative for the style preference. The selected alternative is
saved in the persistent data, and defaults to the first alternative registered for a style property.
An alternative has one or more associations of style, property, and value associated with it,
and represents a promise that when the alternative becomes the selected alternative for the
style preference, the property on the style will be assigned the given value. This occurs when
Ren'Py first initializes, and then whenever a new alternative is selected.
One should ensure that every alternative for a given style preference updates the same set of
styles and properties. Otherwise, some styles may not be assigned values, and the result will
not be deterministic.
The style preference functions are:

StylePreference(preference, alternative)
An action that causes alternativeto become the selected alternative for the given style
preference.

preference
A string giving the name of the style preference.
alternative
A string giving the name of the alternative.

renpy.get_style_preference(preference)
Returns a string giving the name of the selected alternative for the named style
preference.

preference
A string giving the name of the style preference.

renpy.register_style_preference(preference, alternative, style, property, value)


Registers information about an alternative for a style preference.

preference
A string, the name of the style property.
alternative
A string, the name of the alternative.
style
The style that will be updated. This may be a style object or a string giving the style
name.
property
A string giving the name of the style property that will be update.
value
The value that will be assigned to the style property.

renpy.set_style_preference(preference, alternative)
Sets the selected alternative for the style preference.

preference
A string giving the name of the style preference.
alternative
A string giving the name of the alternative.

Here's an example of registering a style property that allows the user to choose between
large, simple text and smaller outlined text.

init python:
renpy.register_style_property("text", "decorated", style.say_dialogue, "outlines",
renpy.register_style_property("text", "decorated", style.say_dialogue, "size", 22)

renpy.register_style_property("text", "large", style.say_dialogue, "outlines", [ ])


renpy.register_style_property("text", "large", style.say_dialogue, "size", 24)

The following code will allow the user to select these alternatives using buttons:

textbutton "Decorated" action StylePreference("text", "decorated")


textbutton "Large" action StylePreference("text", "large")

Other Style Functions

style.rebuild()
This causes named styles to be rebuilt, allowing styles to be changed outside of init code.

Warning
Named styles are not saved as part of the per-game data. This means that changes to them
will not be persisted through a save and load cycle.

Screens and Screen Language

The things that a user sees when looking at a Ren'Py game can be broken divided into images
and user interface. Images are displayed to the user using the scene, show, and hide
statements, and are generally part of the story being told. Everything else the user sees is part
of the user interface, which is customized using screens.
Screens can be displayed in four ways:

Implicitly, when script statements execute. For example, the say statement will cause the
sayscreen to be displayed.
Automatically. For example, Ren'Py will display the main_menuscreen when it starts
running, or when the user returns to the main menu.
As an action, associated with a button, mouse button, or keyboard key. By default, the
savescreen is shown when the user right-clicks or presses escape. It's also possible to
define an on-screen button that shows the savescreen.
Explicitly, using statements that cause screens to be shown.

More than one screen can be shown at a time.

Screens have two main functions. The first is to display information to the user. Information
can be displayed using text, bars, and images. Some of the information displayed in this
manner is vital to gameplay. The sayscreen, for example, is used to display dialogue to the
user, including the character's name and what she is saying.
The other thing a screen can do is to allow the user to interact with the game. Buttons and bars
allow the user to invoke actions and adjust values. Ren'Py includes a pool of pre-defined
actions, allowing the user to advance the game, control preferences, load and save games,
and invoke many other actions. A game-maker can also write new actions in Python.
Screens are updated at the start of each interaction, and each time an interaction is restarted.
Screen code must not cause side effects that are visible from outside the screen.
Ren'Py will run screen code multiple times, as it deems necessary. It runs screen code as part
of the image prediction process, before the screen is first shown. As a result, if screen code
has side effects, those side effects may occur at unpredictable times.
A screen has a scope associated with it, giving values to some variables. When a variable is
accessed by a screen, it's first looked up in the scope, and then looked up as a global variable.

Screen Language

The screen language is a mostly-declarative way of displaying screens. It consists of a


statement that declares a new screen, statements that add displayables to that screen, and
control statements.
Here's an example of a screen.:

screen say:
window id "window":
vbox:
spacing 10

text who id "who"


text what id "what"

The first line of this is a screen statement, a Ren'Py language statement that's used to declare
a screen. The name of the screen is say, so this is the screen that's used to display dialogue.
The screen contains a window, which has been given the id of "window". This window contains
a vertical box, and the spacing inside that box is 10 pixels. It contains two text fields, one of the
name of the speaker, and the other with the speaker's id.

Screen Language Syntax

Most screen language statements share a common syntax. (Some of the control statements
have other syntaxes.) A statement starts at the beginning of a line, with a keyword that
introduces the statement.
If a statement takes parameters, they immediately follow the keyword. The parameters are
space-separated simple expressions, unless otherwise noted.
The positional parameters are followed by a property list. A property consists of the property
name, followed by the value of that property. Property values are simple expressions, unless
otherwise noted. A property list is a space-separated list of these properties.

If a statement ends with a colon (:), then it takes a block. Each line in a block may be one of
two things:

A property list.
A screen language statement.

Screen Statement

The screenstatement is a Ren'Py script language statement that is used to declare a new
screen. It is parsed using the screen language common syntax.
It takes one parameter, the name of the screen. This is a name, not an expression. It takes the
following properties:

modal
If True, the screen is modal. A modal screen prevents the user from interacting with
displayables below it, except for the default keymap.
tag
Parsed as a name, not an expression. This specifies a tag associated with this screen.
Showing a screen replaces other screens with the same tag. This can be used to ensure
that only one screen of a menu is shown at a time, in the same context.
zorder
This controls how close to the user a screen is displayed. The larger the number, the
closer the screen is displayed to the user. It defaults to 0.
variant
If present, this should be a string giving the variant of screen to be defined. See Screen
Variants.

screen hello_world:
tag example
zorder 1
modal False

text "Hello, World."

User Interface Statements

The user interface statements create displayables and add them either to the screen, or to an
enclosing displayable. They allow the user to display information, allow the user to interact
with the game, or allow the game to react to various events.
All user interface statements take the following common properties:

at
A transform, or list of transforms, that are used to wrap this displayable. The show, hide,
replace, and replaced external events are delivered to a transform if and only if it is added
directly to the screen.
For example, if a vbox is wrapped in a transform, and added directly to the screen, then
events are delivered to that transform. But if a transform wraps a textbutton that is added
to the vbox, this second transform is not given events.
default
If given and true, the displayable is focused by default. Only one displayable should have
this.
id
An identifier for the user-interface statement. When a screen is shown, property values
can be supplied for the displayables with a given identifier. Some screens will require that
a displayable with a given identifier is created.
By default, the id is automatically-generated.
style
The name of the style applied to this displayable. This may be a string name, or a style
object. The style gives default values for style properties.
style_group
Style_group is used to provide a prefix to the style of a displayable, for this displayable and
all of its children (unless they have a more specific group set).
For example, if a vbox has a group of "pref", then the vbox will have the style
"pref_vbox", unless a more specific style is supplied to it. A button inside that vbox would
default to the style "pref_button".
Styles accessed in this way are automatically created, if they do not exist. This prevents an
error from being signalled.
Setting a group of Nonedisables this behavior for a displayable and all of its children.
focus
Takes a string or integer, and gives a name to the displayable for focus purposes. Ren'Py
looks for structural similarity between focus names when deciding with displayable to give
focus to at the start of an interaction. If a box is given a focus name, and the third button in
that box is focused at the end of an interaction, the third button of a box with the same will
be highlighted at the start of the next interaction.

Many user interface statements take classes of style properties, or transform properties. These
properties can have a style prefix associated with them, that determines when they apply. For
example, if text is given the hover_size property, it sets the text size when the text is hovered.

Add

Adds an image or other displayable to the screen. This optionally takes transform properties. If
at least one transform property is given, a Transform is created to wrap the image, and the
properties are given to the transform.
This does not take any children.

screen add_test:
add "logo.png" xalign 1.0 yalign 0.0

Bar

Creates a horizontally-oriented bar that can be used to view or adjust data. It takes the
following properties:

value
The current value of the bar. This can be either a BarValue object, or a number.
range
The maximum value of the bar. This is required if valueis a number.
adjustment
A ui.adjustment()object that this bar adjusts.
changed
If given, this should be a python function. The function is called with the value of the
adjustment when the adjustment is changed.
hovered
An action to run when the bar gains focus.
unhovered
An action to run when the bar loses focus.

One of valueor adjustmentmust be given. In addition, this function takes:

Common Properties
Position Style Properties
Bar Style Properties

This does not take children.

screen volume_controls:
frame:
has vbox

bar value Preference("sound volume")


bar value Preference("music volume")
bar value Preference("voice volume")

Button

Creates an area of the screen that can be activated to run an action. A button takes no
parameters, and the following properties.

action
The action to run when the button is activated. This also controls if the button is sensitive,
and if the button is selected.
hovered
An action to run when the button gains focus.
unhovered
An action to run when the button loses focus.

It also takes:

Common Properties
Position Style Properties
Window Style Properties
Button Style Properties

It takes one children. If zero, two, or more children are supplied, they are implicitly added to a
fixed, which is added to the button.

Fixed

This creates an area to which children can be added. By default, the fixed expands to fill the
available area, but the xmaximumand ymaximumproperties can change this.
The children are laid out according to their position style properties. They can overlap if not
positioned properly.

The fixed statement takes no parameters, and the following groups of properties:

Common Properties
Position Style Properties
Fixed Style Properties

This takes any number of children, which are added to the fixed.
It's often unnecessary to explicitly create a fixed displayable. Each screen is contained within a
fixed displayable, and many screen language statements automatically create a fixed
displayable if they have two or more children.

screen ask_are_you_sure:
fixed:
text "Are you sure?" xalign 0.5 yalign 0.3
textbutton "Yes" xalign 0.33 yalign 0.5 action Return(True)
textbutton "No" xalign 0.66 yalign 0.5 action Return(False)

Frame

A frame is a window that contains a background that is intended for displaying user-interface
elements like buttons, bars, and text. It takes the following groups of properties:

Common Properties
Position Style Properties
Window Style Properties

It takes one child. If zero, two, or more children are supplied, then a fixed is created to contain
them.

screen test_frame:
frame:
xpadding 10
ypadding 10
xalign 0.5
yalign 0.5

vbox:
text "Display"
null height 10
textbutton "Fullscreen" action Preference("display", "fullscreen")
textbutton "Window" action Preference("display", "window")

Grid

This displays its children in a grid. Each child is given an area of the same size, the size of the
largest child.
It takes two parameters. The first is the number of columns in the grid, and the second is the
number of rows in the grid. It takes the following property:

transpose
If False (the default), rows are filled before columns. If True, then columns are filled before
rows.
spacing
The spacing between the rows and columns of the grid.

It also takes:

Common Properties
Position Style Properties

This must be given columns * rows children. Giving it a different number of children is an error.

screen grid_test:
grid 2 3:
text "Top-Left"
text "Top-Right"

text "Center-Left"
text "Center-Right"

text "Bottom-Left"
text "Bottom-Right"

Hbox

This displays its children side by side, in an invisible horizontal box. It takes no parameters, and
the following groups of properties:

Common Properties
Position Style Properties
Box Style Properties

UI displayable children are added to the box.

screen hbox_text:
hbox:
text "Left"
text "Right"

Imagebutton

Creates a button consisting of images, that change state when the user hovers over them. This
takes no parameters, and the following properties:

auto
Used to automatically define the images used by this button. This should be a string that
contains %s in it. If it is, and one of the image properties is omitted, %s is replaced with the
name of that property, and the value is used as the default for that property.
For example, if autois "button_%s.png", and idleis omitted, then idle defaults to
"button_idle.png".
The behavior of autocan be customized by changing config.imagemap_auto_function.
insensitive
The image used when the button is insensitive.
idle
The image used when the button is not focused.
hover
The image used when the button is focused.
selected_idle
The image used when the button is selected and idle.
selected_hover
The image used when the button is selected and hovered.
action
The action to run when the button is activated. This also controls if the button is sensitive,
and if the button is selected.
hovered
An action to run when the button gains focus.
unhovered
An action to run when the button loses focus.

It also takes:
Common Properties
Position Style Properties
Window Style Properties
Button Style Properties

This takes no children.

screen gui_game_menu:
vbox xalign 1.0 yalign 1.0:
imagebutton auto "save_%s.png" action ShowMenu('save')
imagebutton auto "prefs_%s.png" action ShowMenu('preferences')
imagebutton auto "skip_%s.png" action Skip()
imagebutton auto "afm_%s.png" action Preference("auto-forward mode", "toggle"

Input

Creates a text input area, which allows the user to enter text. When the user presses return,
the text will be returned by the interaction. This takes no parameters, and the following
properties:

default
The default text in this input.
length
The maximum length of the text in this input.
allow
A string containing characters that are allowed to be typed into this input. (By default,
allow all characters.)
exclude
A string containing characters that are disallowed from being typed into this input. (By
default, "{}".)
prefix
An immutable string to prepend to what the user has typed.
suffix
An immutable string to append to what the user has typed.
changed
A python function that is called with what the user has typed, when the string changes.

It also takes:

Common Properties
Position Style Properties
Text Style Properties

This does not take any children.

screen input_screen:
window:
has vbox

text "Enter your name."


input default "Joseph P. Blow, ESQ."
Key

This creates a keybinding that runs an action when a key is pressed. Key is used in a loose
sense here, as it also allows joystick and mouse events.
Key takes one positional parameter, a string giving the key to bind. See the `Keymap`_ section
for a description of available keysyms. It takes one property:

action
This gives an action that is run when the key is pressed. This property is mandatory.

It takes no children.

screen keymap_screen:
key "game_menu" action ShowMenu('save')
key "p" action ShowMenu('preferences')
key "s" action Screenshot()

Label

Creates a window in the label style, and then places text inside that window. Together, this
combination is used to label things inside a frame.
It takes one positional argument, the text of the label. It takes the property:

text_style
The name of the style to use for the button text. If not supplied, and the styleproperty is a
string, then "_text"is appended to that string to give the default text style.
text_-
Other properties prefixed with text have this prefix stripped, and are then passed to the
text displayable.

It also takes:

Common Properties
Position Style Properties
Window Style Properties

It does not take children.

screen display_preference:
frame:
has vbox

label "Display"
textbutton "Fullscreen" action Preference("display", "fullscreen")
textbutton "Window" action Preference("display", "window")

Null

The null statement inserts an empty area on the screen. This can be used to space things out.
The null statement takes no parameters, and the following properties:

width
The width of the empty area, in pixels.
height
The height of the empty area, in pixels.

It also takes:

Common Properties
Position Style Properties

It does not take children.

screen text_box:
vbox:
text "The title."
null height 20
text "This body text."

Mousearea

A mouse area is an area of the screen that can react to the mouse entering or leaving it.
Unlike a button, a mouse area does not take focus, so it's possible to have a mouse area with
buttons inside it. The mousearea statement takes not parameters, and the following
properties:

hovered
An action to run when the mouse enters the mouse area.
unhovered
An action to run when the mouse leaves the mouse area.

It also takes:

Common Properties
Position Style Properties

It does not take children.

Usually, a mousearea statement is given the areastyle property, which controls the size and
position of the mouse area. Without some way of controlling its size, the mouse area would
take up the entire screen, a less useful behavior.

Note
Since Ren'Py games can be played using the keyboard and joystick, it often makes sense to
duplicate mousearea functionality by some other means.

screen button_overlay:
mousearea:
area (0, 0, 1.0, 100)
hovered Show("buttons", transition=dissolve)
unhovered Hide("buttons", transition=dissolve)

screen buttons:
hbox:
textbutton "Save" action ShowMenu("save")
textbutton "Prefs" action ShowMenu("preferences")
textbutton "Skip" action Skip()
textbutton "Auto" action Preference("auto-forward", "toggle")

label start:
show screen button_overlay
Side

This positions displayables in the corners or center of a grid. It takes a single parameter, string
containing a space-separated list of places to place its children. Each component of this list
should be one of:

'c', 't', 'b', 'l', 'r', 'tl', 'tr', 'bl', 'br'

'c' means center, 't' top, 'tl' top left, 'br' bottom right, and so on.
A side taks the following properties:

spacing
The spacing between the rows and columns of the grid.

A side takes the following property groups:

Common Properties
Position Style Properties

When being rendered, this first sizes the corners, then the sides, then the center. The corners
and sides are rendered with an available area of 0, so it may be necessary to supply them a
minimum size (using xminimumor yminimum) to ensure they render at all.
Children correspond to entries in the places list, so this must have the same number of
children as there are entries in the places list.

screen side_test:
side "c tl br":
text "Center"
text "Top-Left"
text "Bottom-Right"

Text

The text statement displays text. It takes a single parameter, the text to display. It also takes
the following groups of properties:

Common Properties
Position Style Properties
Text Style Properties

It does not take children.

screen hello_world:
text "Hello, World." size 40

Textbutton

Creates a button containing a text label. The button takes a single parameter, the text to
include as part of the button. It takes the following properties:

action
The action to run when the button is activated. This also controls if the button is sensitive,
and if the button is selected.
hovered
An action to run when the button gains focus.
unhovered
An action to run when the button loses focus.
text_style
The name of the style to use for the button text. If not supplied, and the styleproperty is a
string, then "_text"is appended to that string to give the default text style.
text_-
Other properties prefixed with text have this prefix stripped, and are then passed to the
text displayable.

It also takes:

Common Properties
Position Style Properties
Window Style Properties
Button Style Properties

It does not take children.

screen textbutton_screen:
vbox:
textbutton "Wine" action Jump("wine")
textbutton "Women" action Jump("women")
textbutton "Song" action Jump("song")

Timer

This creates a timer that runs an action when time runs out. It takes one positional parameter,
giving the timeout time, in seconds. It takes the properties:

action
This gives an action that is run when the timer expires. This property is mandatory.
repeat
If True, the timer repeats after it times out.

It takes no children.

screen timer_test:
vbox:
textbutton "Yes." action Jump("yes")
textbutton "No." action Jump("no")

timer 3.0 action Jump("too_slow")

Transform

Applies a transform to its child. This takes no parameters, and the following property groups :

Common Properties
Transform Properties

This should take a single child.

Vbar

The vertically oriented equivalent of bar. Properties are the same as bar.
screen volume_controls:
frame:
has hbox

vbar value Preference("sound volume")


vbar value Preference("music volume")
vbar value Preference("voice volume")

Vbox

This displays its children one above the other, in an invisible vertical box. It takes no
parameters, and the following groups of properties:

Common Properties
Position Style Properties
Box Style Properties

UI displayable children are added to the box.

screen vbox_test:
vbox:
text "Top."
text "Bottom."

Viewport

A viewport is area of the screen that can be scrolled by dragging, with the mouse wheel, or
with scrollbars. It can be used to display part of something that is bigger than the screen. It
takes the following properties:

child_size
The size that is offered to the child for rendering. An (xsize, ysize) tuple. This can usually
be omitted, when the child can compute it's own size. If either component is None, the
child's size is used.
mousewheel
If True, the mouse wheel can be used to scroll the viewport.
draggable
If True, dragging the mouse will scroll the viewport.
xadjustment
The ui.adjustment()used for the x-axis of the viewport. When omitted, a new adjustment
is created.
yadjustment
The ui.adjustment()used for the y-axis of the viewport. When omitted, a new adjustment
is created.
xinitial
The initial horizontal offset of the viewport. This may be an integer giving the number of
pixels, or a float giving a fraction of the possible offset.
yinitial
The initial vertical offset of the viewport. This may be an integer giving the number of
pixels, or a float giving a fraction of the possible offset.
scrollbars
If not None, scrollbars are added allong with this viewport. This works by creating a side
layout, and placing the created viewport in the center of the side. If scrollbarsis
"horizontal", a horizontal scrollbar is placed beneath the viewport. If scrollbarsis
"vertical", a vertical scrollbar is placed to the right of the viewport. If scrollbarsis "both",
both horizontal and vertical scrollbars are created.
If scrollbarsis not None, the viewport takes properties prefixed with "side". These are
passed to the created side layout.

In addition, it takes the following groups of style properties:

Common Properties
Position Style Properties

It takes one child. If zero, two, or more children are supplied, then a fixed is created to contain
them.
To make a viewport scrollable, it's often best to assign an id to it, and then use XScrollValue()
and YScrollValue()with that id.

screen viewport_example:
side "c b r":
area (100, 100, 600, 400)

viewport id "vp":
draggable True

add "washington.jpg"

bar value XScrollValue("vp")


vbar value YScrollValue("vp")

Window

A window is a window that contains a background that is intended for displaying in-game
dialogue. It takes the following groups of properties:

Common Properties
Position Style Properties
Window Style Properties

It takes one child. If zero, two, or more children are supplied, then a fixed is created to contain
them.

screen say:
window id "window"
vbox:
spacing 10

text who id "who"


text what id "what"

Imagemap Statements

A convenient way of creating a screen, especially for those who think visually is to create an
imagemap. When creating an imagemap, the imagemap statement is used to specify up to six
images. The hotspot and hotbar images are used to carve rectangular areas out of the image,
and apply actions and values to those areas.

Here's an example of a preferences screen that uses imagemaps.


screen preferences:

tag menu
use navigation

imagemap:
auto "gui_set/gui_prefs_%s.png"

hotspot (740, 232, 75, 73) clicked Preference("display", "fullscreen")


hotspot (832, 232, 75, 73) clicked Preference("display", "window")
hotspot (1074, 232, 75, 73) clicked Preference("transitions", "all")
hotspot (1166, 232, 75, 73) clicked Preference("transitions", "none")

hotbar (736, 415, 161, 20) value Preference("music volume")


hotbar (1070, 415, 161, 20) value Preference("sound volume")
hotbar (667, 535, 161, 20) value Preference("voice volume")
hotbar (1001, 535, 161, 20) value Preference("text speed")

Imagemap

The imagemap statement is used to specify an imagemap. It takes no parameters, and the
following properties:

auto
Used to automatically define the images used by this imagemap. This should be a string
that contains %s in it. If it is, and one of the image properties is omitted, %s is replaced
with the name of that property, and the value is used as the default for that property.
For example, if autois "imagemap_%s.png", and idleis omitted, then idle defaults to
"imagemap_idle.png".
The behavior of autocan be customized by changing config.imagemap_auto_function.
ground
The image used for portions of the imagemap that are not part of a hotspot or hotbar.
insensitive
The image used when a hotspot or hotbar is insensitive.
idle
The image used when a hotspot is not selected and not focused, and for the empty portion
of unfocused hotbars.
hover
The image used when a hotspot is not selected and focused, and for the empty portion of
focused hotbars.
selected_idle
The image used when a hotspot is selected and not focused, and for the full portion of
unfocused hotbars.
selected_hover
The image used when a hotspot is selected and focused, and for the full portion of focused
hotbars.
alpha
If true, the default, a hotspot only gains focus when the mouse is in an area of the hover
image that is opaque. If false, the hotspot gains focus whenever the mouse is within its
rectangular boundary.
cache
If true, the default, hotspot data is cached in to improve performance at the cost of some
additional disk space.

It takes the following groups of properties:

Common Properties
Position Style Properties
Fixed Style Properties

An imagemap creates a fixed, allowing any child to be added to it (not just hotspots and
hotbars).

Hotspot

A hotspot is a button consisting of a portion of the imagemap that contains it. It takes a single
parameter, a (x, y, width, height) tuple giving the area of the imagemap that makes up the
button. It also takes the following properties:

action
The action to run when the button is activated. This also controls if the button is sensitive,
and if the button is selected.
hovered
An action to run when the button gains focus.
unhovered
An action to run when the button loses focus.

It also takes:

Common Properties
Button Style Properties

A hotspot creates a fixed, allowing children to be added to it. The fixed has an area that is the
same size as the hotspot, meaning that the children will be positioned relative to the hotpsot.

Hotbar

A hotbar is a bar that consists of a portion of the imagemap that contains it. It takes a single
parameter, a (x, y, width, height) tuple giving the area of the imagemap that makes up the
button. It also takes the following properties:

value
The current value of the bar. This can be either a Value object, or a number.
range
The maximum value of the bar. This is required if valueis a number.
adjustment
A ui.adjustment()object that this bar adjusts.

One of valueor adjustmentmust be given. In addition, this function takes:

Common Properties
Bar Style Properties

This does not take children.

Advanced Displayables
In addition to the commonly-used statements, the screen language has statements that
correspond to advanced displayables. The mapping from displayable to statement is simple.
Positional parameters of the displayables become positional parameters of the statement.
Keyword arguments and the relevant style properties become screen language properties.
The advanced displayable statements are:

drag
Creates a Drag. A drag can be given an optional child, or the childstyle property can be
used to supply the child, and its focused variants.
draggroup
Creates a DragGroup. A drag group may have zero or more drags as its children.

Has Statement

The has statment allows you to specify a container to use, instead of fixed, for statements that
take only one child. The has statement may only be used inside a statement that takes one
child. The keyword hasis followed (on the same line) by another statement, which must be a
statement that creates a container displayable, one that takes more than one child.

The has statement changes the way in which the block that contains it is parsed. Child
displayables created in that block are added to the container, rather than the parent
displayable. Keyword arguments to the parent displayable are not allowed after the has
statement. Multiple has statements can be used in the same block.
The has statement can be supplied as a child of the following statements:

button
frame
window

The has statement can be given the following statements as a container.

fixed
grid
hbox
side
vbox

screen volume_controls:
frame:
has vbox

bar value Preference("sound volume")


bar value Preference("music volume")
bar value Preference("voice volume")

Control Statements

The screen language includes control statements for conditional execution, iteration, including
other screens, executing actions when events occur, and executing arbitrary python code.

Default

The default statement sets the default value of a variable, if it is not passed as an argument to
the screen, or inherited from a screen that calls us using the use statement.

screen message:
default message = "No message defined."
default message = "No message defined."
text message

For

The for statement is similar to the Python for statment, except that it does not support the else
clause. It supports assignment to (optionally nested) tuple patterns, as well as variables.

$ numerals = [ 'I', 'II', 'III', 'IV', 'V' ]

screen five_buttons:
vbox:
for i, numeral in enumerate(numerals):
textbutton numeral action Return(i + 1)

If

The screen language if statement is the same as the Python/Ren'Py if statement. It supports
the if, elif, and else clauses.

screen skipping_indicator:
if config.skipping:
text "Skipping."
else:
text "Not Skipping."

On

The on statement allows the screen to execute an action when an event occurs. It takes one
parameter, a string giving the name of an event. This should be one of:

"show"
"hide"
"replace"
"replaced"

It then takes an action property, giving an action to run if the event occurs.

screen preferences:
frame:
has hbox

text "Display"
textbutton "Fullscreen" action Preferences("display", "fullscreen")
textbutton "Window" action Preferences("display", "window")

on "show" action Show("navigation")


on "hide" action Hide("navigation")

Use

The use statement allows a screen to include another. The use statement takes the name of
the screen to use. This can optionally be followed by a keyword argument list, in parenthesis.
The scope of the included code includes the scope of the current statement's code, updated
by assinging the parameters their new values.
screen file_slot:
button:
action FileAction(slot)

has hbox

add FileScreenshot(slot)
vbox:
text FileTime(slot, empty="Empty Slot.")
text FileSaveName(slot)

screen save:
grid 2 5:
for i in range(1, 11):
use file_slot(slot=i)

Python

The screen language also includes single-line and multiple-line python statements, which can
execute python code. This code runs in the scope of the screen.
Python code must not cause side effects that are visible from outside the screen.
Ren'Py will run screen code multiple times, as it deems necessary. It runs screen code as part
of the image prediction process, before the screen is first shown. As a result, if screen code
has side effects, those side effects may occur at unpredictable times.

screen python_screen:
python:
test_name = "Test %d" % test_number

text test_name

$ test_label = "test_%d" % test_label

textbutton "Run Test" action Jump(test_label)

Screen Statements

In addition to the screen statement, there are three Ren'Py script language statements that
involve screens.
Two of these statements take a keyword argument list. This is a python argument list, in
parenthesis, consisting of only keyword arguments. Positional arguments, extra positional
arguments (*), and extra keyword arguments (**) are not allowed.

Show Screen

The show screen statement causes a screen to be shown. It takes an screen name, and an
optional argument list. If present, the arguments are used to intialize the scope of the screen.
Screens shown in this way are displayed until they are explicitly hidden. This allows them to be
used for overlay purposes.

show screen overlay_screen


show screen clock_screen(hour=11, minute=30)

Hide Screen
The hide screen statement is used to hide a screen that is currently being shown. If the screen
is not being shown, nothing happens.

hide screen overlay_screen


hide screen clock

Call Screen

The call screen statement shows a screen, and then hides it again at the end of the current
interaction. If the screen returns a value, then the value is placed in _return.
This can be used to display an imagemap. The imagemap can place a value into the _return
variable using the Return()action, or can jump to a label using the Jump()action.

call screen my_imagemap

Screen Variants

Ren'Py runs both on traditional mouse-oriented devices such as Windows, Mac, and Linux PCs,
and newer touch-oriented devices such as Android-based smartphones and tablets. Screen
variants allow a game to supply multiple versions of a screen, and use the version that best
matches the hardware it is running on.

Ren'Py chooses a screen variant to use by searching variants in the order they are listed in
config.variants. The first variant that exists is used.

If the RENPY_VARIANT environment variable is present, config.variants is initialized by splitting


the value of the variable on whitespace, and then appending None. Setting RENPY_VARIANT to
a value such as "tablet touch"or "phone touch"allows screens intended for Android devices
to be tested on a PC.
If the environment variable is not present, a list of variants is built up automatically, by going
through the following list in order and choosing the entries that apply to the current platform.

"tablet"
Defined on touchscreen based devices where the screen has a diagonal size of 6 inches or
more.
"phone"
Defined on touchscren-based devices where the diagonal size of the screen is less than 6
inches. On such a small device, it's important to make buttons large enough a user can
easily choose them.
"touch"
Defined on touchscreen-based devices, such as those running the Android platform.
"pc"
Defined on Windows, Mac OS X, and Linux. A PC is expected to have a mouse and
keyboard present, to allow buttons to be hovered, and to allow precise pointing.
None
Always defined.

An example of defining a screen variant is:

# A variant hello_world screen, used on small touch-based


# devices.
screen hello_world:
tag example
zorder 1
modal False
variant "touch"

text "Hello, World." size 30

Screen Actions, Values, and Functions

Ren'Py ships with a number of actions, values, and functions intended for use with screens and
the screen language.

Actions

Actions are invoked when a button (including imagebuttons, textbuttons, and hotspots) is
activated, hovered, or unhovered. Actions may determine when a button is selected or
insensitive.

Along with these actions, an action may be a function that does not take any arguments. The
function is called when the action is invoked. If the action returns a value, then the value is
returned from an interaction.
An action may also be a list of actions, in which case the actions in the list are run in order.

Control Actions

These are actions that manage screens, interaction results, and control flow.

Hide(screen, transition=None)
This causes the screen named screento be hidden, if it is shown.

transition
If not None, a transition that occurs when hiding the screen.

Jump(label)
Causes control to transfer to the given label. This can be used in conjunction with
renpy.run_screen to define an imagemap that jumps to a label when run.

Return(value=None)
Causes the current interaction to return the supplied value. This is often used with menus
and imagemaps, to select what the return value of the interaction is.
When in a menu, this returns from the menu.

Show(screen, transition=None, **kwargs)


This causes another screen to be shown. screenis a string giving the name of the screen.
The keyword arguments are passed to the screen being shown.
If not None, transitionis use to show the new screen.

ShowTransient(screen, **kwargs)
Shows a transient screen. A transient screen will be hidden when the current interaction
completes.

Data Actions

These set or toggle data.

SetDict(dict, key, value)


Causes the value of keyin dictto be set to value.

SetField(object, field, value)


Causes the a field on an object to be set to a given value. objectis the object, fieldis a
string giving the name of the field to set, and valueis the value to set it to.

SetScreenVariable(name, value)
Causes the variable nameassociated with the current screen to be set to value.

SetVariable(variable, value)
Causes variableto be set to value.

ToggleDict(dict, key, true_value=None, false_value=None)


Toggles the value of keyin dict. Toggling means to invert the value when the action is
performed.

true_value
If not None, then this is the true value we use.
false_value
If not None, then this is the false value we use.

ToggleField(object, field, true_value=None, false_value=None)


Toggles fieldon object. Toggling means to invert the boolean value of that field when
the action is performed.

true_value
If not None, then this is the true value we use.
false_value
If not None, then this is the false value we use.

ToggleScreenVariable(name, true_value=None, false_value=None)


Toggles the value of the variable namein the current screen.

true_value
If not None, then this is the true value we use.
false_value
If not None, then this is the false value we use.

ToggleVariable(variable, true_value=None, false_value=None)


Toggles variable.

true_value
If not None, then this is the true value we use.
false_value
If not None, then this is the false value we use.

Menu Actions

These actions invoke menus, or are primarily useful while in the main or game menus.

MainMenu(confirm=True)
Causes Ren'Py to return to the main menu.

confirm
If true, causes Ren'Py to ask the user if he wishes to return to the main menu, rather
than returning directly.

Quit(confirm=True)
Quits the game.

confirm
If true, prompts the user if he wants to quit, rather than quitting directly.

ShowMenu(screen=None)
Causes us to enter the game menu, if we're not there already. If we are in the game menu,
then this shows a screen or jumps to a label.
screenis usually the name of a screen, which is shown using the screen mechanism. If the
screen doesn't exist, then "_screen" is appended to it, and that label is jumped to.

ShowMenu("load")
ShowMenu("save")
ShowMenu("preferences")
This can also be used to show user-defined menu screens. For example, if one has a
"stats" screen defined, one can show it as part of the game menu using:

ShowMenu("stats")
ShowMenu without an argument will enter the game menu at the default screen, taken
from _game_menu_screen.

Start(label='start')
Causes Ren'Py to jump out of the menu context to the named label. The main use of this is
to start a new game from the main menu. Common uses are:

Start() - Start at the start label.


Start("foo") - Start at the "foo" label.

File Actions

These actions handle saving, loading, and deleting of files. Many of these take the nameand
pagearguments.
name
The name of the file to save to. This can be a string or an integer. It's combined with the
page to create the filename.
page
The page that this action acts on. This is one of "auto", "quick", or a positive integer. If
None, the page is determined automatically, based on a persistent page number.

FileAction(name, page=None)
"Does the right thing" with the file. This means loading it if the load screen is showing, and
saving to it otherwise.

name
The name of the slot to save to or load from. If None, an unused slot (a large number
based on the current time) will be will be used.
page
The page that the file will be saved to or loaded from. If None, the current page is
used.

FileDelete(name, confirm=True, page=None)


Deletes the file.

confirm
If true, prompts before deleting a file.

FileLoad(name, confirm=True, page=None, newest=True)


Loads the file.

name
The name of the slot to load from. If None, an unused slot the file will not be loadable.
confirm
If true, prompt if loading the file will end the game.
page
The page that the file will be loaded from. If None, the current page is used.
newest
If true, the button is selected if this is the newest file.

FilePage(page)
Sets the file page to page, which should be one of "auto", "quick", or an integer.

FilePageNext(max=None)
Goes to the next file page.

max
If set, this should be an integer that gives the number of the maximum file page we
can go to.

FilePagePrevious(self)
Goes to the previous file page, if possible.

FileSave(name, confirm=True, newest=True, page=None, cycle=False)


Saves the file.
The button with this slot is selected if it's marked as the newest save file.

name
The name of the slot to save to. If None, an unused slot (a large number based on the
current time) will be will be used.
confirm
If true, then we will prompt before overwriting a file.
newest
If true, then this file will be marked as the newest save file when it's saved.
page
The name of the page that the slot is on. If None, the current page is used.
cycle
If true, then saves on the supplied page will be cycled before being shown to the user.

FileTakeScreenshot()
Take a screenshot to be used when the game is saved. This can be used to ensure that the
screenshot is accurate, by taking a pictue of the screen before a file save screen is shown.

QuickLoad()
Performs a quick load.

QuickSave(message='Quick save complete.', newest=False)


Performs a quick save.

message
A message to display to the user when the quick save finishes.
newest
Set to true to mark the quicksave as the newest save.

Audio Actions

Play(channel, file, **kwargs)


Causes an audio file to be played on a given channel.

channel
The channel to play the sound on.
file
The file to play.

Any keyword arguments are passed to renpy.music.play()

Queue(channel, file, **kwargs)


Causes an audio file to be queued on a given channel.

channel
The channel to play the sound on.
file
The file to play.

Any keyword arguments are passed to renpy.music.queue()

SetMixer(mixer, volume)
Sets the volume of mixerto value.

mixer
The mixer to set the volume of. A string, usually one of "music", "sfx", or "voice".
value
The value to set the volume to. A number between 0.0 and 1.0, inclusive.

Stop(channel, **kwargs)
Causes an audio channel to be stopped.

channel
The channel to play the sound on.
file
The file to play.

Any keyword arguments are passed to renpy.music.play()

Other Actions

These are other actions, not found anywhere else.

Help(help=None)
Displays help.

help
If this is a string giving a label in the programe, then that label is called in a new
context when the button is chosen. Otherwise, it should be a string giving a file that is
opened in a web browser. If None, the value of config.help is used in the same wayt.

If(expression, true=None, false=None)


This returns trueif expressionis true, and falseotherwise. Use this to select an action
based on an expression. Note that the default, None, can be used as an action that causes
a button to be disabled.

InvertSelected(action)
This inverts the selection state of the provided action, while proxying over all of the other
methods.

Language(language)
Changes the language of the game to language. A language change causes the current
statement to be restarted, and all contexts but the outermost being exited.

language
A string giving the language to translate to, or None to use the language given in the
game script.

Notify(message)
Displays messageusing renpy.notify().

OpenURL(url)
Causes urlto be opened in a web browser.

RollForward()
This action causes a rollforward to occur, if a roll forward is possible. Otherwise, it is
insensitive.

Rollback()
This action causes a rollback to occur, when a rollback is possible. Otherwise, nothing
happens.

Screenshot()
Takes a screenshot.

SelectedIf(expression)
This allows an expression to control if a button should be marked as selected. It should be
used as part of a list with one or more actions. For example:

# The button is selected if mars_flag is True


textbutton "Marsopolis":
action [ Jump("mars"), SelectedIf(mars_flag) ]

Skip()
Causes the game to begin skipping. If the game is in a menu context, then this returns to
the game. Otherwise, it just enables skipping.

With(transition)
Causes transitionto occur.

Values

Values are used with bars, to set the bar value, and to allow the bar to adjust an underlying
property.

AnimatedValue(value=0.0, range=1.0, delay=1.0, old_value=None)


This animates a value, taking delayseconds to vary the value from old_valueto value.
value
The value itself, a number.
range
The range of the value, a number.
delay
The time it takes to animate the value, in seconds. Defaults to 1.0.
old_value
The old value. If this is None, then the value is taken from the AnimatedValue we
replaced, if any. Otherwise, it is initialized to value.

FieldValue(object, field, range, max_is_zero=False, style='bar', offset=0, step=None)


A value that allows the user to adjust the value of a field on an object.

object
The object.
field
The field, a string.
range
The range to adjust over.
max_is_zero
If True, then when the field is zero, the value of the bar will be range, and all other
values will be shifted down by 1. This works both ways - when the bar is set to the
maximum, the field is set to 0.
This is used internally, for some preferences.
style
The styles of the bar created.
offset
An offset to add to the value.
step
The amount to change the bar by. If None, defaults to 1/10th of the bar.

MixerValue(mixer)
The value of an audio mixer.

mixer
The name of the mixer to adjust. This is usually one of "music", "sfx", or "voice", but
user code can create new mixers.

StaticValue(value=0.0, range=1.0)
This allows a value to be specified statically.

value
The value itself, a number.
range
The range of the value.
XScrollValue(viewport)
The value of an adjustment that horizontally scrolls the the viewport with the given id, on
the current screen. The viewport must be defined before a bar with this value is.

YScrollValue(viewport)
The value of an adjustment that vertically scrolls the the viewport with the given id, on the
current screen. The viewport must be defined before a bar with this value is.

Functions and Classes

These functions and classes are useful in association with screens.

Preferences

While all preferences can be defined based on the Actions and Values given above, it requires
some knowledge of Ren'Py to figure out the correct one to use. The preferences constructor
makes this easy, by creation an action or value, as appropriate, based on the names used in
the default preferences screen.

Preference(name, value=None)
This constructs the approprate action or value from a preference. The preference name
should be the name given in the standard menus, while the value should be either the
name of a choice, "toggle" to cycle through choices, a specific value, or left off in the case
of buttons.
Actions that can be used with buttons and hotspots are:

Preference("display", "fullscreen") - displays in fullscreen mode.


Preference("display", "window") - displays in windowed mode at 1x normal size.
Preference("display", 2.0) - displays in windowed mode at 2.0x normal size.
Preference("display", "toggle") - toggle display mode.
Preference("transitions", "all") - show all transitions.
Preference("transitions", "none") - do not show transitions.
Preference("transitions", "toggle") - toggle transitions.
Preference("text speed", 0) - make text appear instantaneously.
Preference("text speed", 142) - set text speed to 142 characters per second.
Preference("joystick") - Show the joystick preferences.
Preference("skip", "seen") - Only skip seen messages.
Preference("skip", "all") - Skip unseen messages.
Preference("skip", "toggle") - Toggle between skip seen and skip all.
Preference("begin skipping") - Starts skipping.
Preference("after choices", "skip") - Skip after choices.
Preference("after choices", "stop") - Stop skipping after choices.
Preference("after choices", "toggle") - Toggle skipping after choices.
Preference("auto-forward time", 0) - Set the auto-forward time to infinite.
Preference("auto-forward time", 10) - Set the auto-forward time (unit is seconds per
250 characters).
Preference("auto-forward", "enable") - Enable auto-forward mode.
Preference("auto-forward", "disable") - Disable auto-forward mode.
Preference("auto-forward", "toggle") - Toggle auto-forward mode.
Preference("music mute", "enable") - Mute the music mixer.
Preference("music mute", "disable") - Un-mute the music mixer.
Preference("music mute", "toggle") - Toggle music mute.
Preference("sound mute", "enable") - Mute the sound mixer.
Preference("sound mute", "disable") - Un-mute the sound mixer.
Preference("sound mute", "toggle") - Toggle sound mute.
Preference("voice mute", "enable") - Mute the voice mixer.
Preference("voice mute", "disable") - Un-mute the voice mixer.
Preference("voice mute", "toggle") - Toggle voice mute.
Preference("music volume", 0.5) - Set the music volume.
Preference("sound volume", 0.5) - Set the sound volume.
Preference("volice volume", 0.5) - Set the voice volume.
Values that can be used with bars are:

Preference("text speed")
Preference("auto-forward time")
Preference("music volume")
Preference("sound volume")
Preference("voice volume")

File Functions

These functions return useful information about files. They use the same default page as the
file actions.

FileCurrentPage()
Returns the current file page as a string.

FileLoadable(name, page=None)
This is a function that returns true if the file is loadable, and false otherwise.

FilePageName(auto='a', quick='q')
Returns the name of the current file page, as a string. If a normal page, this returns the
page number. Otherwise, it returns autoor quick.

FileSaveName(name, empty='', page=None)


Return the save_name that was in effect when the file was saved, or emptyif the file does
not exist.

FileScreenshot(name, empty=None, page=None)


Returns the screenshot associated with the given file. If the file is not loadable, then empty
is returned, unless it's None, in which case, a Null displayable is created.
The return value is a displayable.

FileSlotName(slot, slots_per_page, auto='a', quick='q', format='%s%d')


Returns the name of the numbered slot. This assumes that slots on normal pages are
numbered in a linear order starting with 1, and that page numbers start with 1. When slot
is 2, and slots_per_page is 10, and the other variables are the defauts:

When the first page is slowing, this returns "2".


When the second page is showing, this returns "12".
When the auto page is showing, this returns "a2".
When the quicksave page is showing, this returns "q2".

slot
The number of the slot to access.
slots_per_page
The number of slots per page.
auto
A prefix to use for the auto page.
quick
A prefix to use for the quick page.
format
The formatting code to use. This is given two arguments: A string giving the page
prefix, and an integer giving the slot number.

FileTime(name, format='%b %d, %H:%M', empty='', page=None)


Returns the time the file was saved, formatted according to the supplied format. If the file
is not found, emptyis returned.
The return value is a string.

FileUsedSlots(page=None, highest_first=True)
Returns a list of used numeric file slots on the page.

page
The name of the page that will be scanned. If None, the current page is used.
highest_first
If true, the highest-numbered file slot is listed first. Otherwise, the lowest-numbered
slot is listed first.

Side Image Functions

This function returns the side image to use.

SideImage(prefix_tag='side')
Returns the side image associated with the currently speaking character, or a Null
displayable if no such side image exists.

Tooltips

The tooltip class changes the screen when a button is hovered.

class Tooltip( default)


A tooltip object can be used to define a portion of a screen that is updated when the
mouse hovers an area.
A tooltip object has a valuefield, which is set to the defaultvalue passed to the
constructor when the tooltip is created. When a button using an action creadted by the
tooltip is hovered, the value field changes to the value associated with the action.

Action(value)
Returns an action that is generally used as the hovered property of a button. When
the button is hovered, the value field of this tooltip is set to value. When the buttton
loses focus, the value field of this tooltip reverts to the default.

When using a tooltip with a screen, the usual behavior is to create a tooltip object in a default
statement. The value of the tooltip and the action method can then be used within the screen.
The order of use within a screen doesn't matter - it's possible to use the value before an action
is used.
Tooltips can take on any value. While in the example below we use the text statement to
display a string on the screen, it's also possible to use the add statement to add a displayable.
More complex behavior is also possible.

screen tooltip_test:

default tt = Tooltip("No button selected.")

frame:
xfill True

has vbox

textbutton "One.":
action Return(1)
hovered tt.Action("The loneliest number.")

textbutton "Two.":
action Return(2)
hovered tt.Action("Is what it takes.")

textbutton "Three.":
action Return(3)
hovered tt.Action("A crowd.")

text tt.value

Special Screen Names


There are two kinds of special screen names in Ren'Py. The first are screens that will be
automatically displayed when Ren'Py script language commands (or their programmatic
equivalents) are run. The other type are menu screens. These have conventional names for
conventional functionality, but screens can be omitted or changed as is deemed necessary.

On this page, we'll give example screens. It's important to realize that, while some screens
must have minimal functionality, the screen system makes it possible to add additional
functionality to screens. For example, while the standard say screen only displays text, the
screen systen makes it easy to add features like skipping, auto-forward mode, or muting.
Some special screens take parameters. These parameters can be accessed as variables in the
screen's scope.
Some of the screens also have special ids associated with them. A special id should be
assigned to a displayable of a given type. It can cause properties to be assigned to that
displayable, and can make that displayable accessible to calling code.

In-Game Screens

These screens are automatically displayed when certain Ren'Py statements execute.

Say

The sayscreen is called by the say statement, when displaying ADV-mode dialogue. It is
displayed with the following parameters:

who
The text of the name of the speaking character.
what
The dialogue being said by the speaking character.

It's expected to declare displayables with the following ids:

"who"
A text displayable, displaying the name of the speaking character. The character object
can be given arguments that style this displayable.
"what"
A text displayable, displaying the dialogue being said by the speaking character. The
character object can be given arguments that style this displayable. A displayable with
this id must be defined, as Ren'Py uses it to calculate auto-forward-mode time, click-to-
continue, and other things.
"window"
A window or frame. This conventionally contains the who and what text. The character
object can be given arguments that style this displayable.

screen say:

window id "window":
has vbox

if who:
text who id "who"

text what id "what"

Choice

The choicescreen is used to display the in-game choices created with the menu statement. It
is given the following parameter:

items
This is a list of (caption, action, chosen) tuples. For each choice, captionis the name of
the choice, and actionis the action to invoke for the choice, or None if this is a choice
label. Chosenif a choice with this label has been chosen by the user before. (It doesn't
have to be in the current game.)

screen choice:

window:
style "menu_window"

vbox:
style "menu"

for caption, action, chosen in items:

if action:

button:
action action
style "menu_choice_button"

text caption style "menu_choice"

else:
text caption style "menu_caption"

Input

The inputscreen is used to display renpy.input(). It is given one parameter:

prompt
The prompt text supplied to renpy.input.

It is expected to declare a displayable with the following id:

"input"
An input displayable, which must exist. This is given all the parameters supplied to
renpy.input, so it must exist.

screen input:

window:
has vbox

text prompt
input id "input"

NVL

The nvlscreen is used to display NVL-mode dialogue. It is given the following parameter:

dialogue
This is a list of ( who, what, who_id, what_id, window_id) tuples, each of which corresponds
to a line of dialogue on the screen. Whoand whatare strings containing the speaking
character and the line of dialogue, respectively. The ids should be assigned to the who
and what text displayables, and a window containing each unit of dialogue.
items
This is a list of (caption, action, chosen) tuples. For each choice, captionis the name of
the choice, and actionis the action to invoke for the choice, or None if this is a choice
label. Chosenif a choice with this label has been chosen by the user before. (It doesn't
have to be in the current game.)
If items is empty, the menu should not be shown.

Ren'Py also supports an nvl_choicescreen, which takes the same parameters as nvl, and is
used in preference to nvlwhen an in-game choice is presented to the user, if it exists.

screen nvl:

window:
style "nvl_window"

has vbox:
style "nvl_vbox"

# Display dialogue.
for who, what, who_id, what_id, window_id in dialogue:
window:
id window_id

has hbox:
spacing 10

if who is not None:


text who id who_id

text what id what_id

# Display a menu, if given.


if items:

vbox:
id "menu"

for caption, action, chosen in items:

if action:

button:
style "nvl_menu_choice_button"
action action

text caption style "nvl_menu_choice"

else:

text caption style "nvl_dialogue"

Notify

The notifyscreen is used by renpy.notify()to display notifications to the user. It's generally
used in conjunction with a transform to handle the entire task of notification. It's given a single
parameter:

message
The message to display.

The default notify screen, and its associated transform, are:

screen notify:
zorder 100

text message at _notify_transform

# This controls how long it takes between when the screen is


# first shown, and when it begins hiding.
timer 3.25 action Hide('notify')

transform _notify_transform:
# These control the position.
xalign .02 yalign .015

# These control the actions on show and hide.


on show:
alpha 0
linear .25 alpha 1.0
on hide:
linear .5 alpha 0.0
Menu Screens

These are the menu screens. The main_menuand yesno_promptare invoked implictly. When the
user invokes the game menu, the screen named in _game_menu_screenwill be displayed. (This
defaults to save.)
Remember, menu screens can be combined and modified fairly freely.

Main Menu

The main_menuscreen is the first screen shown when the game begins.

screen main_menu:

# This ensures that any other menu screen is replaced.


tag menu

# The background of the main menu.


window:
style "mm_root"

# The main menu buttons.


frame:
style_group "mm"
xalign .98
yalign .98

has vbox

textbutton _("Start Game") action Start()


textbutton _("Load Game") action ShowMenu("load")
textbutton _("Preferences") action ShowMenu("preferences")
textbutton _("Help") action Help()
textbutton _("Quit") action Quit(confirm=False)

init python:

# Make all the main menu buttons be the same size.


style.mm_button.size_group = "mm"

Navigation

The navigationscreen isn't special to Ren'Py. But by convention, we place the game menu
navigation in a screen named navigation, and then use that screen from the save, load and
preferences screens.

screen navigation:

# The background of the game menu.


window:
style "gm_root"

# The various buttons.


frame:
style_group "gm_nav"
xalign .98
yalign .98
has vbox

textbutton _("Return") action Return()


textbutton _("Preferences") action ShowMenu("preferences")
textbutton _("Save Game") action ShowMenu("save")
textbutton _("Load Game") action ShowMenu("load")
textbutton _("Main Menu") action MainMenu()
textbutton _("Help") action Help()
textbutton _("Quit") action Quit()

init python:
style.gm_nav_button.size_group = "gm_nav"

Save

The savescreen is used to select a file in which to save the game.

screen save:

# This ensures that any other menu screen is replaced.


tag menu

use navigation

frame:
has vbox

# The buttons at the top allow the user to pick a


# page of files.
hbox:
textbutton _("Previous") action FilePagePrevious()
textbutton _("Auto") action FilePage("auto")

for i in range(1, 9):


textbutton str(i) action FilePage(i)

textbutton _("Next") action FilePageNext()

# Display a grid of file slots.


grid 2 5:
transpose True
xfill True

# Display ten file slots, numbered 1 - 10.


for i in range(1, 11):

# Each file slot is a button.


button:
action FileAction(i)
xfill True
style "large_button"

has hbox

# Add the screenshot and the description to the


# button.
add FileScreenshot(i)
text ( " %2d. " % i
+ FileTime(i, empty=_("Empty Slot."))
+ "\n"
+ FileSaveName(i)) style "large_button_text"
Load

The loadscreen is used to select a file from which to load the game.

screen load:

# This ensures that any other menu screen is replaced.


tag menu

use navigation

frame:
has vbox

# The buttons at the top allow the user to pick a


# page of files.
hbox:
textbutton _("Previous") action FilePagePrevious()
textbutton _("Auto") action FilePage("auto")

for i in range(1, 9):


textbutton str(i) action FilePage(i)

textbutton _("Next") action FilePageNext()

# Display a grid of file slots.


grid 2 5:
transpose True
xfill True

# Display ten file slots, numbered 1 - 10.


for i in range(1, 11):

# Each file slot is a button.


button:
action FileAction(i)
xfill True
style "large_button"

has hbox

# Add the screenshot and the description to the


# button.
add FileScreenshot(i)
text ( " %2d. " % i
+ FileTime(i, empty=_("Empty Slot."))
+ "\n"
+ FileSaveName(i)) style "large_button_text"

Preferences

The preferencesscreen is used to select options that control the display of the game.

screen preferences:

tag menu

# Include the navigation.


use navigation
# Put the navigation columns in a three-wide grid.
grid 3 1:
style_group "prefs"
xfill True

# The left column.


vbox:
frame:
style_group "pref"
has vbox

label _("Display")
textbutton _("Window") action Preference("display", "window")
textbutton _("Fullscreen") action Preference("display", "fullscreen")

frame:
style_group "pref"
has vbox

label _("Transitions")
textbutton _("All") action Preference("transitions", "all")
textbutton _("None") action Preference("transitions", "none")

frame:
style_group "pref"
has vbox

label _("Text Speed")


bar value Preference("text speed")

frame:
style_group "pref"
has vbox

textbutton _("Joystick...") action ShowMenu("joystick_preferences")

vbox:

frame:
style_group "pref"
has vbox

label _("Skip")
textbutton _("Seen Messages") action Preference("skip", "seen")
textbutton _("All Messages") action Preference("skip", "all")

frame:
style_group "pref"
has vbox

textbutton _("Begin Skipping") action Skip()

frame:
style_group "pref"
has vbox

label _("After Choices")


textbutton _("Stop Skipping") action Preference("after choices", "stop"
textbutton _("Keep Skipping") action Preference("after choices", "skip"

frame:
style_group "pref"
has vbox
label _("Auto-Forward Time")
bar value Preference("auto-forward time")

vbox:

frame:
style_group "pref"
has vbox

label _("Music Volume")


bar value Preference("music volume")

frame:
style_group "pref"
has vbox

label _("Sound Volume")


bar value Preference("sound volume")
textbutton "Test" action Play("sound", "sound_test.ogg") style "soundtest_bu

frame:
style_group "pref"
has vbox

label _("Voice Volume")


bar value Preference("voice volume")
textbutton "Test" action Play("voice", "voice_test.ogg") style "soundtest_bu

init python:

style.pref_frame.xfill = True
style.pref_frame.xmargin = 5
style.pref_frame.top_margin = 5

style.pref_vbox.xfill = True

style.pref_button.size_group = "pref"
style.pref_button.xalign = 1.0

style.pref_slider.xmaximum = 192
style.pref_slider.xalign = 1.0

style.soundtest_button.xalign = 1.0

Yesno_Prompt

The yesno_promptmessage is used to ask yes/no choices of the user. It takes the following
parameters:

message
The message to display to the user. This is one of:

layout.ARE_YOU_SURE - "Are you sure?" This should be the default if the message is
unknown.
layout.DELETE_SAVE - "Are you sure you want to delete this save?"
layout.OVERWRITE_SAVE - "Are you sure you want to overwrite your save?"
layout.LOADING - "Loading will lose unsaved progress.nAre you sure you want to do
this?"
layout.QUIT - "Are you sure you want to quit?"
layout.MAIN_MENU - "Are you sure you want to return to the mainnmenu? This will
lose unsaved progress."
The values of the variables are strings, which means they can be displayed using a text
displayable.
yes_action
The action to run when the user picks "Yes".
no_action
The action to run when the user picks "No".

screen yesno_prompt:

modal True

window:
style "gm_root"

frame:
style_group "yesno_prompt"

xfill True
xmargin 50
ypadding 25
yalign .25

vbox:
xfill True
spacing 25

text _(message):
text_align 0.5
xalign 0.5

hbox:
spacing 100
xalign .5
textbutton _("Yes") action yes_action
textbutton _("No") action no_action

Side Images

Many visual novels include a picture of the character that is speaking as part of their interface.
Ren'Py calls this image a side image, and has support for automatically selecting and
displaying a side image as part of the dialogue.
The side image support assumes that a Character()is declared with a linked image tag:

define e = Character("Eileen", image="eileen")

When a character with a linked image tag speaks, Ren'Py creates a pool of image attributes.
The linked image tag is added to this pool, as are the current image attributes that are
associated with that tag.
To determine the side image associated with a tag, Ren'Py tries to find an image with the tag
"side", and the largest number of attributes from the pool. If no image can be found, or more

than one image has the same number of attributes, an Nullis shown instead.
than one image has the same number of attributes, an Nullis shown instead.
For example, say we have the following script:

define e = Character("Eileen", image="eileen")

image eileen happy = "eileen_happy.png"


image eileen concerned = "eileen_concerned.png"

image side eileen happy = "side_eileen_happy.png"


image side eileen = "side_eileen.png"

label start:

show eileen happy

e "Let's call this line Point A."

e concerned "And this one is point B."

At point A, the character eis speaking, which is linked to the image tag "eileen". The "eileen
happy" image is showing, so the pool of attributes is "eileen" and "happy". We look for an
image with the "side" tag, and as many of those attributes as possible - and we match "side
eileen happy", which is the side image Ren'Py will display.
At point B, the "eileen concerned" image is showing. The pool of attributes is now "eileen" and
"concerned". The only matching image is "side eileen", so that's what Ren'Py selects. If the was
a "side concerned" image, there would be ambiguity, and Ren'Py wouldn't display an image.

Invisible Characters

Another use of the side image is to show an image of the player character, when that
character has dialogue. The way to do this is to link an image to the character, and then use
the say with attributes construct to select the side image to show.
For example:

define p = Character("Player", image="player")

image side player happy = "side_player_happy.png"


image side player concerned = "side_player_concerned.png"

label start:

p happy "This is shown with the 'side player happy' image."

p "This is also shown with 'side player happy'."

p concerned "This is shown with 'side player concerned'."

Variations

There are two variants of side image support that can be selected - either alone or together -
using config variables:

config.side_image_tag= None
If this is given, then the side image will track the given image tag, rather than the image
associated with currently speaking character. For example,
define e = Character("Eileen", image="eileen")

init python:
config.side_image_tag = "eileen"

Will make the side image track the "eileen" image tag, which is associated with the e
character.

config.side_image_only_not_showing= False
When set to true, the side image will only show if an image with that tag is not already
being shown on the screen.

Leaving Room / Customization

By default, the entire width of the screen is taken up by the text. If one tries to display a side
image, it will be displayed on top of the text. To fix this, one should include margin or padding
on the appropriate side of the text window, using code like:

init python:
style.window.padding_left = 150

The position of the side image can be changed by customizing the sayor nvlscreens. Both
include the line:

add SideImage() xalign 0.0 yalign 1.0

By changing the xalign and yalign properties, you can control the positioning of the side image
on the screen.
Finally, the SideImage()function returns, as a displayable, the current side image. This can be
used as part of more advanced screen customization.

Configuration Variables
Configuration variables control the behavior of Ren'Py's implementation, allowing Ren'Py itself
to be customized in a myriad of ways. These range from the common (such as changing the
screen size) to the obscure (adding new kinds of archive files).

Ren'Py's implementation makes the assumption that, once the GUI system has initialized,
configuration variables will not change. Changing configuration variables outside of init blocks
can lead to undefined behavior. Configuration variables are not part of the save data.
Configuration variables are often changed in init python blocks:

init python:

# Use a widescreen resolution.


config.screen_width = 1024
config.screen_height = 600

Commonly Used

config.developer= False
If set to True, developer mode is enabled. Developer mode gives access to the shift+D
developer menu, shift+R reloading, and various other features that are not intended for
end users.
The default game template sets this to True. We suggest setting it to False before
releasing a game.

config.help= "README.html"
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-?.
If None, the help system is disabled and does not show up on menus. If a string
corresponding to a label found in the script, that label is invoked in a new context. This
allows you to define an in-game help-screen. Otherwise, this is interpreted as a filename
relative to the base directory, that is opened in a web browser.

config.name= ""
This should be a string giving the name of the game. This is included as part of tracebacks
and other log files, helping to identify the version of the game being used.

config.save_directory= "..."
This is used to generate the directory in which games and persistent information are
saved. The name generated depends on the platform:

Windows
%APPDATA%/RenPy/save_directory
Mac OS X
~/Library/RenPy/save_directory
Linux/Other
~/.renpy/save_directory

Setting this to None creates a "saves" directory underneath the game directory. This is not
recommended, as it prevents the game from being shared between multiple users on a
system. It can also lead to problems when a game is installed as Administrator, but run as
a user.
This must be set in a python early block, so that persistent information can be loaded
before init code is run.
The user may change the directory. Code that needs to know the save directory should
read config.savedirinstead of this variable.

config.screen_height= 600
The height of the screen.

config.screen_width= 800
The width of the screen.

config.translations= dict(...)
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.

config.window_icon= None
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.
This should generally be a PNG format file.
config.windows_icon= None
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 should be a PNG format file.

config.window_title= "A Ren'Py Game"


The static portion of the title of the window containing the Ren'Py game. _window_subtitle
is appended to this to get the full title of the window.

config.version= ""
This should be a string giving the version of the game. This is included as part of
tracebacks and other log files, helping to identify the version of the game being used.

Occasionally Used

config.adv_nvl_transition= None
A transition that is used when showing NVL-mode text directly after ADV-mode text.

config.after_load_transition= None
A transition that is used after loading, when entering the loaded game.

config.auto_load= None
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.

config.automatic_images= None
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, then break the name at separators, to creatge
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.
With the example list of separators, if your game directory contains:

eileen_happy.png, Ren'Py will define the image "eileen happy".


lucy/mad.png, Ren'Py will define the image "lucy mad".
mary.png, Ren'Py will do nothing. (As the image does not have two components.)

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.

config.debug= False
Enables debugging functionality (mostly by turning some missing files into errors.) This
should always be turned off in a release.

config.debug_image_cache= False
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.
config.debug_sound= False
Enables debugging of sound functionality. This disables the supression of errors when
generating sound. However, if a sound card is missing or flawed, then such errors are
normal, and enabling this may prevent Ren'Py from functioning normally. This should
always be False in a released game.

config.debug_text_overflow= False
When true, Ren'Py will log text overflows to text_overflow.txt. A text overflow occurs when
a Textdisplayable renders to a size larger than that allocated to it. By setting this to True
and setting the xmaximumand ymaximumstyle properties of the dialogue window to the
window size, this can be used to report cases where the dialogue is too large for its
window.

config.default_afm_time= None
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.
Persistent data must be deleted for this to take effect.

config.default_afm_enable= None
If not None, this should be a boolean that controls if auto-forward-mode is enabled by
default. When it's False, auto-forwarding will not occur. Set this to False with caution, as
the default Ren'Py UI does not provide a way of changing it's setting. (But one can use
Preference action in a screen to create such a UI.)
Persistent data must be deleted for this to take effect.

config.default_fullscreen= None
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.)

config.default_text_cps= None
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.)
Persistent data must be deleted for this to take effect.

config.default_transform= ...
When a displayable is shown using the show or scene statements, the transform properties
are taken from this transform and used to initialize the values of the displayable's
transform.
The default default transform is center.

config.empty_window= ...
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 occurred.) It's expected to show an empty window
on the screen, and return without causing an interaction.
The default implementation of this uses the narrator character to display a blank line
without interacting.

config.end_game_transition= None
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().
config.end_splash_transition= None
The transition that is used to display the main menu after the end of the splashscreen.

config.enter_sound= None
If not None, this is a sound file that is played when entering the game menu.

config.enter_transition= None
If not None, this variable should give a transition that will be used when entering the game
menu.

config.exit_sound= None
If not None, this is a sound file that is played when exiting the game menu.

config.exit_transition= None
If not None, this variable should give a transition that will be performed when exiting the
game menu.

config.fix_rollback_without_choice= False
This option determines how the built in menus or imagemaps behave during fixed
rollback. The default value is False, which means that menu only the previously selected
option remains clickable. If set to True, the selected option is marked but no options are
clickable. The user can progress forward through the rollback buffer by clicking.

config.font_replacement_map= { }
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:

init python:
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.

config.framerate= 100
If not None, this is the upper limit on the number of frames Ren'Py will attempt to display
per second. This is only respected by the software renderer. The GL renderer will
synchronize to vertical blank instead.

config.game_main_transition= None
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.

config.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.
This is not used when the game menu is defined using screens.

config.game_menu_music= None
If not None, a music file to play when at the game menu.
config.gl_test_image= "black"
The name of the image that is used when running the OpenGL performance test. This
image will be shown for 5 frames or .25 seconds, on startup. It will then be automatically
hidden.

config.has_autosave= True
If true, the game will autosave. If false, no autosaving will occur.

config.image_cache_size= 8
This is used to set the size of the image cache, as a multiple of the screen size. This
number is multiplied by the size of the screen, in pixels, to get the size of the image cache
in pixels.
If set too large, this can waste memory. If set too small, images can be repeatedly loaded,
hurting performance.

config.main_game_transition= None
The transition used when entering the game menu from the main menu, as is done when
clicking "Load Game" or "Preferences".

config.main_menu= [ ... ]
The default main menu, when not using screens. For more details, see Main and Game
Menus.

config.main_menu_music= None
If not None, a music file to play when at the main menu.

config.menu_clear_layers= []
A list of layer names (as strings) that are cleared when entering the game menu.

config.menu_window_subtitle= ""
The _window_subtitlevariable is set to this value when entering the main or game
menus.

config.missing_background= "black"
This is the background that is used when config.developeris True and an undefined
image is used in a scene statement. This should be an image name (a string), not a
displayable.

config.mode_callbacks= [ ... ]
A list of callbacks called when entering a mode. For more documentation, see the section
on Modes.
The default value includes a callback that implements config.adv_nvl_transitionand
config.nvl_adv_transition.

config.mouse= None
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, as it is used when a more specific key is absent.
Each value in the dictionary should be a list of (image, xoffset, offset) tuples,
representing frames.
image
The mouse cursor image.
xoffset
The offset of the hotspot pixel from the left side of the cursor.
yoffset
The offset of the hotspot pixel from the top of the cursor.

The frames are played back at 20hz, and the animation loops after all frames have been
shown.

config.narrator_menu= False
(This is set to True by the default screens.rpy file.) If true, then narration inside a menu is
displayed using the narrator character. Otherwise, narration is displayed as captions
within the menu itself.

config.nvl_adv_transition= None
A transition that is used when showing ADV-mode text directly after NVL-mode text.

config.overlay_functions= [ ]
A list of functions. When called, each function is expected to use ui functions to add
displayables to the overlay layer.

config.python_callbacks= [ ]
A list of functions. The functions in this list are called, without any arguments, whenever a
python block is run outside of the init phase.
One possible use of this would be to have a function limit a variable to within a range each
time it is adjusted.
The functions may be called during internal Ren'Py code, before the start of the game
proper, and potentially before the variables the function depends on are intialized. The
functions are required to deal with this, perhaps by using hasattr(store, 'varname')to
check if a variable is defined.

config.quit_action= ...
The action that is called when the user clicks the quit button on a window. The default
action prompts the user to see if he wants to quit the game.

config.say_attribute_transition= None
If not None, a transition to use when the image is changed by a say statement with image
attributes.

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.
When using a load_save layout, a different default may be used.

config.thumbnail_width= 100
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.
When using a load_save layout, a different default may be used.
config.window_hide_transition= None
The transition used by the window hide statement when no transition has been explicitly
specified.

config.window_overlay_functions= []
A list of overlay functions that are only called when the window is shown.

config.window_show_transition= None
The transition used by the window show statement when no transition has been explicitly
specified.

Rarely or Internally Used

config.afm_bonus= 25
The number of bonus characters added to every string when auto-forward mode is in
effect.

config.afm_callback= None
If not None, a python function that is called to determine if it is safe to auto-forward. The
intent is that this can be used by a voice system to disable auto-forwarding when a voice is
playing.

config.afm_characters= 250
The number of characters in a string it takes to cause the amount of time specified in the
auto forward mode preference to be delayed before auto-forward mode takes effect.

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.

config.allow_skipping= True
If set to False, the user is not able to skip over the text of the game.

config.archives= [ ]
A list of archive files that will be searched for images and other data. The entries in this
should consist of strings giving the base names of archive files, without the .rpa extension.
The archives are searched in the order they are found in this list. A file is taken from the
first archive it is found in.
At startup, Ren'Py will automatically populate this variable with the names of all archives
found in the game directory, sorted in reverse ascii order. For example, if Ren'Py finds the
files data.rpa, patch01.rpa, and patch02.rpa, this variable will be populated with
['patch02', 'patch01', 'data'].

config.auto_choice_delay= None
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.

config.autosave_frequency= 200
Roughly, the number of interactions that will occur before an autosave occurs. To disable
autosaving, set config.has_autosaveto False, don't change this variable.
config.character_callback= None
The default value of the callback parameter of Character.

config.clear_layers= []
A list of names of layers to clear when entering the main and game menus.

config.context_clear_layers= [ 'screens' ]
A list of layers that are cleared when entering a new context.

config.fade_music= 0.0
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.

config.fast_skipping= False
Set this to True to allow fast skipping outside of developer mode.

config.file_open_callback= None
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.

config.focus_crossrange_penalty= 1024
This is the amount of penalty to apply to moves perpendicular to the selected direction of
motion, when moving focus with the keyboard.

config.gl_enable= True
Set this to False to disable OpenGL acceleration. OpenGL acceleration will automatically
be disabled if it's determined that the system cannot support it, so it usually isn't
necessary to set this.
OpenGL can also be disabled by holding down shift at startup.

config.gl_resize= True
Determines if the user is allowed to resize an OpenGL-drawn window.

config.hard_rollback_limit= 100
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.

config.hide= renpy.hide
A function that is called when the hide statement is executed. This should take the same
arguments as renpy.hide.

config.imagemap_auto_function= ...
A function that expands the autoproperty of a screen language imagebutton or
imagemap statement into a displayable. It takes the value of the auto property, and the
desired image, one of: "insensitive", "idle", "hover", "selected_idle", "selected_hover", or
"ground". It should return a displayable or None.
The default implementation formats the autoproperty with the desired image, and then
checks if the computed filename exists.
config.imagemap_cache= True
If true, imagemap hotspots will be cached to PNG files, reducing time and memory usage,
but increasing the size of the game on disk. Set this to false to disable this behavior.

config.implicit_with_none= True
If True, then by default the equivalent of a with None statement will be performed after
interactions caused by dialogue, menus input, and imagemaps. This ensures that old
screens will not show up in transitions.

config.interact_callbacks= ...
A list of functions that are called (without any arguments) when an interaction is started or
restarted.

config.joystick= True
If True, joystick support is enabled.

config.keep_running_transform= True
If true, showing an image without supplying a transform or ATL block will cause the image
to continue the previous transform an image with that tag was using, if any. If false, the
transform is stopped.

config.keymap= dict(...)
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.

config.label_callback= None
If not None, this is a function that is called whenever a label is reached. It is called with two
parameters. The first is the name of the label. The second is true if the label was reached
through jumping, calling, or creating a new context, and false otherwise.

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.

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.
If a layer is not mentioned in config.layer_clipping, then it is assumed to take up the full
screen.

config.layers= [ 'master', 'transient', 'screens', 'overlay' ]


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", "screens", and "overlay" internally, so they should always
be in this list.

config.lint_hooks= ...
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).

config.load_before_transition= True
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.)

config.log= None
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.

config.missing_image_callback= None
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.

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.

config.new_substitutions= True
If true, Ren'Py will apply new-style (square-bracket) substitutions to all text displayed.

config.old_substitutions= False
If true, Ren'Py will apply old-style (percent) substitutions to text displayed by the say and
menu statements.

config.overlay_during_with= True
True if we want overlays to be shown during with statements, or False if we'd prefer that
they be hidden during the with statements.

config.overlay_layers= [ 'overlay' ]
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.

config.periodic_callback= None
If not None, this should be a function. The function is called, with no arguments, at around
20hz.

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 number of statements is considered, and any image referenced in those
statements is potentially predictively loaded. Setting this to 0 will disable predictive
loading of images.

config.profile= False
If set to True, some profiling information will be output to stdout.

config.rollback_enabled= True
Should the user be allowed to rollback the game? If set to False, the user cannot
interactively rollback.

config.rollback_length= 128
When there are more than this many statements in the rollback log, Ren'Py will consider
trimming the log.
config.say_allow_dismiss= None
If not None, this should be a function. The function is called with no arguments when the
user attempts to dismiss a say statement. If this function returns true, the dismissal is
allowed, otherwise it is ignored.

config.say_menu_text_filter= None
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.

config.say_sustain_callbacks= ...
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.

config.save_dump= False
If set to true, Ren'Py will create the file save_dump.txt whenever it saves a game. This file
contains information about the objects contained in the save file. Each line consists of a
relative size estimate, the path to the object, information about if the object is an alias,
and a representation of the object.

config.save_physical_size= True
If true, the physical size of the window will be saved in the preferences, and restored when
the game resumes.

config.savedir= ...
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.

config.scene= renpy.scene
A function that's used in place of renpy.scene by the scene statement. Note that this is
used to clear the screen, and config.show is used to show a new image. This should have
the same signature as renpy.scene.

config.screenshot_callback= ...
A function that is called when a screenshot is taken. The function is called with a single
parameter, the full filename the screenshot was saved as.

config.screenshot_crop= None
If not None, this should be a (x, y, height, width) tuple. Screenshots are cropped to this
rectangle before being saved.

config.screenshot_pattern= "screenshot%04d.png"
The pattern used to create screenshot files. This pattern is applied (using python's %-
formatting rules) to the natural numbers to generate a sequence of filenames. The
filenames may be absolute, or relative to config.renpy_base. The first filename that does
not exist is used as the name of the screenshot.

config.script_version= None
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.
config.searchpath= [ 'common', 'game' ]
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.

config.show= renpy.show
A function that is used in place of renpy.show by the show and scene statements. This
should have the same signature as renpy.show.

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.)

config.skip_indicator= True
If True, the library will display a skip indicator when skipping through the script.

config.sound= True
If True, sound works. If False, the sound/mixer subsystem is completely disabled.

config.sound_sample_rate= 44100
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.

config.start_interact_callbacks= ...
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.

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.

config.transient_layers= [ 'transient' ]
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.

config.transform_uses_child_position= True
If True, transforms will inherit position properties from their child. If not, they won't.

config.variants= [ ... ]
A list of screen variants that are searched when choosing a screen to display to the user.
This should always end with None, to ensure that the default screens are chosen. See
Screen Variants.

config.with_callback= None
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 screen during the
transition. The function is called with a single argument, which is the transition that is
occurring. It is expected to return a transition, which may or may not be the transition
supplied as its argument.
Image Gallery and Music Room Actions

Image Gallery

A image gallery is a screen that allows the player to unlock images, and then view those
images. The screen has one or more buttons associated with it, and each button has one or
more associated images. Buttons and images also have conditions that determine if they have
unlocked.
Image galleries are managed by instances of the Gallery class. A single instance of the gallery
class may be shared between multiple image gallery screens.

A gallery has one or more buttons associated with it, a button has one or more images
associated with it, and each image has one or more displayables associated with it. Conditions
can be assigned to buttons and images. A button is unlocked when all of the conditions
associated with it are satisfied and at least one image associated with that button is unlocked.
An image is unlocked when all associated conditions are satisfied.
Creating an image gallery consists of the following four steps.

1. Create an instance of Gallery.


2. Add buttons and images to that gallery, along with conditions that determine if the
buttons and images they belong to are unlocked. This is also a multi-step process.
1. Declare a new button by calling Gallery.button().
2. Optionally, add one or more unlock conditions to the button by calling
Gallery.unlock()or Gallery.condition().
3. Declare an image by calling Gallery.image()with one or displayables as
arguments. Or call the convenience method Gallery.unlock_image()instead.
4. Optionally, call Gallery.transform()to associate transforms with the displayables.
5. Optionally, add one or more unlock conditions to the image by calling
Gallery.unlock(), Gallery.condition(), or Gallery.allprior().

Additional images can be added to a button by repeating steps 3-5, while additional
buttons can be added to the gallery by repeating all five steps.
3. Create an image gallery screen. The screen should display a background, and should
contain navigation that allows the user to show other image galleries, or to return to the
main or extras menu.
4. Add code to display the image gallery screen to the main or extras menu.

Here's an example of the first three steps:

init python:

# Step 1. Create the gallery object.


g = Gallery()

# Step 2. Add buttons and images to the gallery.

# A button that contains an image that automatically unlocks.


g.button("dawn")
g.image("dawn1")
g.unlock("dawn1")

# This button has multiple images assocated with it. We use unlock_image
# so we don't have to call both .image and .unlock. We also apply a
# transform to the first image.
g.button("dark")
g.unlock_image("bigbeach1")
g.transform(slowpan)
g.unlock_image("beach1 mary")
g.unlock_image("beach2")
g.unlock_image("beach3")

# This button has a condition associated with it, allowing code


# to choose which images unlock.
g.button("end1")
g.condition("persistent.unlock_1")
g.image("transfer")
g.image("moonpic")
g.image("girlpic")
g.image("nogirlpic")
g.image("bad_ending")

g.button("end2")
g.condition("persistent.unlock_2")
g.image("library")
g.image("beach1 nomoon")
g.image("bad_ending")

# The last image in this button has an condition associated with it,
# so it will only unlock if the user gets both endings.
g.button("end3")
g.condition("persistent.unlock_3")
g.image("littlemary2")
g.image("littlemary")
g.image("good_ending")
g.condition("persistent.unlock_3 and persistent.unlock_4")

g.button("end4")
g.condition("persistent.unlock_4")
g.image("hospital1")
g.image("hospital2")
g.image("hospital3")
g.image("heaven")
g.image("white")
g.image("good_ending")
g.condition("persistent.unlock_3 and persistent.unlock_4")

# The final two buttons contain images that show multiple pictures
# at the same time. This can be used to compose character art onto
# a background.
g.button("dawn mary")
g.unlock_image("dawn1", "mary dawn wistful")
g.unlock_image("dawn1", "mary dawn smiling")
g.unlock_image("dawn1", "mary dawn vhappy")

g.button("dark mary")
g.unlock_image("beach2", "mary dark wistful")
g.unlock_image("beach2", "mary dark smiling")
g.unlock_image("beach2", "mary dark vhappy")

# The transition used when switching images.


g.transition = dissolve

# Step 3. The gallery screen we use.


screen gallery:

# Ensure this replaces the main menu.


tag menu

# The background.
add "beach2"
# A grid of buttons.
grid 3 3:

xfill True
yfill True

# Call make_button to show a particular button.


add g.make_button("dark", "gal-dark.png", xalign=0.5, yalign=0.5)
add g.make_button("dawn", "gal-dawn.png", xalign=0.5, yalign=0.5)
add g.make_button("end1", "gal-end1.png", xalign=0.5, yalign=0.5)

add g.make_button("end2", "gal-end2.png", xalign=0.5, yalign=0.5)


add g.make_button("end3", "gal-end3.png", xalign=0.5, yalign=0.5)
add g.make_button("end4", "gal-end4.png", xalign=0.5, yalign=0.5)

add g.make_button("dark mary", "gal-dark_mary.png", xalign=0.5, yalign=0.5)


add g.make_button("dawn mary", "gal-dawn_mary.png", xalign=0.5, yalign=0.5)

# The screen is responsible for returning to the main menu. It could also
# navigate to other gallery screens.
textbutton "Return" action Return() xalign 0.5 yalign 0.5

Step 4 will vary based on how your game is structured, but one way of accomplishing it is to
add the following line:

textbutton "Gallery" action ShowMenu("gallery")

to the main menu screen.

class Gallery( self)


This class supports the creation of an image gallery by handling the locking of images,
providing an action that can show one or more images, and a providing method that
creates buttons that use that action.

transition
The transition that is used when changing images.

locked_button
The default displayable used by make_button for a locked button.

hover_border
The default hover border used by make_button.

idle_border
The default idle border used by make_button.

Action(name)
An action that displays the images associated with the given button name.

allprior(self)
A condition that is true if all prior images associated with the current button have
been unlocked.

button(name)
Creates a new button, named name.

name
The name of the button being created.

condition(expression)
A condition that is satisfied when an expression evaluates to true.

expression
A string giving a python expression.

display(*displayables)
Adds a new image to the current button, where an image consists of one or more
displayables.

image(*displayables)
Adds a new image to the current button, where an image consists of one or more
displayables.

make_button(name, unlocked, locked=None, hover_border=None, idle_border=None,


**properties)
This creates a button that displays the images associated with the given button name.

name
The name of the button that will be created.
unlocked
A displayable that is displayed for this button when it is unlocked.
locked
A displayable that is displayed for this button when it is locked. If None, the
locked_button field of the gallery object is used instead.
hover_border
A displayable that is used to overlay this button when when it is unlocked and has
focus. If None, the hover_border field of the gallery object is used.
idle_border
A displayable that is used to overlay this button when when it is unlocked but
unfocused. If None, the idle_border field of the gallery object is used.

Additional keyword arguments become style properties of the created button object.

transform(*transforms)
Applies transforms to the last image registered. This should be called with the same
number of transforms as the image has displayables. The transforms are applied to
the corresponding displayables.
If a transform is None, the default transform is used.

unlock(*images)
A condition that takes one or more image names as argument, and is satisfied when
all the named images have been seen by the player. The image names should be
given as strings.

unlock_image(*images)
A convenience method that is equivalent to calling image and unlock with the same
parameters. This will cause an image to be displayed if it has been seen before.
The images should be specified as strings giving image names.

Music Room

A music room is a screen that allows the user to select and play music tracks from the game.
These tracks may start off locked when the user first begins playing a particular game, and will
be unlocked as the user listens to the music while playing the game.
A music room is managed by an instance of the MusicRoom class. There can be more than
one MusicRoom instance in a game, allowing a game to have multiple music rooms. Creating
a music room consists of the following four steps:

1. Create an instance of MusicRoom. The MusicRoom constructor takes parameters to


control the channel on which music is played back, and how long it takes to fade music
out and back in.
2. Add music files to the instance.
3. Create a screen that uses the MusicRoom instance to create actions for buttons,
imagebuttons, or hotspots. These actions can pick a track, the next or previous track, or
stop and start the music.

Note that the actions used are members of a MusicRoom instance, so if the MusicRoom
instance is named mr, then mr.Play("track1.ogg")is how you'd use the play action.
4. Add the music room screen to the main menu, or an extras menu.

Here's an example of the first three steps:

init python:

# Step 1. Create a MusicRoom instance.


mr = MusicRoom(fadeout=1.0)

# Step 2. Add music files.


mr.add("track1.ogg", always_unlocked=True)
mr.add("track2.ogg")
mr.add("track3.ogg")

# Step 3. Create the music room screen.


screen music_room:

tag menu

frame:
has vbox

# The buttons that play each track.


textbutton "Track 1" action mr.Play("track1.ogg")
textbutton "Track 2" action mr.Play("track2.ogg")
textbutton "Track 3" action mr.Play("track3.ogg")

null height 20

# Buttons that let us advance tracks.


textbutton "Next" action mr.Next()
textbutton "Previous" action mr.Previous()

null height 20
# The button that lets the user exit the music room.
textbutton "Main Menu" action ShowMenu("main_menu")

# Start the music playing on entry to the music room.


on "replace" action mr.Play()

# Restore the main menu music upon leaving.


on "replaced" action Play("music", "track1.ogg")

Step 4 will vary based on how your game is structured, but one way of accomplishing it is to
add the following line:

textbutton "Music Room" action ShowMenu("music_room")

to the main menu screen.


Using the Preferences()function, especially Preferences("music volume"), it's possible to
include a volume slider on the music screen.

class MusicRoom( channel='music', fadeout=0.0, fadein=0.0)


A music room that contains a series of songs that can be unlocked by the user, and actions
that can play entries from the list in order.

channel
The channel that this music room will operate on.
fadeout
The number of seconds it takes to fade out the old music when changing tracks.
fadein
The number of seconds it takes to fade in the new music when changing tracks.

Next(self)
An action that causes the music room to play the next unlocked file in the playlist.

Play(filename=None)
Causes the music room to start playing. If filenameis given, that file begins playing.
Otherwise, the currently playing file starts over (if it's unlocked), or the first file starts
playing.
If filenameis given, buttons with this action will be insensitive while filenameis
locked, and will be selected when filenameis playing.

Previous(self)
An action that causes the music room to play the previous unlocked file in the playlist.

Stop(self)
Stops the music.

add(filename, always_unlocked=False)
Adds the music file filenameto this music room. The music room will play unlocked
files in the order that they are added to the room.

always_unlocked
If true, the music file will be always unlocked. This allows the file to show up in the
music room before it has been played in the game.
is_unlocked(filename)
Returns true if the filename has been unlocked (or is always unlocked), and false if it is
still locked.

NVL-Mode Tutorial

There are two main styles of presentation used for visual novels. ADV-style games present
dialogue and narration one line at a time, generally in a window at the bottom of the screen.
NVL-style games present multiple lines on the screen at a time, in a window that takes up the
entire screen.
In this tutorial, we will explain how to make an NVL-mode game using Ren'Py. This tutorial
assumes that you are already familiar with the basics of Ren'Py, as explained in the Quickstart
manual.

Getting Started

NVL-mode can be added to a Ren'Py script in two steps. The first is to declare the characters to
use NVL-mode, and the second is to add nvl clearstatements at the end of each page.
Characters can be declared to use NVL-mode by adding a kind=nvlparameter to each of the
Character declarations. For example, if we the character declarations from the Quickstart
manual are:

define s = Character('Sylvie', color="#c8ffc8")


define m = Character('Me', color="#c8c8ff")

Changed to use NVL-mode, those declarations become:

define s = Character('Sylvie', kind=nvl, color="#c8ffc8")


define m = Character('Me', kind=nvl, color="#c8c8ff")
define narrator = Character(None, kind=nvl)

Note that we have also added an NVL-mode declaration of narrator. The narratorcharacter is
used to speak lines that do not have another character name associated with it.
If we ran the game like this, the first few lines would display normally, but after a while, lines
would begin displaying below the bottom of the screen. To break the script into pages, include
an nvl clearstatement after each page.
The following is an example script with pagination:

label start:
"I'll ask her..."

m "Um... will you..."


m "Will you be my artist for a visual novel?"

nvl clear

"Silence."
"She is shocked, and then..."

s "Sure, but what is a \"visual novel?\""

nvl clear
While nvl-mode games generally have more text per paragraph, this example demonstrates a
basic NVL-mode script. (Suitable for use in a kinetic novel that does not have transitions.)

Menus

By default, menus are displayed in ADV-mode, taking up the full screen. There is also an
alternate NVL-mode menu presentation, which displays the menus immediately after the
current page of NVL-mode text.
To access this alternate menu presentation, write:

init python:
menu = nvl_menu

The menu will disappear after the choice has been made, so it usually makes sense to follow
menus with an "nvl clear" or some sort of indication as to the choice.

Showing and Hiding the NVL-mode Window

The NVL-mode window can be controlled with the standard window showand window hide
statements. To enable this, add the following code to your game:

init python:
config.empty_window = nvl_show_core
config.window_hide_transition = dissolve
config.window_show_transition = dissolve

Setting config.empty_windowto nvl_show_corewill cause the NVL-mode window to be


displayed during a transition. (The last two lines select the default transitions to be used for
showing and hiding the window.)
An example of using the window commands to show and hide the window is:

label meadow:

nvl clear

window hide
scene bg meadow
with fade
window show

"We reached the meadows just outside our hometown. Autumn was so
beautiful here."
"When we were children, we often played here."

m "Hey... ummm..."

window hide
show sylvie smile
with dissolve
window show

"She turned to me and smiled."


"I'll ask her..."
m "Ummm... will you..."
m "Will you be my artist for a visual novel?"
Customizing Characters

NVL-mode characters can be customized to have several looks, hopefully allowing you to pick
the one that is most appropriate to the game you are creating.

1. The default look has a character's name to the left, and dialogue indented to the right of
the name. The color of the name is controlled by the ''color'' parameter.

define s = Character('Sylvie', kind=nvl, color="#c8ffc8")

2. A second look has the character's name embedded in with the text. Dialogue spoken by
the character is enclosed in quotes. Note that here, the character's name is placed in the
''what_prefix'' parameter, along with the open quote. (The close quote is placed in the
''what_suffix'' parameter.)

define s = Character(None, kind=nvl, what_prefix="Sylvie: \"",


what_suffix="\"")

3. A third look dispenses with the character name entirely, while putting the dialogue in
quotes.

define s = Character(None, kind=nvl, what_prefix="\"", what_suffix="\"")

4. Since the third look might make it hard to distinguish who's speaking, we can tint the
dialogue using the ''what_color'' parameter.

define s = Character(None, kind=nvl, what_prefix="\"", what_suffix="\"",


what_color="#c8ffc8")

5. Of course, a completely uncustomized NVL-mode character can be used, if you want to


take total control of what is shown. (This is often used for the narrator.)

define s = Character(None, kind=nvl)

Customizing Menus

There are a few styles that control the look of the menus. Here's some code showing how to
customize them. See Styles and Style Properties for more information about styles.

init python:

# The color of a menu choice when it isn't hovered.


style.nvl_menu_choice.idle_color = "#ccccccff"

# The color of a menu choice when it is hovered.


style.nvl_menu_choice.hover_color = "#ffffffff"

# The color of the background of a menu choice, when it isn't


# hovered.
style.nvl_menu_choice_button.idle_background = "#00000000"

# The color of the background of a menu choice, when it is


# hovered.
style.nvl_menu_choice_button.hover_background = "#ff000044"

# How far from the left menu choices should be indented.


style.nvl_menu_choice_button.left_margin = 20

Customizing the NVL window

There are a few styles that control the NVL window; here's some code showing how to
customize them. See Styles and Style Properties for more information about styles.

init python:

# Set the background of the NVL window; this image should be the
# same size as the screen.
style.nvl_window.background = "nvl_window.png"

# Add some additional padding around the contents of the NVL window.
# This keeps the text inside the borders of our image.
style.nvl_window.xpadding = 55
style.nvl_window.ypadding = 55

# Set the spacing between each block of text on the page.


# The default is 10 pixels.
style.nvl_vbox.box_spacing = 10

You can also completely customize the screen used to display NVL text, which is named nvl;
see NVL.

Paged Rollback

Paged rollback causes Ren'Py to rollback one NVL-mode page at a time, rather than one block
of text at a time. It can be enabled by including the following code in your script.

init python:
config.nvl_paged_rollback = True

Script of The Question (NVL-mode Edition)

You can view the full script of the NVL-mode edition of ''The Question'' here.

Advanced Displayables

Drag and Drop

Ren'Py includes drag and drop displayables that allow things to be moved around the screen
with the mouse. Some of the uses of dragging are:

Allowing windows to be repositioned by the user, storing the window positions.


Card games that require cards to be dragged around the screen. (For example, solitaire.)
Inventory systems.
Drag-to-reorder systems.

The drag and drop displayables make it possible to implement these and other uses of drag
and drop. There are two classes involved here. The Drag class represents either something
that can be dragged around the screen, something that can have a draggable dropped onto it,
or something that can do both. The DragGroup class represents a group of Drags - for a drag
and drop to occur, both Drags must be part of the same drag group.
The drag and drop system can be used either through the Screen Language or directly as
displayables. It makes sense to use the screen language when you don't need to refer to the
Drags that you create after they've been created. This might be the case if the draggable
represents a window that the user places on the scren. If you need to refer to the drags after
they've been created, then it's often better to create Drags directly, and add them to a
DragGroup.

Displayables

class Drag( d=None, drag_name=None, draggable=True, droppable=True, drag_raise=True,


dragged=None, dropped=None, drag_handle=(0.0, 0.0, 1.0, 1.0), drag_joined=...,
clicked=None, hovered=None, unhovered=None, **properties)
A displayable that represents an object that can be dragged around its enclosing area. A
Drag can also represent an area that other Drags can be dropped on.
A Drag can be moved around inside is parent. Generally, its parent should be either a
Fixed()or DragGroup.
A Drag has one child. The child's state reflects the status of the drag and drop operation:

selected_hover- when it is being dragged.


selected_idle- when it can be dropped on.
hover- when the draggable will be dragged when the mouse is clicked.
idle- otherwise.
The drag handle is a rectangle inside the child. The mouse must be over a non-
transparent pixel inside the drag handle for dragging or clicking to occur.
A newly-created draggable is added to the default DragGroup. A draggable can only be in
a single DragGroup - if it's added to a second group, it's removed from the first.
When a Drag is first rendered, if it's position cannot be determined from the DragGroup it
is in, the position of its upper-left corner is computed using the standard layout algorithm.
Once that position

d
If present, the child of this Drag. Drags use the child style in preference to this, if it's
not None.
drag_name
If not None, the name of this draggable. This is available as the nameproperty of
draggable objects. If a Drag with the same name is or was in the DragGroup, the
starting position of this Drag is taken from that Draggable.
draggable
If true, the Drag can be dragged around the screen with the mouse.
droppable
If true, other Drags can be dropped on this Drag.
drag_raise
If true, this Drag is raised to the top when it is dragged. If it is joined to other Drags, all
joined drags are raised.
dragged
A callback (or list of callbacks) that is called when the Drag has been dragged. It is
called with two arguments. The first is a list of Drags that are being dragged. The
second is either a Drag that is being dropped onto, or None of a drop did not occur. If
the callback returns a value other than None, that value is returned as the result of the
interaction.
dropped
A callback (or list of callbacks) that is called when this Drag is dropped onto. It is called
with two arguments. The first is the Drag being dropped onto. The second is a list of
Drags that are being dragged. If the callback returns a value other than None, that
value is returned as the result of the interaction.
When a dragged and dropped callback are triggered for the same event, the dropped
callback is only called if dragged returns None.
clicked
A callback this is called, with no arguments, when the Drag is clicked without being
moved. A droppable can also be focused and clicked. If the callback returns a value
othe than None, that value is returned as the result of the interaction.
drag_handle
A (x, y, width, height) tuple, giving the position of the drag handle within the child. In
this tuple, integers are considered to be a literal number of pixels, while floats are
relative to the size of the child.
drag_joined
This is called with the current Drag as an argument. It's expected to return a list of [
(drag, x, y) ] tuples, giving the draggables to drag as a unit. xand yare the offsets of
the drags relative to each other, they are not relative to the corner of this drag.

Except for d, all of the parameters are available as fields (with the same name) on the
Drag object. In addition, after the drag has been rendered, the following fields become
available:

x, y
The position of the Drag relative to its parent, in pixels.
w, h
The width and height of the Drag's child, in pixels.

set_child(d)
Changes the child of this drag to d.

snap(x, y, delay=0)
Changes the position of the drag. If the drag is not showing, then the position change
is instantaneous. Otherwise, the position change takes delayseconds, and is animated
as a linear move.

top(self)
Raises this displayable to the top of its drag_group.

class DragGroup( *children, **properties)


Represents a group of Drags. A Drag is limited to the boundary of its DragGroup. Dropping
only works between Drags that are in the same DragGroup. Drags may only be raised
when they are inside a DragGroup.
A DragGroup is laid out like a Fixed().
All positional parameters to the DragGroup constructor should be Drags, that are added to
the DragGroup.

add(child)
Adds child, which must be a Drag, to this DragGroup.
get_child_by_name(name)
Returns the first child of this DragGroup that has a drag_name of name.

remove(child)
Removes childfrom this DragGroup.

Examples

An example of a say screen that allows the user to choose the location of the window by
dragging it around the screen.:

screen say:

drag:
drag_name "say"
yalign 1.0
drag_handle (0, 0, 1.0, 30)

xalign 0.5

window id "window":
# Ensure that the window is smaller than the screen.
xmaximum 600

has vbox

if who:
text who id "who"

text what id "what"

Here's a more complicated example, one that shows how dragging can be used to influence
gameplay. It shows how dragging can be used to send a character to a location:

init python:

def detective_dragged(drags, drop):

if not drop:
return

store.detective = drags[0].drag_name
store.city = drop.drag_name

return True

screen send_detective_screen:

# A map as background.
add "europe.jpg"

# A drag group ensures that the detectives and the cities can be
# dragged to each other.
draggroup:

# Our detectives.
drag:
drag_name "Ivy"
child "ivy.png"

droppable False
droppable False
dragged detective_dragged
xpos 100 ypos 100
drag:
drag_name "Zack"
child "zack.png"
droppable False
dragged detective_dragged
xpos 150 ypos 100

# The cities they can go to.


drag:
drag_name "London"
child "london.png"
draggable False
xpos 450 ypos 140
drag:
drag_name "Paris"
draggable False
child "paris.png"
xpos 500 ypos 280

label send_detective:
"We need to investigate! Who should we send, and where should they go?"

call screen send_detective_screen

"Okay, we'll send [detective] to [city]."

More complicated systems take significant programming skill to get right. The Ren'Py
cardgame framework is both an example of how to use drag and drop in a complex system,
and useful for making card games in its own right.

Sprites

To support the display of a large number of images at once, Ren'Py supports a sprite system.
This system allows one to create sprites, where each sprite contains a displayable. The sprites
can then have their location on the screen and vertical ordering changed.
If one ignores performance, the sprite system is conceptually similar to a Fixed()wrapping
Transform()s. Sprites are much faster than transforms, but also less flexible. The big
performance improvement of sprites is that each Displayable is rendered only once per frame,
even if that Displayable is used by many sprites. The limitation is that Sprites only allow one to
change their xoffset and yoffset, rather than the many properties that a Transform has.
To use the sprite system, create a SpriteManager object, and then call its create method to
create new particles. As necessary, update the xoffset, yoffset, and zorder fields of each sprite
to move it around the screen. By supplying updateand eventarguments to SpriteManager, you
can have the sprites change over time, and react to user input.

Sprite Classes

class Sprite
This represents a sprite that is managed by the SpriteManager. It contains fields that
control the placement of the sprite on the screen. Sprites should not be created directly.
Instead, they should be created by calling SpriteManager.create().
The fields of a sprite object are:

x, y
The x and y coordinates of the upper-left corner of the sprite, relative to the
SpriteManager.
zorder
An integer that's used to control the order of this sprite in the relative to the other
sprites in the SpriteManager. The larger the number is, the closer to the viewer the
sprite is.
events
If True, then events are passed to child. If False, the default, the children igore events
(and hence don't spend time processing them).

The methods of a Sprite object are:

destroy(self)
Destroys this sprite, preventing it from being displayed and removing it from the
SpriteManager.

set_child(d)
Changes the Displayable associated with this sprite to d.

class SpriteManager( update=None, event=None, predict=None, ignore_time=False,


**properties)
This displayable manages a collection of sprites, and displays them at the fastest speed
possible.

update
If not None, a function that is called each time a sprite is rendered by this sprite
manager. It is called with one argument, the time in seconds since this sprite manager
was first displayed. It is expected to return the number of seconds until the function is
called again, and the SpriteManager is rendered again.
event
If not None, a function that is called when an event occurs. It takes as arguments: * A
pygame event object. * The x coordinate of the event. * The y coordinate of the event.
* The time since the sprite manager was first shown. If it returns a non-None value, the
interaction ends, and that value is returned.
predict
If not None, a function that returns a list of displayables. These displayables are
predicted when the sprite manager is.
ignore_time
If True, then time is ignored when rendering displayables. This should be used when
the sprite manager is used with a relatively small pool of images, and those images do
not change over time. This should only be used with a small number of displayables,
as it will keep all displayables used in memory for the life of the SpriteManager.

After being rendered once (before the updatefunction is called), SpriteManagers have the
following fields:
width, height

The width and height of this SpriteManager, in pixels.


SpriteManagers have the following methods:

create(d)
Creates a new Sprite for the displayable d, and adds it to this SpriteManager.

SnowBlossom(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0,


fast=False, horizontal=False)
The snowblossom effect moves multiple instances of a sprite up, down, left or right on the
screen. When a sprite leaves the screen, it is returned to the start.

d
The displayable to use for the sprites.
border
The size of the border of the screen. The sprite is considered to be on the screen until
it clears the border, ensuring that sprites do not disappear abruptly.
xspeed, yspeed
The speed at which the sprites move, in the horizontal and vertical directions,
respectively. These can be a single number or a tuple of two numbers. In the latter
case, each particle is assigned a random speed between the two numbers. The
speeds can be positive or negative, as long as the second number in a tuple is larger
than the first.
start
The delay, in seconds, before each particle is added. This can be allows the particles
to start at the top of the screen, while not looking like a "wave" effect.
fast
If true, particles start in the center of the screen, rather than only at the edges.
horizontal
If true, particles appear on the left or right side of the screen, rather than the top or
bottom.

Sprite Examples

The SnowBlossom class is an easy-to use way of placing falling things on the screen.

image snow = SnowBlossom("snow.png", count=100)

This example shows how a SpriteManager can be used to create complex behaviors. In this
case, it shows 400 particles, and has them avoid the mouse.

init python:
import math

def repulsor_update(st):

# If we don't know where the mouse is, give up.


if repulsor_pos is None:
return .01

px, py = repulsor_pos

# For each sprite...


for i in repulsor_sprites:

# Compute the vector between it and the mouse.


# Compute the vector between it and the mouse.
vx = i.x - px
vy = i.y - py

# Get the vector length, normalize the vector.


vl = math.hypot(vx, vy)
if vl >= 150:
continue

# Compute the distance to move.


distance = 3.0 * (150 - vl) / 150

# Move
i.x += distance * vx / vl
i.y += distance * vy / vl

# Ensure we stay on the screen.


if i.x < 2:
i.x = 2

if i.x > repulsor.width - 2:


i.x = repulsor.width - 2

if i.y < 2:
i.y = 2

if i.y > repulsor.height - 2:


i.y = repulsor.height - 2

return .01

# On an event, record the mouse position.


def repulsor_event(ev, x, y, st):
store.repulsor_pos = (x, y)

label repulsor_demo:

python:
# Create a sprite manager.
repulsor = SpriteManager(update=repulsor_update, event=repulsor_event)
repulsor_sprites = [ ]
repulsor_pos = None

# Ensure we only have one smile displayable.


smile = Image("smile.png")

# Add 400 sprites.


for i in range(400):
repulsor_sprites.append(repulsor.create(smile))

# Position the 400 sprites.


for i in repulsor_sprites:
i.x = renpy.random.randint(2, 798)
i.y = renpy.random.randint(2, 598)

del smile
del i

# Add the repulsor to the screen.


show expression repulsor as repulsor

"..."
hide repulsor

# Clean up.
python:
del repulsor
del repulsor_sprites
del repulsor_pos

Python and Ren'Py

Statement Equivalents

To allow Ren'Py to be scripted in python, each Ren'Py statement has equivalent Python code.
This usually consists of a Python function, but may also consist of a code pattern that performs
an action equivalent to the statement.

Dialogue

The Ren'Py say statement is equivalent to calling the character object as a function. The
following code displays the same line twice:

e "Hello, world."

$ e("Hello, world.")

Displaying narration can be done the same way, by using the narratorcharacter. When
calling a character, it's possible to supply the keyword argument interact. When interact is
false, Ren'Py will display the character dialogue box, and will then return before performing an
interaction.
This equivalence of characters and function objects works in the other direction as well. It is
possible to declare a python function, and then use that function in the place of a character
object. For example, the following function uses a variable to choose between two characters.

define lucy_normal = Character("Lucy")


define lucy_evil = Character("Evil Lucy")

init python:

def l(what, **kwargs):


if lucy_is_evil:
lucy_evil(what, **kwargs)
else:
lucy_normal(what, **kwargs)

label start:

$ lucy_is_evil = False

l "Usually, I feel quite normal."

$ lucy_is_evil = True

l "But sometimes, I get really mad!"


A function used in this way should either ignore unknown keyword arguments, or pass them to
a character function. Doing this will allow the game to continue working if Ren'Py adds
additional keyword arguments to character calls.

Displaying Images

The image, scene, show, and hide statements each have an equivalent python function.

renpy.hide(name, layer='master')
Hides an image from a layer. The python equivalent of the hide statement.

name
The name of the image to hide. Only the image tag is used, and any image with the
tag is hidden (the precise name does not matter).
layer
The layer on which this function operates.

renpy.image(name, d)
Defines an image. This function is the python equivalent of the image statement.

name
The name of the image to display, a string.
d
The displayable to associate with that image name.

This function may only be run from inside an init block. It is an error to run this function
once the game has started.

renpy.scene(layer='master')
Removes all displayables from layer. This is equivalent to the scene statement, when the
scene statement is not given an image to show.
A full scene statement is equivalent to a call to renpy.scene followed by a call to
renpy.show(). For example:

scene bg beach

is equivalent to:

$ renpy.scene()
$ renpy.show("bg beach")

renpy.show(name, at_list=[], layer='master', what=None, zorder=0, tag=None,


behind=[])
Shows an image on a layer. This is the programmatic equivalent of the show statement.

name
The name of the image to show, a string.
at_list
A list of transforms that are applied to the image. The equivalent of the atproperty.
layer
A string, giving the name of the layer on which the image will be shown. The
equivalent of the onlayerproperty.
what
If not None, this is a displayable that will be shown in lieu of looking on the image.
(This is the equivalent of the show expression statement.) When a whatparameter is
given, namecan be used to associate a tag with the image.
zorder
An integer, the equivalent of the zorderproperty.
tag
A string, used to specify the the image tag of the shown image. The equivalent of the
asproperty.
behind
A list of strings, giving image tags that this image is shown behind. The equivalent of
the behindproperty.

Transitions

The equivalent of the with statement is the renpy.with_statement function.

renpy.with_statement(trans, always=False)
Causes a transition to occur. This is the python equivalent of the with statement.

trans
The transition.
always
If True, the transition will always occur, even if the user has disabled transitions.

This function returns true if the user chose to interrupt the transition, and false otherwise.

Saving, Loading, and Rollback

Ren'Py has support for saving game state, loading game state, and rolling back to a previous
game state. Although implemented in a slightly different fashion, rollback can be thought of as
saving the game at the start of each statement that interacts with the user, and loading saves
when the user rolls back.

Note
While we usually attempt to keep save compatibility between releases, this compatibility is not
guaranteed. We may decide to break save-compatibility if doing so provides a sufficiently large
benefit.

What is Saved

Ren'Py attempts to save the game state. This includes both internal state and python state.
The internal state consists of all aspects of Ren'Py that are intented to change once the game
has started, and includes:
The current statement, and all statements that can be returned to.
The images and displayables that are being shown.
The screens being shown, and the values of variables within those screens.
The music that Ren'Py is playing.
The list of nvl-mode text blocks.

The python state consists of the variables in the store that have changed since the game
began, and all objects reachable from those variables. Note that it's the change to the
variables that matters - changes to fields in objects will not cause those objects to be saved.
In this example:

define a = 1
define o = object()

label start:
$b=1
$ o.value = 42

only bwill be saved. A will not be saved because it does not change once the game begins. Ois
not saved because it does not change - the object it refers to changes, but the variable itself
does not.

What isn't Saved

Python variables that are not changed before the game begins will not be saved. This can be a
major problem if a variable that is saved and one that is refer to the same object. (Alias the
object.) In this example:

init python:
a = object()
a.f = 1

label start:
$b=a
$ b.f = 2

"a.f=[a.f] b.f=[b.f]"

aand bare aliased. Saving and loading may break this aliasing, causing aand bto refer to
different objects. Since this can be very confusing, it's best to avoid aliasing saved and
unsaved variables. (This is rare to encounter directly, but might come up when an unsaved
variable and saved field alias.)
There are several other kinds of state that isn't saved:

control flow path


Ren'Py only saves the current statement, and the statement it needs to return to. It doesn't
remember how it got there. Importantly, if code (like variable assignments) is added to the
game, it won't run.
mappings of image names to displayables
Since this mapping is not saved, the image may change to a new image when the game
loads again. This allows an image to change to a new file as the game evolves.
configuration variables, styles, and style properties
Configuration variables and styles aren't saved as part of the game. Therefore, they
should only be changed in init blocks, and left alone once the game has started.
Where Ren'Py Saves

Saves occur at the start of a Ren'Py statement in the outermost interaction context.
What's important here is to note that saving occurs at the start of a statement. If a load or
rollback occurs in the middle of a statement that interacts multiple times, the state will be the
state that was active when the statement began.
This can be a problem in python-defined statements. In code like:

python:
i=0
while i < 10:
i += 1
narrator("The count is now [i].")

if the user saves and loads in the middle, the loop will begin anew. Using similar code in Ren'Py
- rather than Python - avoids this problem.:

$i=0
while i < 10:
$ i += 1
"The count is now [i]."

What Ren'Py can Save

Ren'Py uses the python pickle system to save game state. This module can save:

Basic types, such as True, False, None, int, str, float, complex, str, and unicode objects.
Compound types, like lists, tuples, sets, and dicts.
Creator-defined objects, classes, functions, methods, and bound methods. For pickling
these functions to succeed, they must remain available under their original names.
Character, Displayable, Transform, and Transition objects.

There are certain types that cannot be pickled:

Render objects.
Iterator objects.
File-like objects.
Inner functions and lambdas.

By default, Ren'Py uses the cPickle module to save the game. Setting config.use_cpicklewill
make Ren'Py use the pickle module instead. This makes the game slower, but is better at
reporting save errors.

Save Functions and Variables

There is one variable that is used by the high-level save system:

save_name= ...
This is a string that is stored with each save. It can be used to give a name to the save, to
help users tell them apart.

There are a number of high-level save actions and functions defined in the screen actions. In
addition, there are the following low-level save and load actions.

renpy.can_load(filename, test=False)
Returns true if filenameexists as a save file, and False otherwise.

renpy.list_saved_games(regexp='.', fast=False)
Lists the save games. For each save game, returns a tuple containing:

The filename of the save.


The extra_info that was passed in.
A displayable that, when displayed, shows the screenshot that was used when saving
the game.
The time the game was stayed at, in seconds since the UNIX epoch.

regexp
A regular expression that is matched against the start of the filename to filter the list.
fast
If fast is true, the filename is returned instead of the tuple.

renpy.load(filename)
Loads the game state from filename. This function never returns.

renpy.rename_save(old, new)
Renames a save from oldto new.

renpy.save(filename, extra_info='')
Saves the game state to a save slot.

filename
A string giving the name of a save slot. Despite the variable name, this corresponds
only loosely to filenames.
extra_info
An additional string that should be saved to the save file. Usually, this is the value of
save_name.

renpy.take_screenshot()should be called before this function.

renpy.take_screenshot(scale=None, background=False)
Causes a screenshot to be taken. This screenshot will be saved as part of a save game.

renpy.unlink_save(filename)
Deletes the save with the given filename.

Rollback

Rollback allows the user to revert the game to an earlier state in much the same way as
undo/redo systems that are available in most modern applications. While the system takes
care of maintaining the visuals and game variables during rollback events, there are several
things that should be considered while creating a game.

Supporting Rollback and Roll Forward


Most Ren'Py statements automatically support rollback and roll forward. If you call
ui.interact()directly, you'll need to add support for rollback and roll-forward yourself. This
can be done using the following structure:

# This is None if we're not rolling back, or else the value that was
# passed to checkpoint last time if we're rolling forward.
roll_forward = renpy.roll_forward_info()

# Set up the screen here...

# Interact with the user.


rv = ui.interact(roll_forward=roll_forward)

# Store the result of the interaction.


renpy.checkpoint(rv)

It's important that your game does not interact with the user after renpy.checkpoint has been
called. (If you do, the user may not be able to rollback.)

renpy.checkpoint(data=None)
Makes the current statement a checkpoint that the user can rollback to. Once this function
has been called, there should be no more interaction with the user in the current
statement.

data
This data is returned by renpy.roll_forward_info()when the game is being rolled
back.

renpy.in_rollback()
Returns true if the game has been rolled back.

renpy.roll_forward_info()
When in rollback, returns the data that was supplied to renpy.checkpoint()the last time
this statement executed. Outside of rollback, returns None.

Blocking Rollback

Warning
Blocking rollback is a user-unfriendly thing to do. If a user mistakenly clicks on an unintended
choice, he or she will be unable to correct their mistake. Since rollback is equivalent to saving and
loading, your users will be forced to save more often, breaking game engagement.

It is possible to disable rollback in part or in full. If rollback is not wanted at all, it can simply be
turned of through the config.rollback_enabledoption.

More common is a partial block of rollback. This can be achieved by the


renpy.block_rollback()function. When called, it will instruct Ren'Py not to roll back before
that point. For example:

label final_answer:
"Is that your final answer?"

menu:
"Yes":
jump no_return
"No":
"We have ways of making you talk."
"You should contemplate them."
"I'll ask you one more time..."
jump final_answer

label no_return:
$ renpy.block_rollback()

"So be it. There's no turning back now."

When the label no_return is reached, Ren'Py won't allow a rollback back to the menu.

Fixing Rollback

Fixing rollback provides for an intemediate choice between unconstrained rollback and
blocking rollback entirely. Rollback is allowed, but the user is not allowed to make changes to
their decisions. Fixing rollback is done with the renpy.fix_rollback()function, as shown in the
following example:

label final_answer:
"Is that your final answer?"
menu:
"Yes":
jump no_return
"No":
"We have ways of making you talk."
"You should contemplate them."
"I'll ask you one more time..."
jump final_answer

label no_return:
$ renpy.fix_rollback()

"So be it. There's no turning back now."

Now, after the fix_rollback function is called, it will still be possible for the user to roll back to
the menu. However, it will not be possible to make a different choice.
There are some caveats to consider when designing a game for fix_rollback. Ren'Py will
automatically take care of locking any data that is given to checkpoint(). However, due to the
generic nature of Ren'Py, it is possible to write Python code that bypasses this and changes
things in ways that may have unpredictable results. It is up to the game designer to block
rollback at problematic locations or write additional code to deal with it.
The internal user interaction options for menus, renpy.input()and renpy.imagemap()are
designed to fully work with fix_rollback.

Styling Fixed Rollback

Because fix_rollback changes the functionality of menus and imagemaps, it is advisable to


reflect this in the appearance. To do this, it is important to understand how the widget states of
the menu buttons are changed. There are two modes that can be selected through the
config.fix_rollback_without_choiceoption.

The default option will set the chosen option to "selected", thereby activating the style
properties with the "selected_" prefix. All other buttons will be made insensitive and show using
the properties with the "insensitive_" prefix. Effectively this leaves the menu with a single
selectable choice.
When the config.fix_rollback_without_choiceoption is set to False, all buttons are made
insensitive. This means that the chosen option will use the "selected_insensitive_" prefix for the
style properties while the other buttons use properties with the "insensitive_" prefix.

Fixed Rollback and Custom Screens

When writing custom Python routines that must play nice with the fix_rollback system there are
a few simple things to know. First of all the renpy.in_fixed_rollback()function can be used
to determine whether the game is currently in fixed rollback state. Second, when in fixed
rollback state, ui.interact()will always return the supplied roll_forward data regardless of
what action was performed. This effectively means that when the
ui.interact()/renpy.checkpoint()functions are used, most of the work is done.

To simplify the creation of custom screens, two actions are provided to help with the most
common uses. The ui.ChoiceReturn()action returns the value when the button it is attached
to is clicked. The ui.ChoiceJump()action can be used to jump to a script label. However, this
action only works properly when the screen is called trough a call screenstatement.
Example:

screen demo_imagemap:
imagemap:
ground "imagemap_ground.jpg"
hover "imagemap_hover.jpg"
selected_idle "imagemap_selected_idle.jpg"
selected_hover "imagemap_hover.jpg"

hotspot (8, 200, 78, 78) action ui.ChoiceJump("swimming", "go_swimming", block_all


hotspot (204, 50, 78, 78) action ui.ChoiceJump("science", "go_science_club", block_a
hotspot (452, 79, 78, 78) action ui.ChoiceJump("art", "go_art_lessons", block_all
hotspot (602, 316, 78, 78) action uiChoiceJump("home", "go_home", block_all=False

Example:

python:
roll_forward = renpy.roll_forward_info()
if roll_forward not in ("Rock", "Paper", "Scissors"):
roll_forward = None

ui.hbox()
ui.imagebutton("rock.png", "rock_hover.png", selected_insensitive="rock_hover.png",
ui.imagebutton("paper.png", "paper_hover.png", selected_insensitive="paper_hover.png"
ui.imagebutton("scissors.png", "scissors_hover.png", selected_insensitive="scissors_hove
ui.close()

if renpy.in_fixed_rollback():
ui.saybehavior()

choice = ui.interact(roll_forward=roll_forward)
renpy.checkpoint(choice)

$ renpy.fix_rollback()
m "[choice]!"

Rollback-blocking and -fixing Functions

renpy.block_rollback()
Prevents the game from rolling back to before the current statement.

renpy.fix_rollback()
Prevents the user from changing decisions made before the current statement.

renpy.in_fixed_rollback()
Returns true if rollback is currently occurring and the current context is before an
executed renpy.fix_rollback() statement.

ui.ChoiceJump(label, value, location=None, block_all=None)


A menu choice action that returns value, while managing the button state in a manner
consistent with fixed rollback. (See block_all for a description of the behavior.)

label
The label text of the button. For imagebuttons and hotspots this can be anything. This
label is used as a unique identifier of the options within the current screen. Together
with locationit is used to store whether this option has been chosen.
value
The location to jump to.
location
A unique location identifier for the current choices screen.
block_all
If false, the button is given the selected role if it was the chosen choice, and
insensitive if it was not selected.
If true, the button is always insensitive during fixed rollback.
If None, the value is taken from the config.fix_rollback_without_choicevariable.
When true is given to all items in a screen, it will become unclickable (rolling forward
will still work). This can be changed by calling ui.saybehavior()before the call to
ui.interact().

ui.ChoiceReturn(label, value, location=None, block_all=None)


A menu choice action that returns value, while managing the button state in a manner
consistent with fixed rollback. (See block_all for a description of the behavior.)

label
The label text of the button. For imagebuttons and hotspots this can be anything. This
label is used as a unique identifier of the options within the current screen. Together
with locationit is used to store whether this option has been chosen.
value
The value this is returned when the choice is chosen.
location
A unique location identifier for the current choices screen.
block_all
If false, the button is given the selected role if it was the chosen choice, and
insensitive if it was not selected.
If true, the button is always insensitive during fixed rollback.
If None, the value is taken from the config.fix_rollback_without_choicevariable.
When true is given to all items in a screen, it will become unclickable (rolling forward
will still work). This can be changed by calling ui.saybehavior()before the call to
ui.interact().

Transforms and Transitions in Python

Python can be used to create new transforms and transitions for use by Ren'Py scripts.

Transforms

A transform is a python callable that, when called with a displayable, returns another
displayable.
For example:

init python:

# This is a transform that uses the right and


# left transforms.
def right_or_left(d):
if switch:
return right(d)
else:
return left(d)

The python equivalent of an ATL transform is a Transform object.

class Transform( child=None, function=None, **properties)


A transform applies operations such as cropping, rotation, scaling, and alpha-blending to
its child. A transform object has fields corresponding to the transform properties, which it
applies to its child.

child
The child the transform applies to.
function
If not none, this is a function that is called when the transform is rendered. The
function is called with three arguments:

The transform object.


The shown timebase, in seconds.
The animation timebase, in seconds.
The function should return a delay, in seconds, after which it will be called again, or
None to never be called again.

Additional arguments are taken as values to set transform properties to.

hide_request
This is set to true when the function is caled, to indicate that the transform is being
hidden.

hide_response
If hide request is true, this can be set to false to prevent the transform from being
hidden.
set_child(child)
Call this method with a new childto change the child of this transform.

update()
This should be called when a transform property field is updated outside of the
callback method, to ensure that the change takes effect.

Transitions

A transition is a python callable that, when called with two keyword arguments, returns a
displayable that performs the transition effect. The two keyword arguments are:

old_widget
A displayable representing the old screen.
new_widget
A displayable representing the new screen.

The returned displayable should have a delayfield, which gives the number of seconds the
transition should run for.
For example:

init python:

def dissolve_or_pixellate(old_widget=None, new_widget=None):


if persistent.want_pixellate:
return pixellate(old_widget=old_widget, new_widget=new_widget)
else:
return dissolve(old_widget=old_widget, new_widget=new_widget)

Screens and Python

Ren'Py supports defining screens in Python, as well as in the Ren'Py screen language. A Python
screen is created by supplying a screen function to the renpy.define_screen()function. It can
then be used like it was any other screen.
The screen function should have parameters corresponding to the scope variables it expects,
and it should ignore extra keyword arguments. (That is, it should have **kwargsat the end of
its parameter list.) It is then expected to call the UI functions to add displayables to the
screen.The screen function is called whenever an interaction starts or restarts.
To ensure that this restarting is seamless to the user (and not causing things to reset), it's
important that every call to a UI function supply the idargument. As a screen is re-created,
Ren'Py will update each displayable with the contents of the old displayable with the same id.
Ids are generated automatically by the screen language, but when doing things by hand, they
must be manually specified.
Here's an example python screen:

init python:
def say_screen(who, what, **kwargs):
ui.window(id="window")
ui.vbox(id="say_vbox")

ui.text(who, id="who")
ui.text(what, id="what")

ui.close("return")

renpy.define_screen("say", say_screen)

Screen Functions

The following functions support the definition, display, and hiding of screens.

renpy.call_screen(_screen_name, **kwargs)
The programmatic equivalent of the show screen statement.
This shows _screen_nameas a screen, then causes an interaction to occur. The screen is
hidden at the end of the interaction, and the result of the interaction is returned.
Keyword arguments not beginning with _ are passed to the scope of the screen.

renpy.define_screen(name, function, modal="False", zorder="0", tag=None,


variant=None)
Defines a screen with name, which should be a string.

function
The function that is called to display the screen. The function is called with the screen
scope as keyword arguments. It should ignore additional keyword arguments.
The function should call the ui functions to add things to the screen.
modal
A string that, when evaluated, determines of the created screen should be modal. A
modal screen prevents screens underneath it from receiving input events.
zorder
A string that, when evaluated, should be an integer. The integer controls the order in
which screens are displayed. A screen with a greater zorder number is displayed
above screens with a lesser zorder number.
tag
The tag associated with this screen. When the screen is shown, it replaces any other
screen with the same tag. The tag defaults to the name of the screen.
predict
If true, this screen can be loaded for image prediction. If false, it can't. Defaults to
true.
variant
String. Gives the variant of the screen to use.

renpy.get_screen(name, layer='screens')
Returns the ScreenDisplayable with the given tag, on layer. If no displayable with the tag
is not found, it is interpreted as screen name. If it's still not found, None is returned.

renpy.get_widget(screen, id, layer='screens')


From the screenon layer, returns the widget with id. Returns None if the screen doesn't
exist, or there is no widget with that id on the screen.
renpy.hide_screen(tag, layer='screens')
The programmatic equivalent of the hide screen statement.
Hides the screen with tagon layer.

renpy.show_screen(_screen_name, _layer='screens', _tag=None, _widget_properties={},


_transient=False, **kwargs)
The programmatic equivalent of the show screen statement.
Shows the named screen.

_screen_name
The name of the screen to show.
_layer
The layer to show the screen on.
_tag
The tag to show the screen with. If not specified, defaults to the tag associated with
the screen. It that's not specified, defaults to the name of the screen.,
_widget_properties
A map from the id of a widget to a property name -> property value map. When a
widget with that id is shown by the screen, the specified properties are added to it.
_transient
If true, the screen will be automatically hidden at the end of the current interaction.

Keyword arguments not beginning with underscore (_) are used to initialize the screen's
scope.

renpy.variant(name)
Returns true if a nameis a screen variant that can be chosen by Ren'Py. See Screen
Variants for more details. This function can be used as the condition in a python if
statement to set up the appropriate styles for the selected screen variant.

UI Functions

The UI functions are python equivalents of the screen language statements. For each screen
language statement, there is a ui function with the same name. For example, ui.text
corresponds to the text statement, and ui.add corresponds to the add statement.
There is a simple mapping between screen language parameters and arguments and python
arguments. Screen language parameters become positional arguments, while properties
become keyword arguments. For example, the screen language statement:

text "Hello, World" size 40 xalign 0.5

becomes:

ui.text("Hello, World", size=40, xalign=0.5)

(It really should have an idparameter added.)


There are three groups of UI functions, corresponding to the number of children they take.
The following UI functions do not take any children.
ui.add
ui.bar
ui.imagebutton
ui.input
ui.key
ui.label
ui.null
ui.text
ui.textbutton
ui.timer
ui.vbar
ui.hotspot
ui.hotbar
ui.spritemanager

The following UI functions take a single child. They must be given that child - use ui.null() if the
child is missing.

ui.button
ui.frame
ui.transform
ui.window
ui.drag

The following UI functions take multiple children. They continue taking children until
ui.close()is called.

ui.fixed
ui.grid
ui.hbox
ui.side
ui.vbox
ui.imagemap
ui.draggroup

There are a few UI functions that do not correspond to screen language statments, as they
correspond to concepts that are not present in the screen language.

ui.adjustment(range=1, value=0, step=None, page=0, changed=None, adjustable=None,


ranged=None)
Adjustment objects represent a value that can be adjusted by a bar or viewport. They
contain information about the value, the range of the value, and how to adjust the value in
small steps and large pages.
The following parameters correspond to fields or properties on the adjustment object:

range
The range of the adjustment, a number.
value
The value of the adjustment, a number.
step
The step size of the adjustment, a number. If None, then defaults to 1/10th of a page,
if set. Otherwise, defaults to the 1/20th of the range.
This is used when scrolling a viewport with the mouse wheel.
page
The page size of the adjustment. If None, this is set automatically by a viewport. If
never set, defaults to 1/10th of the range.
It's can be used when clicking on a scrollbar.

The following parameters control the behavior of the adjustment.

adjustable
If True, this adjustment can be changed by a bar. If False, it can't.
It defaults to being adjustable if a changedfunction is given or if the adjustment is
associated with a viewport, and not adjustable otherwise.
changed
This function is called with the new value when the value of the adjustment changes.
ranged
This function is called with the adjustment object when the range of the adjustment is
set by a viewport.

change(value)
Changes the value of the adjustment to value, updating any bars and viewports that
use the adjustment.

ui.at(transform)
Specifieds a transform that is applied to the next displayable to be created. This is largely
obsolete, as all UI functions now take an atargument.

ui.close()
Closes a displayable created with by a UI function. When a displayable is closed, we add
new displayables to its parent, or to the layer if no displayable is open.

ui.detached()
Do not add the next displayable to any later or container. Use this if you want to assign the
result of a ui function to a variable.

ui.layer(name)
Adds displayables to the layer named name. The later must be closed with ui.close().

Actions

Many of the displayables created in the screen language take actions as arguments. An action
is one of three things:

A callable python object (like a function or bound method) that takes no arguments.
An object of a class that inherits from the Action class.
A list of other Actions.

The advantage to inheriting from the Action class is that it allows you to override the methods
that determine when a button should be sensitive, and when it is selected.

class Action
To define a new action, inherit from this class. Override the methods in this class to
change the behavior of the action.
__call__(self)
This is the method that is called when the action is activated. In many cases, returning
a non-None value from the action will cause the current interaction to end.
This method must be overriden, as the default method will raise NotImplemented (and
hence cause Ren'Py to report an error).

get_sensitive(self)
This is called to determine if the button with this action should be sensitive. It should
return true if the button is sensitive.
Note that __call__ can be called, even if this returns False.
The default implementation returns True.

get_selected(self)
This should return true if the button should be rendered as a selected button, and
false otherwise.
The default implemention returns False.

periodic(self, st)
This method is called once at the start of each interaction, and then is called
periodically thereafter. If it returns a number, it will be called before that many
seconds elapse, but it might be called sooner.
The main use of this is to call renpy.restart_interaction()if the value of
get_selected or get_sensitive should change.
It takes one argument:

st
The number of seconds since the screen or displayable this action is associated
with was first shown.

unhovered(self):
When the action is used as the hoveredparameter to a button (or similar object), this
method is called when the object loses focus.

BarValues

When creating a bar, vbar, or hotbar, a BarValue object can be supplied as the value
argument. Methods on the BarValue object are called to get the adjustment and styles.

class BarValue
To define a new BarValue, inherit from this class and override some of the methods.

get_adjustment(self)
This method is called to get an adjustment object for the bar. It should create the
adjustment with ui.adjustment(), and then return the object created this way.
This method must be overriden, as the default method will raise NotImplemented (and
hence cause Ren'Py to report an error).

get_style(self)
This is used to determine the style of bars that use this value. It should return a tuple
of two style names or style objects. The first is used for a bar, and the second for vbar.
This defaults to ("bar", "vbar").
replaces(self, other)
This is called when a BarValue replaces another BarValue, such as when a screen is
updated. It can be used to update this BarValue from the other. It is called before
get_adjustment.
Note that otheris not necessarily the same type as self.

periodic(self, st)
This method is called once at the start of each interaction. If it returns a number of
seconds, it will be called before that many seconds elapse, but it might be called
sooner. It is called after get_adjustment.
It can be used to update the value of the bar over time, like AnimatedValue()does. To
do this, get_adjustment should store the adjustment, and periodic should calle the
adjustment's changed method.

Modes

In Ren'Py, a mode is a concise way of describing the type of an interaction. When a mode is
reported to Ren'Py, user-defined callbacks can be run. These calbacks can be used to react to
a change in mode, perhaps by reconfiguring the user interface. For example, one can cause a
transition to occur when switching from ADV-mode to NVL-mode, or when going to a menu,
etc.
The goal of the mode systems is to provide a powerful and flexible way of detecting and
responding to these changes.

Default Modes

The following are the modes corresponding to built-in interactions:

start
This is the mode that Ren'Py is in when a new context is created, such as at the start of a
game. Ren'Py never automatically enters this mode, but instead, initializes the list of
modes to include start.
say
The mode Ren'Py enters when an ADV-mode say executes.
menu
The mode Ren'Py enters when an ADV-mode menu executes.
nvl
The mode Ren'Py enters when an NVL-mode say executes.
nvl_menu
The mode Ren'Py enters when an NVL-mode menu executes.
pause
The mode Ren'Py enters when renpy.pause()is run. This is also the mode Ren'Py is in
when a pausestatement of indefinite duration occurs.
with
The mode Ren'Py enters when a transition introduced by the withstatement occurs. This
is also used for pausestatement with a duration specified.
Note that the with mode is entered at the start of the with statement, which is after any
preceding scene, show, or hide statements have been run.
screen
The mode Ren'Py enters when a screen is invoked using the call screenstatement.
imagemap
The mode Ren'Py enters when an old-style imagemap is invoked using renpy.imagemap().
input
The mode Ren'Py enters when text input is requested using the renpy.input()function.

Other modes can be entered by calling the renpy.mode function.

renpy.mode(mode)
Causes Ren'Py to enter the named mode, or stay in that mode if it's already in it.

Mode Callbacks

The config.mode_callbacksvariable contains a list of mode callbacks that are invoked


whenever Ren'Py enters a mode. The mode callbacks are called with two parameters:

mode
A string giving the name of the mode that we are entering.
old_modes
A list of strings, giving the modes that the system has previously entered, ordered from
most recent to least recent.

Note that when entering a mode we're already in, the first item in old_modeswill be equal to
mode.

Example Mode Callbacks

This mode callback causes transitions to occur when switching from ADV to NVL mode, and
vice-versa. This ships as part of Ren'Py, so there's no need to actually use it.

init python:
def _nvl_adv_callback(mode, old_modes):

old = old_modes[0]

if config.adv_nvl_transition:
if mode == "nvl" or mode == "nvl_menu":
if old == "say" or old == "menu":
nvl_show(config.adv_nvl_transition)

if config.nvl_adv_transition:
if mode == "say" or mode == "menu":
if old == "nvl" or old == "nvl_menu":
nvl_hide(config.nvl_adv_transition)

config.mode_callbacks.append(_nvl_adv_callback)

Creator-Defined Displayables

The most complex, but most powerful, way of customizing Ren'Py's behavior is to use a
creator-defined displayable. A creator-defined displayable is allowed to take arbitrary pygame
events. It can also render other displayables, and place them at arbitrary locations on the
events. It can also render other displayables, and place them at arbitrary locations on the
screen. This makes it suitable for creating 2D mini-games that cannot be expressed with the
tools Ren'Py gives you. (But see also the section sprites, which describes a higher-level way of
accomplishing many of the same things.)
Creator-defined displayables are programmed entirely in Python, and we encourage you to
have a reasonable degree of skill at object-oriented Python programming before you begin
creating one.

Example

Here's an example of a creator-defined displayable. This displayable changes renders its child
with an alpha that is determined by the distance of the mouse pointer from the center of the
child.

init python:

import math

class Appearing(renpy.Displayable):

def __init__(self, child, opaque_distance, transparent_distance, **kwargs):

# Pass additional properties on to the renpy.Displayable


# constructor.
super(Appearing, self).__init__(**kwargs)

# The child.
self.child = renpy.displayable(child)

# The distance at which the child will become fully opaque, and
# where it will become fully transparent. The former must be less
# than the latter.
self.opaque_distance = opaque_distance
self.transparent_distance = transparent_distance

# The alpha channel of the child.


self.alpha = 0.0

# The width and height of us, and our child.


self.width = 0
self.height = 0

def render(self, width, height, st, at):

# Create a transform, that can adjust the alpha channel of the


# child.
t = Transform(child=self.child, alpha=self.alpha)

# Create a render from the child.


child_render = renpy.render(t, width, height, st, at)

# Get the size of the child.


self.width, self.height = child_render.get_size()

# Create the render we will return.


render = renpy.Render(self.width, self.height)

# Blit (draw) the child's render to our render.


render.blit(child_render, (0, 0))
# Return the render.
return render

def event(self, ev, x, y, st):

# Compute the distance between the center of this displayable and


# the mouse pointer. The mouse pointer is supplied in x and y,
# relative to the upper-left corner of the displayable.
distance = math.hypot(x - (self.width / 2), y - (self.height / 2))

# Base on the distance, figure out an alpha.


if distance <= self.opaque_distance:
alpha = 1.0
elif distance >= self.transparent_distance:
alpha = 0.0
else:
alpha = 1.0 - 1.0 * (distance - self.opaque_distance) / (self.transparent_di

# If the alpha has changed, trigger a redraw event.


if alpha != self.alpha:
self.alpha = alpha
renpy.redraw(self, 0)

# Pass the event to our child.


return self.child.event(ev, x, y, st)

def visit(self):
return [ self.child ]

To use the creator-defined displayable, we can create an instance of it, and add that instance
to the screen.

screen alpha_magic:
add Appearing("logo.png", 100, 200):
xalign 0.5
yalign 0.5

label start:
show screen alpha_magic

"Can you find the logo?"

return

renpy.Displayable

A creator-defined displayable is created by subclassing the renpy.Displayable class. A creator-


defined displayable must override the render method, and may override other methods as
well.
A displayable object must be pickleable, which means it may not contain references to objects
that cannot be pickled. Most notably, Render objects cannot be stored in a creator-defined
displayable.
Since we expect you to override the methods of the displayable class, we'll present them with
the selfparameter.

class renpy.Displayable
Base class for creator-defined displayables.

__init__(**properties):
A subclass may override the constructor, perhaps adding new parameters. If it does, it
should pass all unknown keyword arguments to the renpy.Displayable constructor,
using code like:

super(MyDisplayable, self).__init__(properties)

render(self, width, height, st, at)


Subclasses must override this, to return a renpy.Renderobject. The render object
determines what, if anything, is shown on the screen.

width, height
The amount of space available to this displayable, in pixels.
st
A float, the shown timebase, in seconds. The shown timebase begins when this
displayable is first shown on the screen.
at
A float, the animation timebase, in seconds. The animation timebase begins when
an image with the same tag was shown, without being hidden. (When the
displayable is shown without a tag, this is the same as the shown timebase.)

The render method is called when the displayable is first shown. It can be called again
if renpy.redraw()is called on this object.

event(self, ev, x, y, st)


The event method is called to pass a pygame event to the creator-defined
displayable. If the event method returns a value other than None, that value is
returned as the result of the interaction.
The event method exists on other displayables, allowing the creator-defined
displayable to pass on the event.

ev
An event object
x, y
The x and y coordinates of the event, relative to the upper-left corner of the
displayable. These should be used in preference to position information found in
the pygame event objects.
st
A float, the shown timebase, in seconds.

An event is generated at the start of each interaction, and renpy.timeout()can be


used to cause another event to occur.

per_interact(self)
This method is called at the start of each interaction. It can be used to trigger a
redraw, and probably should be used to trigger a redraw if the object participates in
rollback.

visit(self)
If the displayable has child displayables, this method should be overridden to return a
list of those displayables. This ensures that the per_interact methods of those
displayables are called, and also allows images used by those displayables to be
predicted.

renpy.Render

creator-defined displayables work with renpy.Render objects. Render objects are returned by
calling the renpy.render()function on a displayable. A creator-defined displayable should
create a Render object by calling renpy.Renderfrom its render method.

Since the render object isn't intended to be subclassed, we will omit the implicit self
parameter.

class renpy.Render( width, height)


Creates a new Render object.

width, height
The width and height of the render object, in pixels.

blit(source, pos)
Draws another render object into this render object.

source
The render object to draw.
pos
The location to draw into. This is an (x, y) tuple with the coordinates being pixels
relative to the upper-left corner of the target render.

canvas()
Returns a canvas object. A canvas object has methods corresponding to the
pygame.draw functions, with the first parameter (the surface) omitted.

get_size()
Returns a (width, height) tuple giving the size of this render.

subsurface(rect)
Returns a render consisting of a rectangle cut out of this render.

rect
A (x, y, width, height) tuple.

Utility Functions

These function manage the rendering process.

renpy.displayable(d)
This takes d, which may be a displayable object or a string. If it's a string, it converts that
string into a displayable using the usual rules.

renpy.render(d, width, height, st, at)


Causes a displayable to be rendered, and a renpy.Render object to be returned.

d
The displayable to render.
width, height
The width and height available for the displayable to render into.
st, at
The shown and animation timebases.

Renders returned by this object may be cached, and should not be modified once they
have been retrieved.

renpy.timeout(seconds)
Causes an event to be generated before secondsseconds have elapsed. This ensures that
the event method of a user-defined displayable will be called.

renpy.redraw(d, when)
Causes the displayable dto be redrawn after whenseconds have elapsed.

Other Functions

We're in the process of migrating the documentation over to a new tool. As not every page has
been migrated yet, this exists to document new functionality that has no other place to go.

renpy.call(label, *args, **kwargs)


Causes the current Ren'Py statement to terminate, and a jump to a labelto occur. When
the jump returns, control will be passed to the statement following the current statement.

renpy.clear_game_runtime()
Resets the game runtime counter.

renpy.focus_coordinates()
This attempts to find the coordinates of the currently-focused displayable. If it can, it will
return them as a (x, y, w, h) tuple. If not, it will return a (None, None, None, None) tuple.

renpy.fsdecode(s)
Converts s from filesystem encoding to unicode.

renpy.fsencode(s)
Converts s from unicode to the filesystem encoding.

renpy.get_game_runtime()
Returns the game runtime counter.
The game runtime counter counts the number of seconds that have elapsed while waiting
for user input in the top-level context. (It does not count time spent in the main or game
menus.)
renpy.get_image_load_log(age=None)
A generator that yields a log of image loading activity. For the last 100 image loads, this
returns:

The time the image was loaded (in seconds since the epoch).
The filename of the image that was loaded.
A boolean that is true if the image was preloaded, and false if the game stalled to
load it.
The entries are ordered from newest to oldest.

age
If not None, only images that have been loaded in the past ageseconds are included.

The image load log is only kept if config.developer = True.

renpy.get_physical_size()
Returns the size of the physical window.

renpy.get_renderer_info()
Returns a dictionary, giving information about the renderer Ren'Py is currently using. The
dictionary has one required key:

"renderer"
One of "gl"or "sw", corresponding to the OpenGL and software renderers,
respectively.
"resizable
True if and only if the window is resizable.

Other, renderer-specific, keys may also exist. The dictionary should be treated as
immutable. This should only be called once the display has been started (that is, after the
init code is finished).

renpy.get_say_attributes()
Gets the attributes associated with the current say statement, or None if no attributes are
associated with this statement.
This is only valid when executing or predicting a say statement.

renpy.get_side_image(prefix_tag, image_tag=None, not_showing=True,


layer='master')
This attempts to find an image to show as the side image.
It begins by determining a set of image attributes. If image_tagis given, it gets the image
attributes from the tag. Otherwise, it gets them from the currently showing character.
It then looks up an image with the tag prefix_tagand those attributes, and returns it if it
exists.
If not_showing is True, this only returns a side image if the image the attributes are taken
from is not on the screen.

renpy.image_size(im)
Given an image manipulator, loads it and returns a (width, height) tuple giving its size.
This reads the image in from disk and decompresses it, without using the image cache.
This can be slow.

renpy.list_files(common=False)
Lists the files in the game directory and archive files. Returns a list of files, with / as the
directory separator.

common
If true, files in the common directory are included in the listing.

renpy.notify(message)
Causes Ren'Py to display the messageusing the notify screen. By default, this will cause the
message to be dissolved in, displayed for two seconds, and dissolved out again.
This is useful for actions that otherwise wouldn't produce feedback, like screenshots or
quicksaves.
Only one notification is displayed at a time. If a second notification is displayed, the first
notification is replaced.

renpy.set_physical_size(size)
Attempts to set the size of the physical window to size. This has the side effect of taking the
screen out of windowed mode.

renpy.vibrate(duration)
Causes the device to vibrate for durationseconds. Currently, this is only supported on
Android.

renpy.music.register_channel(name, mixer=None, loop=None, stop_on_mute=True,


tight=False, file_prefix='', file_suffix='', buffer_queue=True)
This registers a new audio channel named name. Audio can then be played on the channel
by supplying the channel name to the play or queue statements.

mixer
The name of the mixer the channel uses. By default, Ren'Py knows about the "music",
"sfx", and "voice" mixers. Using other names is possible, but may require changing the
preferences screens.
loop
If true, sounds on this channel loop by default.
stop_on_mute
If true, music on the channel is stopped when the channel is muted.
tight
If true, sounds will loop even when fadeout is occuring. This should be set to True for a
sound effects or seamless music channel, and False if the music fades out on its own.
file_prefix
A prefix that is prepended to the filenames of the sound files being played on this
channel.
file_suffix
A suffix that is appended to the filenames of the sound files being played on this
channel.
buffer_queue
Should we buffer the first second or so of a queued file? This should be True for audio,
and False for movie playback.

layout.yesno_screen(message, yes=None, no=None)


This causes the a yes/no prompt screen with the given message to be displayed. The
screen will be hidden when the user hits yes or no.

message
The message that will be displayed.
yes
An action that is run when the user chooses yes.
no
An action that is run when the user chooses no.

updater.fsencode(s)
Converts s from unicode to the filesystem encoding.

Building, Updating, and Other Platforms

Building Distributions

Ren'Py includes support for building game distributions. Upon choosing "Build Distributions" in
the launcher, Ren'Py will scan itself and the project to determine the files to include in the
distribution, will create any archives that are necessary, and will build package and update
files.
With no configuration, Ren'Py will build the following four kinds of packages:
All Desktop Platofrms

A zip file targeting Windows x86, Macintosh x86, Linux x86, and Linux x86_64.

Linux x86/x86_64

A tar.bz2 file targeting Linux x86 and Linux x86_64.

Macintosh x86

A zip file containing a Macintosh application targeting Macintosh OS X on Intel


processors. Game data will be included inside the application, which appears to the
user as a single file.

Windows x86

A zip file targeting Windows x86.

Warning
The zip and tar.bz2 files that Ren'Py produces contain permissions information that must be
present for Ren'Py to run on Linux and Macintosh.
Unpacking and re-packing a zip file on Windows and then running it on Linux or Macintosh is not
supported.

Basic Configuration

The build process can be configured by setting variables and calling function that live in the
build namespace. This must be done from inside an init python block.
There are a few basic variables and functions that many games will use.

build.directory_name= "..."
This is used to create the names of directories in the archive files. For example, if this is
set to "mygame-1.0", the Linux version of the project will unpack to "mygame-1.0-linux".
This is also used to determine the name of the directory in which the package files are
placed. For example, if you set build.directory_name to mygame-1.0, the archive files will
be placed in mygame-1.0-dists in the directory above the base directory.

build.executable_name= "..."
This variable controls the name of the executables that the user clicks on to start the
game.
For example, if this is set to "mygame", the user will be able to run mygame.exe on
Windows, mygame.app on Macintosh, and mygame.sh on Linux.

Special Files

There are two files that can be included in your game's base directory to customize the build.

icon.ico
The icon that is used on Windows.
icon.icns
The icon that is used on Macintosh.

These icon files much be in specific formats. You'll need to use a program or web service (such
as http://iconverticons.com/ ) to convert them.

Classifying and Ignoring Files

The build process works by first classifying files in the Ren'Py distribution and your game into
file lists. These file lists are then added to package files.
The classification is done by the build.classify function. It takes a patterns and a space-
separated list of filenames. Patterns are matched from first to last, with the first match taking
precedence (even if a more-specific pattern follows.) Patterns are matched with and without a
leading /. Patterns may include the following special characters:

/
The directory separator.
*
Matches all characters except for the directory separator.
**
Matches all characters.

For example:
**.txt
Matches all txt files.
game/*.txt
Matches txt files in the game directory.

There are five file lists that files can be classified into by default. (Ren'Py places its own files
into the first four of these.)

all
These files will be included in all packages.
linux
These files will be included in packages targeting Linux.
mac
These files will be included in packages targeting Macintosh.
windows
These files will be included in packages targeting Windows.
archive
These files will be included in the archive.rpa archive.

Files that are not otherwise classified are placed in the "all" file list.
To exclude files from distribution, classify them as None or the empty string.
For example:

# Include README.txt
build.classify("README.txt", "all")

# But exclude all other txt files.


build.classify("**.txt", None)

# Add png and jpg files in the game directory into an archive.
build.classify("game/**.png", "archive")
build.classify("game/**.jpg", "archive")

Documentation

Calling the build.documentation function with patterns marks files matching those patterns as
documentation. Documentation files are included twice in a Macintosh application - both
inside and outside of the application itself.
For example, to mark all txt and html files in the base directory as documentation, call:

build.documentation("*.txt")
build.documentation("*.html")

Packages

It's also possible to add new types of packages to the Ren'Py build process. This is done by
calling the build.package function with a package name, type, and a string containing the file
lists to include.
Say we wanted to build a normal version of our game, and one containing bonus material. We
could classify the bonus files in to a "bonus" file list, and then declare an all-premium package

with:
with:

build.package("all-premium", "zip", "windows mac linux all bonus")

Archives

Ren'Py supports combining files into a simple archive format. While not very secure, this
protects files from casual copying.
By default, all files classified into the "archive" file list will be placed in an archive.rpa archive,
which is included in the all file list.
By calling build.archive, it's possible to declare a new archives and the file lists they will be
included in. (It's rare to use anything but the all file list, however.) To use an archive, classify
files into a list with its name.
For example, the following code will archive images in images.rpa, and game scripts into
scripts.rpa:

# Declare two archives.


build.archive("scripts", "all")
build.archive("images", "all")

# Put script files into the scripts archive.


renpy.classify("game/**.rpy", "scripts")
renpy.classify("game/**.rpyc", "scripts")

# Put images into the images archive.


renpy.classify("game/**.jpg", "images")
renpy.classify("game/**.png", "images")

If an archive file is empty, it will not be built.

Please think twice about archiving your game. Keeping files open will help others run your
game on future platforms - platforms that may not exist until after you're gone.

Build Functions

build.archive(name, file_list='all')
Declares the existence of an archive. If one or more files are classified with name, name.rpa
is build as an archive. The archive is included in the named file lists.

build.classify(pattern, file_list)
Classifies files that match patterninto file_list.

build.clear()
Clears the list of patterns used to classify files.

build.documentation(pattern)
Declares a pattern that matches documentation. In a mac app build, files matching the
documentation pattern are stored twice - once inside the app package, and again outside
of it.
build.executable(pattern)
Adds a pattern marking files as executable on platforms that support it. (Linux and
Macintosh)

build.package(name, format, file_lists, description=None, update=True, dlc=False)


Declares a package that can be built by the packaging tool.

name
The name of the package.
format
The format of the package. A string containing a space separated list of:

zip
A zip file.
app-zip
A zip file containing a macintosh application.
tar.bz2
A tar.bz2 file.

The empty string will not build any package formats (this makes dlc possible).
file_lists
A list containing the file lists that will be contained within the package.
description
An optional description of the package to be built.
update
If true and updates are being built, an update will be built for this package.
dlc
If true, any zip or tar.bz2 file will be built in standalone DLC mode, without an update
directory.

Web Updater

Ren'Py includes an updater that can automatically download and install updates to a Ren'Py
game hosted at a website. This can be useful in keeping a large game up to date.
The Ren'Py updater works by automatically performing the following steps:

1. Downloading an index file that controls what is updated.


2. Asking the user if he or she wants to proceed with the update.
3. Producing an archive file from the files on disk.
4. Downloading a zsync control file from the server.
5. Using the zsync tool to update the archive file to the version on the server. Zsync
automatically computes the differences between the two files, and attempts to only
download the portions that have changed.
6. Unpacking the archive, replacing the files on disk.
7. Deleting files that have been removed between the old and new versions.
8. Restarting the game.

The Ren'Py updater shows an updater screen during this process, prompting the user to
proceed and allowing the user to cancel when appropriate.

Server Requirements

The updater requires that you provide your own hosting. You should be able to download the
update files by going to the appropriate URL directly, and your server must support HTTP
range queries.
(This means paying for web hosting, as "sharing" sites tend not to support the required
features.)

Building an Update

Updates are built automatically when distributions are built. To build an update, set
build.include_updates to True in options.rpy. This will unlock the "Build Updates" option in
options.rpy. Check this option, and Ren'Py will create the update files.
The update files consist of:

updates.json
An index of available updates and their versions.
package.sums
Contains checksums for each block in the package.
package.update.gz
Contains the update data for the given package.
package.update.json
Contains a list of the files in each package, which the updater uses when downloading
DLC.
package.zsync
This is a control file that's used by zsync to manage the download.

You must upload all these files to a single directory on your web server.

Functions

To cause an update to occur, invoke either updater.update or the updater.Update action.

updater.Update(*args, **kwargs)
An action that calls updater.update(). All arguments are stored and passed to that
function.

updater.can_update(base=None)
Returns true if it's possible that an update can succeed. Returns false if updating is totally
impossible. (For example, if the update directory was deleted.)

updater.get_installed_packages(base=None)
Returns a list of installed DLC package names.

base
The base directory to update. Defaults to the current project's base directory.
updater.update(url, base=None, force=False, public_key=None, simulate=None, add=[],
restart=True)
Updates this Ren'Py game to the latest version.

url
The URL to the updates.json file.
base
The base directory that will be updated. Defaults to the base of the current game.
(This can usually be ignored.)
force
Force the update to occur even if the version numbers are the same. (Used for
testing.)
public_key
The path to a PEM file containing a public key that the update signature is checked
against. (This can usually be ignored.)
simulate
This is used to test update guis without actually performing an update. This can be:

None to perform an update.


"available" to test the case where an update is available.
"not_available" to test the case where no update is available.
"error" to test an update error.
add
A list of packages to add during this update. This is only necessary for dlc.
restart
Restart the game after the update.

Screen

To customize the look of the updater, you may override the updaterscreen. The default
screen is defined in common/00updater.rpy.

Android

Ren'Py support devices running the Android operating system, such as smartphones and
tablets. While these devices do not support 100% of Ren'Py's functionality, with minimal
modification code can be packaged and ported to these devices.
RAPT - the Ren'Py Android Packaging Tool - is a program, downloaded separately from Ren'Py,
that creates an Android package for testing or release purposes.

User Instructions

When a Ren'Py game has been launched on Android, the following keybindings work:

Home
Returns to the Android home screen, suspending the Ren'Py game. As part of the suspend
process, Ren'Py will automatically save the game. If necessary, the save will be
automatically loaded when the user returns to the game.
Menu
Brings up the in-game menu, and returns to the game.
Back
Rolls back.
Volume Up, Volume Down
Controls Android's media volume.

Platform Differences

There are many important differences between the touch-based Android platform and the
mouse-based platforms that Ren'Py supports. Changes due to the Android software and
hardware are:

The touchscreen is treated as if it was a mouse. However, it will only produce mouse
events when the user is actively touching the screen. When the user is not touching the
screen, the virtual pointer will move to the upper-left corner of the screen.
ImageDissolve(), AlphaDissolve(), and AlphaBlend()are not supported.
Functions that render to a texture can only render an opaque texture. This means that
the Dissolve()and Pixellate()transitions will only produce opaque output.
The focus_maskproperty is not supported. It will be treated as if all pixels in the mask are
opaque.
Movie playback is not supported.
Launching the web browser is not supported.
Some python modules (including network communication) modules are not supported.
Ren'Py cannot change the device volume. However, the android volume buttons work
normally.

In addition, there are a few changes that may be necessary due to human factors:

Since Android smartphones can be smaller than a computer monitor, it may be


necessary to increase text size.
Since touch input is less accurate than mouse input, touch-based buttons need to be
larger than mouse-based ones.

To help you adapt to these differences, Ren'Py for Android automatically selects a screen
variant of touch. It also selects screen variants of phoneor tabletbased on the device's screen
size. See Screen Variants for more information.

Building Android Applications

RAPT contains tools that help you take a packaging-centric approach to Android game
development. In this approach, you will use a PC to build an Android package and upload it to
your device. You can then run the game like any Android application. When it works correctly,
you can upload the package you make to the Android Market or other app stores.
Building your first package takes four steps:

1. Download and install RAPT, Python 2.7, the Java Development Kit, and Android USB
Drivers (scroll down for links).
2. Use the android.py installsdkcommand to install the Android SDK and set up your
development environment.
3. Use the android.py configurecommand to configure Android-specific settings in your
game.
4. Use the android.py buildcommand to build a package, and to install the package on
your device.

Once you've finished these four steps, you'll have a runnable Android package. You'll only
need to run step 3 when you decide to make changes to your game's configuration or when
configuring a new game entirely; you'll run step 4 most often, whenever you need to make a
new build of your game.

Host Platform Support

We've tested RAPT on Linux and Windows computers. While it should work on Mac OS X, we
haven't tested it there, so there may be problems encountered. The examples we give will be
for Linux and Windows.
The RAPT tools are command-line based. We will try to assist you with examples to familiarize
you with the command line on Windows.

Step 1: Installing RAPT and its Dependencies

There are four things you may need to manually download and install before you can run
RAPT:
Java Development Kit. The Java Development Kit (JDK) contains several tools that are used
by RAPT, including the tools used to generate keys and sign packages. It can be downloaded
from:

http://www.oracle.com/technetwork/java/javase/downloads/index.html

Please note that the developer-focused JDK is different from the user-focused JRE, and you'll
need the JDK to create Android packages.
Python 2.7. Python 2.7 is required to run the android.py script that's included with RAPT. It
can be downloaded from:

http://python.org/download/releases/2.7.2/

RAPT is not compatible with Python 3 at this time.


Android Device Drivers. On Windows, you may want to install a device driver to access your
device, although this is not necessary. Links to android device drivers can be found at:

http://developer.android.com/sdk/oem-usb.html

On Linux or OS X, you won't need a device driver. If you can't access your device, you may
need to read:

http://developer.android.com/guide/developing/device.html#setting-up

However, modern versions of Linux and OS X should just work.


RAPT Itself. The latest version of RAPT can be downloaded from:

http://www.renpy.org/dl/android/

Once RAPT has been downloaded, you should extract it using an archive program. The
directory contained in that archive is what we will refer to as the RAPT directory.

Aside: Running android.py

In this documentation, we'll ask you to run the android.pycommand. The technique we use to
run this varies based on the system you're on.

In all cases, you should run android.pyfrom within the RAPT directory. (That is, the directory
containing android.pyitself.)
On Windows, to do this, you will need to open up the command line by pressing and holding
down the Windows key and 'R'. In the small window that pops up write "cmd" and press Enter.
This should bring up the command line.
To run the command from within the RAPT directory you need to navigate to it from the
command line. Find out where you extracted RAPT and copy the path from Explorer (just click
in the address bar so the path turns blue and press Ctrl+c). In the command prompt, write cd
then a space, a double-quote, paste the path you just copied from Explorer (right click and
choose paste), then another double-quote.
Let's assume you extracted RAPT to C:\tools\RAPT. In the command line write:

cd "C:\tools\RAPT"

Now you're within the RAPT directory.


On Windows, if the .py extension is registered to Python 2.7, you then can just run:

android.py test

If you don't know what the above means or you don't want to do it, you will have to add the full
path to Python to each command in the following steps of this guide beginning with
'android.py'. If you installed Python to the default location, the above command would
become:

C:\python27\python.exe android.py test

If you installed Python to a different location, then find your Python install in Explorer, click in
the address bar and copy the path, then replace C:\python27with the path you copied instead
- leaving \python.exeon the

end. So if your Python install is in C:\tools\python, you would type:

C:\tools\python\python.exe android.py test

Warning
If the path to Python that you copied has any spaces in - for example, if you had installed it in the
Program Filesdirectory - you will need to put double quotes at the beginning of the whole
command and just after python.exe:

"C:\Program Files\Python\python.exe" android.py test

On Linux, you may need to prefix the command with the current directory:

./android.py test

For the rest of this documentation, we'll just use android.py- if you had to include the path to
Python in the example above, you will need to do the same thing every time you see
android.pyin these instructions.

Step 2: Set up the Android SDK and Development Environment

The next step is to set up the Android SDK and the rest of your development environment. This
step will:

Check that the JDK is installed properly.


Install Apache Ant.
Install the Android SDK.
Use the Android SDK to install the appropriate development packages.
Create a signing key that will be used to sign packages that are placed on the market
(android.keystore: this will be generated in the RAPT directory).

This step requires Internet access.


To perform this step, run:

android.py installsdk

RAPT will report on what it's doing. It will also prompt you with warnings about licenses, and
ask if you want it to generate a key.

Warning
The key generated by RAPT is created with a standard passphrase. You should really use keytool to
generate your own signing keys.

http://docs.oracle.com/javase/1.3/docs/tooldocs/win32/keytool.html

At the very least, you should keep the android.keyring file in a safe place. You should also back it
up, because without the key, you won't be able to upload the generated applications.

In the examples below, mygameis short for the path to the game you're working on, relative to
the current directory. When you make your own game, you should change mygameto
something else. The easiest way to do this, of course, is to make a copy of your game's
directory inside the RAPT directory and then replace mygamein the examples below with the
name of your game's directory.

Step 3: Configure Your Game

Before building a package, you must give RAPT some information about your game. You can
do this with the following command:

android.py configure mygame

This will ask you a series of questions about your game, and store that information in a file in
the game directory.
If you need to change the information - for example, if you release a new version of your game
- you can re-run the configure command. Your previous choices will be remembered.

Step 4: Build and Install the Package

Finally, you can build and install the package. This is done with a command like:

android.py build mygame release install

This command will build a releasable version of your game, and then install it on the
connected device. Please look at the output of this command to make sure it succeeds.
Once the game successfully installs, you can touch its icon in your device's launcher to start it
running.

If you'd rather just copy the game's apk file to your Android device manually, you can just run:

android.py build mygame release


Then navigate to the 'bin' directory inside RAPT and copy the file mygame-release.apk into
your Android Device. You will then need to find the .apk file in your Android device using your
file application and open it to install the
game.
The build command passes the options after the game name to the ant tool, which is
responsible for creating the Android package. Other commands are also possible - for a list,
run:

android.py build mygame help

Viewing Debug Output

To view debug output from your application, run the logcat command:

android.py logcat

This command runs the adb logcatcommand in a mode that selects only Python output.

Troubleshooting and Support

Here's a list of errors that you might encounter and possible solutions:
When trying to run:

android.py test

After having associated .py files with Python 2.7, if you get:

Traceback (most recent call last):


File "C:\Visual Novels and Games\rapt-6.13.11.0\android.py", line 9, in <module>
import subprocess
File "C:\Python27\lib\subprocess.py", line 444, in <module>
from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP
ImportError: cannot import name CREATE_NEW_PROCESS_GROUP

This may be related to having more than one version of Python installed on your system. Try
running android.py with the full path to Python, e.g.:

C:\python27\python.exe android.py test

(If this works, then you will need to include the full path to Python in every command, as if you
didn't have the file type associated.)
If while downloading Apache Ant you get:

IOError: [Errno socket error] [Errno 10054] An existing connection was forcibly
closed by the remote host

Just try installing the sdk again with the same command.
If while configuring your game you get something like:

Tag <manifest> attribute package has invalid character '-'.


You may have inserted an invalid character in the package name you used during
configuration (in this case a hyphen '-'). You'll have to use a different package name which
does not contain anything other than letters and dots.
If while configuring you get something like:

Traceback (most recent call last):


File "android.py", line 66, in <module>
main()
File "android.py", line 44, in main
configure.configure(iface, directory)
File "buildlib\configure.py", line 108, in configure
config.save(directory)
File "buildlib\configure.py", line 30, in save
with file(os.path.join(directory, ".android.json"), "w") as f:
IOError: [Errno 2] No such file or directory: 'mygame\\.android.json'

You should check whether you specified the correct path to your game directory. The easiest
way to be sure is to put your game's directory inside the RAPT directory, and simply supply the
name of your game's directory. (If your game's directory name has spaces, you may need to
surround it with double quotes.)
If building your game gives you an error like:

Error: Target id android-8 is not valid. Use 'android list targets' to get the target ids

You might want to check whether you have Android 2.2 (API 8) in the Android SDK manager.
You can run it by navigating to the android-sdk/tools directory inside the RAPT directory and
run android.bat.
If Android 2.2 (API 8) is missing like in the above image, click 'Updates' and then 'Install
Updates'.
Once the updates are installed, make sure Android 2.2 (API 8) and SDK platform are ticked:
And install the packages. Then, try building your game again.
If you still have questions or doubts you can try searching through or posting on the RAPT
thread over at the Lemmasoft forums:

http://lemmasoft.renai.us/forums/viewtopic.php?f=32&t=13987&hilit=rapt

End-User Documentation

Dealing With Display Problems


As of version 6.13, Ren'Py will take advantage of graphics acceleration hardware, if it's present
and functional. Using hardware acceleration brings with it several advantages, such as
allowing vertical-blank synchronization and scaling games to full-screen size while preserving
aspect ratio.
By default, Ren'Py selects a renderer to use in the following order:

1. OpenGL 2.0 or greater.


2. DirectX 9, provided that all libraries are available.
3. OpenGL 1.x.
4. Software.
A small fraction of systems may experience problems when running hardware accelerated
Ren'Py games. These problems are often due to buggy graphics drivers, and so your first step
to fixing them should be to check for an update to your graphics card drivers.
If upgrading your video drivers does not fix the problem, you should consider switching video
renderers, using the following steps.

1. Hold down shift while starting Ren'Py, or press shift+G once Ren'Py has started.
2. From the "Graphics Acceleration" menu that appears, choose the renderer to use.
3. Choose "Quit", then restart Ren'Py.

We suggest trying OpenGL, DirectX, and Software, in that order.

Engine Developer Documentation

Text Editor Integration

Ren'Py uses a text editor to allow the user to edit game scripts from the launcher, and to report
errors to the user. By default, Ren'Py uses jEdit as the text editor when launched from the
launcher and the system default editor otherwise. This can be customized by the user as
necessary.
The editor is customized by creating an Editor class in a .edit.py file. This class contains
methods that are called to manage text editing.
When run directly, Ren'Py first looks at the RENPY_EDIT_PY environment variable to find an
.edit.py file to use. If it can find one, it uses the Editor class defined in that file. If not, it uses a
built-in editor class that launches the editor in a system-specific manner.
When the Ren'Py Launcher is run, it scans subdirectories of the projects directory and Ren'Py
directory to find files of the form name.edit.py. (For example, it would find launcher/jEdit.edit.py
and myeditor/MyEditor.edit.py.) The latest editor with a given nameis presented to the creator
as part of the launcher options. The launcher also sets RENPY_EDIT_PY to the selected file, so
that games launched from the launcher will use the selected editor.

Writing an .edit.py File

An edit.py file is a Python (not Ren'Py) file that must define a single class, named Editor. Ren'Py
will call methods on this class to cause editing to occur.
Use of the editor is done as part of an editor transaction, which groups related operations
together. For example, if an editor transaction asks for a new window, all of the files in that
transaction should be opened in the same new window. An editor transaction starts with a call
to the begin method, may contain one or more calls to operation methods, and ends with a
call to the end method.
The edit.py file should import renpy.editor, and the Editor class should inherit from
renpy.editor.Editor. As additional keyword arguments may be added to methods, each method
you define should ignore unknown keyword arguments. Since you're expected to define your
own Editor subclass, we present the methods with the selfparameter.

class Editor

begin(self, new_window=False, **kwargs)


Starts an editor transaction.
If new_windowis true, the editor should attempt to open a new window. Otherwise, it
should attempt to perform the transaction in an existing editor window.

end(self, **kwargs)
Ends a transaction.

open(self, filename, line=None, **kwargs)


Opens a filenamein the editor.
If lineis not None, attempts to position the editing cursor at line.

Changes and License

Full Changelog

Ren'Py 6.14

Ren'Py Launcher Rewrite

The Ren'Py launcher has been rewritten. Some of the improvements are:

A new visual design by Doomfest of the Dischan visual novel team.


The launcher now includes direct access to open the script and game directories, and
common script files.
The launcher includes Script Navigation support. Clicking the name of a label, define,
transform, screen, or callable will open the editor to the location where that name is
defined.
Script navigation also provides access to individual script files.
The launcher now supports one-click project building. Instead of using multiple steps to
build a project, a single click will now cause the launcher to:
Read the build process configuration from the game script.
Build the archives needed.
Generate the archive and update files.
The launcher can now use the Ren'Py updater to update Ren'Py, and to download editors.

Editra & Text Editing

For most users, Ren'Py recommends the use of the Editra editor. We have developed an Editra
plugin that communicates with the Ren'Py launcher and supports the editing of Ren'Py script.
While still in beta, Editra is a fast and light editor with good code editing support. Editra also
includes a spell-checker that can be enabled, and applies to dialogue and other strings.
If Editra is selected by the user, and it is not installed, Ren'Py will automatically download it.
The jEdit editor remains supported, and is preferred for use with languages (like Chinese,
Japanese, and Korean) that Editra doesn't support fully. If selected, Ren'Py will download jEdit
automatically.
Ren'Py also supports editing files through system-specific file associations. (This support will
not send the cursor to the correct line, however.)
Ren'Py Web Updater

Ren'Py includes an updater that can update Ren'Py and individual Ren'Py games by
downloading changes from a properly-configured web server with a small number of update
files uploaded to it.
The updater uses zsync to download the minimal set of changes between the local files on disk
and the files stored on the server. A single set of files on the server supports updating from all
prior versions of a project.
Ren'Py includes a default updater interface that can be further configured by interested users.

Transform Changes

This release changes the behavior of transforms to make them more correct and easier to
use.
The xzoom and yzoom properties are now applied before, rotation. This means that the shape
of the image will remain consistent as the image is rotated. Previously, the image to change
shape as it was rotated.
The xzoom and yzoom properties may now be negative, with negative zoom values causing
the images to be flipped. The positioning code now takes this into account, and positions a
flipped image properly.
Thanks to Edwin for contributing these changes.

Screen Language, Displayable, and Transition Enhancements

The Textbutton and Label screen language statements now take properties prefixed with
text_. These properties have the text_ prefix stripped, and are then passed to the
internal text displayable.
The Viewport screen language statement now takes a scrollbarsparameter. If given,
scrollbars that manipulate the viewport are created.
The Viewport screen language statement now takes xinitialand yinitialparameters.
If given, these control the initial positioning of the viewport.
A screen language block may now contain multiple has statements. Screen language
widgets that take single children can now take a has statement.
The input displayable now supports the use of the left and right arrow keys within the
text. (Thanks to Edwin for this feature.)
MoveTransition()has been rewritten. The new version now uses transforms to control
the positioning of entering and leaving images, and can interpolate between the
locations of moving images.

Rollback Improvements

The new renpy.fix_rollback()function allows the game to fix choices, even if they are
made in rollback mode. The user can roll back and roll forward, but is restricted to
making the choices he made the first time through the game.
Thanks to Edwin for contributing fix_rollback.
Rolling forward now works through a jump out of a call screenstatement.

Video Improvements

Ren'Py's video playback support has been partially rewritten to improve robustness, speed,
and framerate stability. These improvements should reduce the number of frame drops
Ren'Py performs, and should also prevent Ren'Py from locking up if too many frames are
dropped.
Ren'Py now supports the WebM video format.

Image Load Log

When config.developeris true, Ren'Py keeps an internal log of image loads.


This log can be access by showing the _image_load_log screen. This screen displays the name
of an image file for a few seconds after that image has been loaded. The name is in white if
the image was loaded by the image predictor, and pink if Ren'Py was unable to predict the
image.

File Actions and Functions

Two screen functions have been added, and two screen actions have been changed:

The new FileUsedSlots()function returns a list of used file slots on the current page.
The new FileCurrentPage()function returns the name of the current page.
The FileSave()and FileAction()actions have been modified so that if the slot name is
None, an unused slot based on the current time is used.

Taken together, these changes make it possible to create a list of save slots where the user is
able to add new slots to the list.

Multiple Store Support

Ren'Py now supports multiple stores - multiple namespaces in which python code can be run.
Variables in these stores are saved, loaded, and rolled-back in the same way that variables in
the default store are.
Stores are accessed by supplying an in-clause to a python block. For example:

init python in stats:

def reset():
"""
Code to reset the statistics.
"""

User-created stores are placed into the "store" package, with the default store being the
package itself. Names can be imported between packages.

init python:
from store.stats import reset

init python in stats:


from store import ToggleField

Note that stores do not affect the order in which init python blocks are run. A name must be
defined in a block before the one that imports that name.

Platform Support and Library Updates

Linux support has been changed.

The Linux platform supports the x86_64 CPU architecture in addition to the x86
architecture. The Ren'Py shell script will automatically determine the platform it is
running on when it is launched.
The Linux version is now linked agains the libraries from the 2009-era Ubuntu 10.04
Lucid. (Previously, Ren'Py had been linked against 2006's Dapper.) Older versions of
Lucid. (Previously, Ren'Py had been linked against 2006's Dapper.) Older versions of
Linux are no longer supported.

Many libraries that Ren'Py depends on have been updated. Some of the changes that have
occured are:

Python has been updated to version 2.7.3.


Pygame has been updated to version 1.9.1.
GLEW has been updated to version 1.7.0. This may fix OpenGL problems on some Linux
systems.
LibAV has been updated to version 0.7.6, and has been compiled with CPU detection
enabled.

Other Changes

The renpy.call()function allows - with major and important caveats - a call to a Ren'Py
label to begin from inside python code. Such a call immediately terminates the current
statement.
When an action is expected, nested lists of actions can be given. The lists are flattened
and the action executed.
Added the OpenURL()action, which opens a URL in a web browser.
Added the config.gl_resizevariable, which determines if the user can resize OpenGL
windows.
Ren'Py's handling of command line argments has been rewritten. Most notably, lint is
now invoked with the

renpy.sh <gamename> lint

command. (Which also works with renpy.exe.)


Ren'Py can now dump information about the game to a json file when starting up. The
information dumped can assist other tools in providing launcher-like code navigation.
The little-used remote control feature has been removed from Ren'Py.
The config.gl_resizevariable now controls resizing of a game running in GL mode.
Documentation fixes (by SleepKirby and others).
The NVL-Mode tutorial has been ported to Sphinx (by Apricotorange).
Ren'Py now defaults to reporting errors with sound and music files when
config.developer is True.

Ren'Py 6.13.9

The new RAPT tool makes it far easier to package a Ren'Py game for Android. It can semi-
automatically set up an Android build environment on your system, build a package, and
install that package on your Android device.
To fix some editor-related problems, backported the 6.14 editor system. This changes how
editors are configured. Please see Text Editor Integration for a description of the new system.
The new config.save_dumpvariable causes Ren'Py to write out save_dump.txt each time it
saves. This file describes the contents of the save, making it possible to figure out what's
causing an overly large save file.
Worked around a bug in Mesa that can cause crashes on certain Linux systems.
Fixed the following bugs in Ren'Py.
The (default) texwrap layout represents character widths as floating-point numbers. This
fixes a bug where non-integer kerning would lead to text overflowing its bounding box.
Menu choices are logged correctly.
All file access is now done in unicode, rather than the system's native encoding. This
prevents crashes that occured when Ren'Py was placed in a directory that had non-ASCII
characters in it.
Fixed focus_mask on the ANGLE renderer.
Displayables can now have fractional-pixel sizes. This allows a zooming image to remain
precisely centered on the screen.
Fixed a problem where Ren'Py would save unnecessary trees of displayables each time it
saved a screen. This would lead to overly large save files and slow save performance.
Ren'Py would not attempt an alternate rendering method if the texture test failed,
leading a "Textures are not rendering properly." exception.
A crash in Render.fill.

Ren'Py 6.13.8

Side images can now be limited to showing a single character, or only showing characters that
are not on the screen. See config.side_image_tagand config.side_image_only_not_showing.
Added config.python_callbacks, a list of python functions that are called at the end of each
python block.
Ren'Py now tests the video card it is running on for functionality. If it can't draw textured
rectangles to the screen, it will proceed to a different renderer.
Old-style string interpolation is now enabled by default, alongside new-style string
interpolation.
Ren'Py is now compatible with libpng 1.5. Thanks to James Broadhead for the patch.
Fixed the following bugs:

A crash when dealing with certain invalid fonts.


Pausing too long when typing out text.
Cutting one pixel off a block of text when fractional kerning was used.
Crashing when the time was set in the far future or past.
Immediately exiting when rolling forward at the quit prompt.
Crashing when a non-existing directory is added to the search path. (This prevented
Katawa Shoujo from starting in the latest version.)
Save-file size was overly large due to screens being included in save files.

Ren'Py 6.13

Text Rewrite

Text display has been rewritten from scratch. In addition to supporting many new features, the
new implementation of Text is much faster at text layout and display, and contains much
cleaner code.
Some of the new features that are now supported by the text display system are:

Interpolation of variables enclosed in square brackets. It's now possible to write code
like:

"You scored [score] out of a possible [max_score] points."

The new string interpolation takes place on all text that is displayed, rather than just say
and menu statements. When used as part of a screen, interpolation has access to
screen-local variables.
PEP 3101-style string formatting is supported, which means that this syntax can be used
to display fields and items, as well as variables.
Kerning support was added, both as the kerningstyle property and the ktext tag.
Support for ruby text (also known as furigana), via the rtand rbtext tags, and the
ruby_stylestyle property.
The new spaceand vspacetext tags make it easy to whitespace into the text.
The new cpstext tag controls the speed of text display.
By default, Ren'Py uses the unicode linebreaking algorithm to find points at which a line
can be broken. This algorithm should correctly break lines that contain a mix of western
and eastern languages. Since that algorithm is incorrect on some Korean texts, Ren'Py
also implements a korean-with-spaces variant, that only breaks runs of Korean text at
whitespace. These algorithms can be selected by the languagestyle property.
Ren'Py now uses the Knuth-Plass linebreaking algorithm to choose the points at which it
actually splits lines. This algorithm attempts to minimize the unevenness of all lines
except the last. Ren'Py also supports a nobreak mode, which allows one to create a Text
larger than the screen without it being automatically wrapped. These can be selected
using the layoutstyle property.
The new newline_indentstyle property determines if Ren'Py adds indentation after a
newline in text.
The new line_leadingstyle property inserts space above a line of text. (Ruby text can be
placed into this space.)
Text can be automatically translated before it is displayed. (This support will be improved
in a future major release.)

DirectX Support

On Windows systems that have the February 2010 DirectX update installed, Ren'Py will use
DirectX via the ANGLE adaptation layer, if OpenGL 2.0 or later is not found. The ANGLE layer is
used by popular web browsers such as Firefox and Google Chrome. This allows hardware
rendering to be used on netbooks, where drivers often support DirectX far better than OpenGL.
At startup, Ren'Py will test the graphics capabilities of the computer it is running on. If the
software render is being used, or the game renders at an unacceptably slow speed, Ren'Py will
display a warning message to the user. The warning message includes a link to a page on
renpy.org that explains how to update the graphics drivers.
This version of Ren'Py will only use the software renderer if both DirectX and OpenGL are
incapable of rendering Ren'Py games. Screen-scaling in the software renderer has been
replaced by a simpler but slower version.

Other Changes

Ren'Py now includes a style preference system. This system allows styles to be changed
after the init phase has finished. These changes are saved with the persistent data.
Among other things, style preferences allow a game to offer the user the option to
change the font, size, and color of dialogue text.
Support has been added for screen-based image galleries and music rooms. This
support consists of a classes that provides actions that make it easy to present the user
with graphics and music. The creator is responsible for creating screens that use the
supplied actions.
The default screens.rpy file, used when a new game is created, contains support for a
"quick menu". This menu adds buttons to screens that allow the user to quick save, quick

load, save, toggle skipping, toggle auto-forward mode, and access the preferences
load, save, toggle skipping, toggle auto-forward mode, and access the preferences
menu.
Ren'Py includes 5 new themes, and a number of new color schemes.
Several new actions have been added. The SelectedIf()action allows the creator to
control if a button is displayed in the selected state. The SetMixer()action allows a
mixer to be set to a specific value. The Rollback()and RollForward()actions allow the
creator to bind rollback to buttons.
The behavior of the xfill and yfill style properties was accidentally changed in the 6.12
series. It has been returned to the historical behavior.
The Dissolve()and ImageDissolve()transitions now take a time_warp parameter.
The Frame()displayable now allows the user to specify the left, top, right, and bottom
borders independently.
The caretstyle property allows the user to customize the caret of an input widget.
The renpy.displayable()function has been exposed to the user.
Timers can now take a list of actions, rather than just a single callable.
Three transforms were added to the default library: top, topleft, and topright.
Ren'Py can now load files (including images, music, and fonts) from an Android package.
User-defined statements can now take a block, which the statement is responsible for
parsing.
Wrote documentation for:
Menus
Transforms
Creator-Defined Displayables
Several indexes were added to the documentation, and the style was updated.
Ren'Py now uses the libjpeg-turbo library, for faster jpeg loading. Ren'Py now uses libav
0.7.1, for improved compatibility with movie formats.
Removed support for the iLiad platform.
PowerPC support has been removed from the main Ren'Py distribution. It's available as a
download from the Ren'Py web site.

Thanks to Aleema for contributing the new themes and color schemes.

Ren'Py 6.12.2

This release contains the following changes:

ATL Transforms with parameters compile correctly.


MultipleTransition works in conjunction with pauses.
The mouse is shown when a quit action is run while a movie is playing.
A fix for a lockup that occured when the user entered the game menu while a transition
was running.
RENPY_SCALE_FAST works again.
Ren'Py compiles with newer versions of ffmpeg.
Skipping ends when the game restarts.
Fixed a problem with texture upload that made games noticeably slower.
Choose a better default size for windows on small monitors, like netbooks.
xfill and yfill now work for vbox and hbox, respectively.
Click-to-continue fixes.
Side image fixes.
Documentation fixes.
Thanks to David Gowers and zhangning for contributing patches to this release.

Ren'Py 6.12.1

Image Attributes

The process of showing images is now attribute-based. Image names now consist of a tag, and
zero or more attributes. When showing an image, the order of attributes is no longer important
- it's now possible to define an image using one set of attributes, and show it using those
attributes in a different order.

Attributes are also "sticky". This means that we attempt to preserve as many attributes as
possible when showing a new image.
For example, say we had the following images:

image eileen beach happy = "eileen_beach_happy.png"


image eileen beach woozy = "eileen_beach_woozy.png"

We can now show the first image using the command:

show eileen happy beach

Since the order of attributes no longer matters, this will show the "eileen beach happy" image.
If we follow this with the show statement:

show eileen woozy

the image "eileen beach woozy" will be shown. (Assuming no other images exist. If the image
"eileen happy woozy" existed, an ambiguity error would occur.)
When an image tag is shown without any attributes, then the current attributes are retained.
Now, one can write:

show eileen at right

to display Eileen on the right side of the screen, without changing the attributes supplied to an
image.
Say Attributes. Image attributes can be updated as part of a say statement. A character can
be given an imageargument, giving the name of an image that character is linked to. As part
of the say statement, image attributes can be given before the dialogue string. These
attributes are given to the linked image.
For example, if we define a character using the code:

define e = Character('Eileen', image="eileen")

the code:

e woozy "I think I'm getting too much sun."

is equivalent to:

show eileen woozy


e "I think I'm getting too much sun."
whenever an image with the tag eileen is being shown.
Side Image. This release features a new implementation of Side Images, which allows side
images to be defined like other images, and allows side images to be integrated with screens
easily.
Sticky Transforms. Finally, showing an image without providing a transform or ATL block will
now continue the previous transform that an image with that tag was using. Previously, it
caused those transforms to stop.

Error Handling

Ren'Py now has a new exception handing framework. Instead of always crashing when an error
occurs, Ren'Py will now display the error message on the screen, and give the user the
following choices, as appropriate to the situation:

Rollback
Reload
Ignore
Open Traceback
Quit

When an editor is defined, Ren'Py will allow the user to click on a filename and line number to
open that line in the editor.
The framework is used to handle exceptions and parse errors.

Other

When in OpenGL mode, Ren'Py now remembers the window size between sessions. (This can
be disabled using config.save_physical_size, and it may make sense to do so if your game is
using the pre-screen preferences system.) Choosing the "Window" display preference now
resizes the window to 100% of normal size.
Added the xcenterand ycenterposition and transform properties. These set the position of
the center of a displayable.

The renpy.vibrate()function allows Ren'Py to ask Android devices to vibrate.


The hyperlink style, callback, and focus functions have now been moved to the
hyperlink_functionsstyle property. This allows the functions to be changed on a per-style
basis.
Indentation errors are now reported on the indented line, and not the line preceding the
erroneous indentation.
Added the SetScreenVariable()and ToggleScreenVariable()actions. These allow screen-
local variables to be changed.
Ren'Py now attempts to elide personal information from filenames. Where possible, filenames
are reported relative to the base or Ren'Py base directories, rather than the root of the
filesystem.

The new box_wrapstyle property allows hboxes and vboxes to automatically wrap when they
reach the edge of their enclosing area.
Actions now can have an Action.unhovered()method. This method is called when an action
supplied as a hoveredparameter loses focus.
Added the Tooltipclass, which makes it easier to define tooltips as part of a screen.
Added config.debug_text_overflow, which controls the logging of cases where text exceeds

its allocated area.


its allocated area.
Ren'Py no longer attempts to adjust the system level mixer controls, which means that it's no
longer possible to raise the volume from within Ren'Py. Controlling the system volume
exhibited bugs on all three platforms, including hard-to-predict volume changes that affect
other applications.
Along with the new features, transitions have been documented in the new manual.
Archives are now automatically detected in asciiabetical order. See the documentation for
config.archivesfor more details.

Bug fixes:

launchpad bug 734137 - Timers do not participate in rollback.


launchpad bug 735187 - Ren'Py get stuck when using {nw}. (Thanks to Franck_v for
tracking this down.)

Ren'Py 6.12.0

Android Support

Ren'Py now supports the Android platform. This includes support for a large fraction of
Ren'Py's functionality, although we were unable to add support for imagedissolves and movie
playback. It should be possible to package a Ren'Py game and distribute it through the Android
market.
Android support required several changes in Ren'Py:

The OpenGL renderer has been extended to support OpenGL ES.


For performance reasons, much of the display system has been rewritten in the Cython
language. This also should improve performance on other platforms.
Support was added for the Android lifecycle. Ren'Py automatically saves when the
android device suspends, and reloads (if necessary) upon resume.
We added the concept of Screen Variants. This allows a single game to have multiple
interfaces - such a mouse interface for computer platforms, and a touch interface for
Android-based smartphones and tablets.
We built a system that allows one to package a game separately from Ren'Py. This allows
one to build packages without having to set up the Android NDK (you'll still need the
Android SDK, Java, Python, Ant, and a lot of patience).

New Widgets and Displayables

Added the SpriteManager displayable. This provides a high-performance way of drawing many
similar sprites to the screen. This can scale to hundreds of particles, provided those particles
are mostly similar to each other.
Added the Mousearea widget. A mousearea allows hovered and unhovered callbacks to occur
when the mouse enters and leaves an area of the screen. Since it doesn't participate in the
focus system, a mousearea can include buttons and bars.

Added Drag and Drop widgets and displayables. The drag and drop system can support:

Windows being repositioned by the user.


Card games.
Inventory systems.
Drag-to-reorder systems.

Image Prediction
Ren'Py is now better at predicting image usage. Along with predicting images used by normal
gameplay, it now attempts to predict images that are used by screens one click away from the
user. For example, during normal gameplay, it will predict images on the first screen of the
game menu. While at the game menu, it will predict the other screens of the game menu, and
also the images the user will see when returning to the main menu. This prediction is
automatic, but only occurs when using screens.
Screens may be invoked at any time, in order to allow for image prediction, unless they have a
predict property of False. This means that displaying a screen should not have side effects.
(Most screens only have side effects when a button is clicked or a bar changed - that's still
fine.)
Ren'Py now supports hotspot caching for screen language imagemaps. When
config.developeris true, Ren'Py will write a PNG file in the game/cache/ directory containing
image data for each of the hotspots in the imagemap. If the cache file exists (regardless of the
config.developer setting) it will be loaded instead of loading the hotspot images. As the cache
file is often much smaller than the size of the hotspot images, it will load faster and reduce
image cache pressure, improving game performance. This behavior only applies to screen
language imagemaps, and can be disabled with config.imagemap_cache.
This should remove most of the need for renpy.cache_pin(). While not an error, the use of
cache pinning can cause unnecessary memory usage when the wrong image is loaded.

Screens

Ren'Py now ships with a default set of screens, which are used by the demo and installed by
default when a new game is created. You can find them in template/game/screens.rpy, and
they can be used by copying that file into your project. These screens are not 100%
compatible with the previous layout system - for example, some styles have changed. That's
why games must opt-in to them.

The definition of the itemsparameter of the Choice and NVL screens has changed, and games
will need to be updated to work with the new version.
Character arguments beginning with show_are passed to the Say screen. This allows things
like show_side_image and show_two_window to work with screens. The screens we ship
support these options.
The new config.imagemap_auto_functionvariable allows the game-maker to control the
interpretation of the autoproperty of imagemaps and imagebuttons.
The imagemap caching behavior described above applies only to screens.
The FilePageName()and FileSlotName()functions make it easier to name slots

Other Improvements

Ren'Py 6.12 includes a number of other improvements:

We've continued writing the new manual. Notably, we have rewritten the documentation
for displayables.
When taking a screenshot, config.screenshot_callbackis called. The default
implementation of this function notifies the user of the location of the screenshot.
The Solid()and Frame()displayables are now tiny and no longer take up (much) space
in the image cache.
We now create a log.txt file, which replaces the old opengl.txt, and can log other
subsystems.
Several missing properties have been added to the screen language.
Ren'Py now treats filenames as if they were case-insensitive. This means that filename
mismatches on Linux should no longer be a problem.
Bug Fixes

launchpad bug 680266 - Ensures that dynamic displayables update before Transforms
that use them.
launchpad bug 683412 - Do not crash if a shader fails to compile.
Fixed a bug that caused Ren'Py to crash when the system volume was lowered to 0, but
not muted.
Fixed a bug that prevented Render.canvas()from working with the OpenGL renderer.

Ren'Py 6.11.2

New Features

This release includes four new themes, generously contributed by Aleema. You can see and
change to these new themes by clicking the "Choose Theme" button in the launcher.

Software Update

The jEdit text editor included with Ren'Py has been updated to version 4.3.2, a supported
version that should be able to run most plugins.

Behavior Changes

The maximum default physical size of the Ren'Py window is now 102 pixels smaller than the
height of the screen. This should prevent Ren'Py from creating windows that can't be resized
since they are much bigger than the screen.

Buttons now only pass key events to their children when they are focused. This allows a screen
language key statement to be used as the child of a button, and only activate when the button
is focused.
MoveTransition was rewritten to correctly deal with cases in which images changed their
order. This may lead to differences in behavior from the old version, where the ordering was
undefined.

Bug fixes

Fixed launchpad bug 647686, a regression that prevented sounds from looping properly.
Fixed launchpad bug 661983, which caused insensitive hotspots to default to the idle, rather
than ground, image when no insensitive image was supplied.
Fixed launchpad bug 647324, where ImageDissolves are rendered as if specified with
alpha=True whether or not alpha=True was set.
Fixed a problem that caused the game to start when picking "No" after clicking the (window-
level) quit button.
Fixed a problem that prevented AnimatedValue from functioning properly when delay was not
1.0. Thanks to Scout for the fix.
Fixed a problem that caused movies to display incorrectly when the screen was scaled using
OpenGL scaling.

Ren'Py 6.11.1

New Features

Add the AlphaBlend()displayable and the AlphaDissolve()transition. These take two


displayables, and use the alpha channel of a third displayable to blend them together. (The
displayables, and use the alpha channel of a third displayable to blend them together. (The
third displayable is often an animation, allowing the effect to change over time.)
The new Modes system allows one to invoke callbacks when switching from one type of
interaction to another. This can be used, for example, to automatically hide the window before
transitions.
Imagemaps created using the screen language now only have a size equal to that of their
ground image. (Previously, they took up the entire screen.) This change makes it easier to
position an imagemap at a different location on screen, such as the bottom.
Imagemaps now take an alpha argument. If true (the default), hotspots are only focused if the
mouse is over a non-transparent part of the idle or hover image. If set to false, the hotspot is
focused whenever the mouse is within its boundaries.
Added the renpy.focus_coordinates()function, which returns the coordinates of the currently
focused displayable, when possible.
The new renpy.notify()function and Notify()action make it simple to flash small status
messages on the screen, such as might be used to notify the user of a completed quicksave or
screenshot.
The new HideInterface()action allows the interface to temporarily be hidden, as a screen
language action.
The developer menu now includes a command that will list all the files in the game directory.
The urllib and urllib2 modules from the Python standard library are now distributed as part of
Ren'Py. These modules allow data to be retrieved from web servers.
The launcher now includes an experimental updater, that makes it easier to update to the
latest pre-release. Hitting shift+U at the launcher's main screen will cause Ren'Py to be
updated.

Fixes

MoveTransition()now respects the xoffset and yoffset parameters.

Fixed several bugs with screen-language imagemaps.


Fixed a bug (#626303) that was caused by an incorrect texture unit check. Thanks to tmrwiz
for the fix.
Transforms no longer cause a divide by zero exception when the zoom, xzoom, or yzoom
properties are 0.
Clockwise and counterclockwise revolution in transforms now works.

Fixed a bug with scaling, that occured when switching between the scaled software and GL
renderers.
Hidden screens are no longer considered when assigning default focus.
FieldValues with max_is_zero set to True now work properly. Thanks to SleepKirby for the fix.

Ren'Py 6.11.0

OpenGL Support

Ren'Py will now take advantage of a computer's OpenGL hardware acceleration, if supported.
This OpenGL support has several user-visible changes:

The window containing a Ren'Py game can be resized or maximized, using standard
window controls. When the window's aspect ratio does not match the game's aspect
window controls. When the window's aspect ratio does not match the game's aspect
ratio, black bars will be added.
Displaying in full-screen mode should not change the monitor's resolution. This will
prevent the game from being distorted when displayed on a monitor with a different
aspect ratio.
Unless disabled in the video driver configuration, Ren'Py will use vertical blank
synchronization, eliminating image tearing.
GPU rendering is used, which should make drawing the screen faster in most
circumstances.

Software rendering is still supported, and Ren'Py will automatically fall back to software
rendering if it detects an improperly configured video card.
You can test that Ren'Py is in OpenGL mode by attempting to resize the window. If it's
resizable, it's OpenGL, otherwise, software rendering is being used.

Screens and Screen Language

This release introduces a new screen system, which allows one to use the new screen
language to declaratively specify portions of the user interface. The screen language
supersedes layouts, overlay functions, imagemaps, and most other means of customizing the
out-of-game menus and the in-game screens.
The previous way of customizing the behavior of the game menu, the layout system, had
problems, especially when using imagemap layouts. Screens were single-purpose, and it
would be difficult to (for example) load a quick-save game from the main menu, without
extensive Python code.
The screen system addresses this by providing a pool of functionality, in the form of Actions
and BarValues. This makes it possible to pick and choose functionality, and add it to screens as
is deemed necessary.

Transform Changes

If a transform does not define one of the position properties xpos, ypos, xanchor, or
yanchor, that property will be taken from the transform's child, if the defines that
property.
This makes it possible to have one transform control a displayable's vertical motion, and
the other control the horizontal. But this is incompatible with previous behavior, and so
can be disabled with the config.transform_uses_child_positionvariable.
The new config.default_transform variable allows a transform to specify the initial
transform properties of an image that does not have a more specific transform applied
to it. Its default value is center, a transform that shows the image at the center-bottom of
the screen.
This can lead to a behavior change. When an image is shown, and then shown
transforms, the transform will be initialized to the bottom center of the screen, not the
top-left. The reset transform can be used to reset the position to the top-left.
Transform (and ui.transform) have been changed so that their arguments can now be
prefixed with a style prefix. One can write ui.transform(idle_rotate=30, hover_rotate=90)
and have it work.
Added the rotate_pad transform property, which controls how Transform pads rotated
displayables. When set to False, _not_ the default, it's now possible to rotate a (100, 50)
displayable by 90 degrees, and have the result be (50, 100) in size.

Other Changes
The Ren'Py documentation is in the process of being rewritten. This changelog is now
being maintained as part of the Ren'Py documentation.
Added support for composite style properties, that allow several style properties to be set
using a single parameter. The new composite style properties are:
pos - takes a pair, and uses it to set xpos and ypos.
anchor - takes a pair, and uses it to set xanchor and yanchor.
align - takes a pair, and uses it to set xalign and yalign. (And hence xpos, ypos,
xanchor, and yanchor.)
area - take (x, y, height, width) pair, and tries to set properties such that the
displayable will be placed inside the rectangle. This sets the xpos, ypos, xanchor,
yanchor, xfill, yfill, xminimum, yminimum, xmaximum, and ymaximum properties.
ui.add can now take transform properties as keyword arguments. If at least one
transform property is present, ui.add will create a transform that wraps the displayable
it's adding to the screen.
The new LiveTile()displayable tiles its child, without consuming a large amount of
memory to do so.
config.quit_actionallows one to specify an action that is run when the quit button (in
the corner of the window) is pressed. config.game_menu_action allows one to specify an
action that is run when entering the game menu.
The config.screenshot_cropconfiguration variable controls the area of the screen that
it stored when the user presses the screenshot key.
The renpy.music.register_channel()method now has two additional parameters,
file_prefix and file_suffix. These are prepended and appended to filenames provided to
the registered channel, respectively.
The new renpy.list_files()method returns a list of files in the game directory and
archives. This can be used to write your own automatic image loading method, among
other things.
The interaction between Character and Text has been rewritten to ensure that text is
only tokenized once. This required changing a few of the methods on ADVCharacter and
NVLCharacter, so code that inherits from those classes should be checked.
The distribution code has been moved into launcher/distribute.py. This file can be run
from the command line to build distributions in shell scripts and other automated
processes.
When there are transparent areas on the screen, and config.developeris true, the
transparent areas are filled with a checkerboard pattern.
The new input, side, grid, and fixedstyles were created, and the corresponding
displayables use them by default.
When a style is accessed at init-time, and doesn't exist, we divide it into two parts at the
first underscore. If the second part corresponds to an existing style, we create a new
style instead of causing an error.
The python compiler has been rewritten to use the python ast module. This should both
improve performance, and improve error handling for python syntax.
Because of this change, Ren'Py now ships with and requires Python 2.6.
The following numbered bugs were fixed:
520276 - ctc does not appear when cps interrupted
526297 - im.Rotozoom()s crash when Ren'Py is scaled down. (Thanks to Spiky
Caterpillar for the bug report and fix.)
543785 - Launcher bug on select Projects Directory
583112 - rollback while a movie displayable is shown leaves a video frame
onscreen
595532 - Wrong text in tutorial game. (Thanks to Viliam Br.)
The following other bugs were fixed:
Renamed the internal show and hide methods of Displayable, so those names can
once again be used by user-defined displayables.
Rewrote MultipleTransition (which is used by Fade) to fix some problems it was
exhibiting.
Take the condition parameter to Character into account when determining if an nvl
clear occurs before the next interaction.

Incompatible Changes

This is a list of changes that may require intervention in the form of changes to scripts or your
development environment. Our intent is that all other changes should not affect existing
scripts.
Note that setting config.script_versionwill cause many of these changes to be reverted, at
the cost of losing access to recent features.

6.14

Previously, Ren'Py moved archived files into the archived/ directory. It would search this
directory automatically when running a game or building archives. One-click builds make this
unnecessary, and files in archived/ should be moved back into the game directory.
MoveTransition()has changed its interface. The old version of MoveTransition can be
accessed as OldMoveTransition, if you don't want to rewrite your code. (The changes only
matter if you use factories with MoveTransition.)
Transform()has changed its behavior with regards to asymmetrically scaled and rotated
images. It's unlikely the old behavior was ever used.

6.13.8

Old-style string interpolation has been re-enabled by default. If you wrote code (between 6.13
and 6.13.7) that uses % in say or menu statements, you should either write %% instead, or
include the code:

init python:
config.old_substitutions = False

6.13

The changes to text behavior can affect games in development in many ways. The biggest
change is the introduction of new-style (square-bracket) text substitutions, and the elimination
of old-style (percent-based) substitutions. These changes can be reverted with the code:

init python:
config.old_substitutions = True
config.new_substitutions = False

New- and old-style substitutions can coexist in the same game, by setting both variables to
True.
Ren'Py has also changed the default line-wrapping behavior. While the new behavior should
never increase the number of lines in a paragraph, it may change which words fall on each
line. To restore the old behavior, add the code:

init python:
style.default.layout = "greedy"
style.default.language = "western"

A bug with negative line_spacing was fixed. This fix can cause blocks of text to shrink in height.
To revert to the old behavior, use:

init python:
config.broken_line_spacing = True

Finally, the new text code may lead to artifacts when displaying slow text, especially in
conjunction with a negative line spacing. Consider adjusting :prop:`line_overlap_split` to fix
this.

6.12.1

Image names have changed from being static names to being attribute-based. This can lead
to image names that were previously distinct becoming ambiguous. To disable attribute-based
image names, set config.image_attributesto False.
Showing an image without providing a transform or ATL block will now continue the previous
transform that the image was using. This means that a moving image may continue moving
once it has changed. To revert to the old behavior, set config.keep_running_transformto
False.
The imageargument to Character()has changed meaning. While the old meaning was
unsupported in the screens-based environment, it can be restored for compatibility purposes
by setting config.new_character_image_argumentto False.

6.12.0

The definition of the itemsparameter of the Choice and nvl_choicescreens has changed. The
nvl_choicescreen is deprecated in favor of the NVL screen.

Screens may be invoked at any time, in order to allow for image prediction, unless they have a
predict property of False. When the predict property is not False, screens should not cause side
effects to occur upon their initial display.
For performance reason, Ren'Py now ignores the position properties of ImageReferences. This
means that the position properties of style.image_placement are now ignored. To revert to the
old behavior, set config.imagereference_respects_positionto True.

6.11.1

MoveTransition has been modified to respect the xoffset and yoffset parameters of the
displayables it is moving. The factory functions that are used for movement now take xoffset
and yoffsetparameters. While the built-in movement factories take these parameters without
problem, user-defined factories may need to be upgraded to use or ignore these additional
parameters.

6.11.0

The transform specified by the config.default_transformvariable is used to initialize


the transform properties of images shown using the show and hide statements. The
default value of this transform sets xposand xanchorto 0.5, and yposand yanchorto 1.0.
This represents a change in the default value of these style properties, which were
previously uninitialized and hence defaulted to 0.
By including the resettransform in ATL transforms, these properties can be reset back
to 0. Alternatively, one can stop using the default transform, and revert to the old
behavior, using the code:

init python:
style.image_placement.xpos = 0.5
style.image_placement.ypos = 1.0
style.image_placement.xanchor = 0.5
style.image_placement.yanchor = 1.0

config.default_transform = None

If a transform does not define one of the position properties xpos, ypos, xanchor, or
yanchor, that property will be taken from the transform's child, if the defines that
property.
This makes it possible to have one transform control a displayable's vertical motion, and
the other control the horizontal. But this is incompatible with previous behavior, and so
can be disabled with the config.transform_uses_child_positionvariable.

init python:
config.transform_uses_child_position = False

6.10.0

The default positions (left, right, center, truecenter, offscreenleft, and offscreenright) are
now defined as ATL transforms. This means that showing an image at such a position will
cause the position to be remembered. If you do not want this behavior, you need to
redefine these positions, by adding the code:

define left = Position(xalign=0.0)


define center = Position(xalign=0.5)
define truecenter = Position(xalign=0.5, yalign=0.5)
define right = Position(xalign=1.0)
define offscreenleft = Position(xpos=0.0, xanchor=1.0)
define offscreenright = Position(xpos=1.0, xanchor=0.0)

6.9.2

To migrate your game from Ren'Py 6.9.2 or later, copy the directory containing your
game into your projects directory. You can choose a projects directory by clicking
"Options", "Projects Directory" in the Launcher. Please see the Ren'Py 6.9.2 release notes
for information about migrating from older releases.

Distributor Notes

6.12.0

Ren'Py now creates a number of binary modules that live in the renpy.display package. As long
as they go in the same place as _renpy.so, they should be picked up automatically.
6.11.0

Ren'Py now depends on:

Python 2.6
OpenGL
The GL Extension Wrangler Library: http://glew.sourceforge.net/
The argparse Python module: http://code.google.com/p/argparse/

License

Most of Ren'Py is covered by the terms of the following (MIT) license:

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Portions of Ren'Py are derived from code that is copyright using the Lesser GNU Public License,
so Ren'Py games must be distributed in a manner that satisfies the LGPL.
Please see each individual source file for a list of copyright holders. The artwork in the demo is
released by various copyright holders, under the same terms.
Ren'Py binaries include code from the following projects:

Python (Python License)


Pygame (LGPL)
SDL (LGPL)
SDL_image (LGPL)
SDL_ttf (LGPL)
Freetype (LGPL)
Fribidi (LGPL)
libav (LGPL)
libjpeg-turbo (LGPL)
libpng (PNG license)
zlib (Zlib License)
bzip2 (Bzip2 License)
pyobjc (MIT License)
py2exe (MIT License)
GLEW (Modified BSD, MIT)
zsync (Artistic License)

For the purpose of LGPL compliance, the source code to all LGPL software we depend on is
either in the Ren'Py package (available from http://www.renpy.org/), or in the renpy-deps
package (http://www.renpy.org/dl/lgpl/). We believe compliance can be achieved by including
a copy of this license with every copy of Ren'Py you distribute, and referring to it in your
project's README file.
Ren'Py may be distributed alongside the jEdit or Editra text editors. Editra is licensed under the
wxWindows license, while jEdit is under the GNU General Public License.

GNU Lesser General Public License

GNU LESSER GENERAL PUBLIC LICENSE


Version 2.1, February 1999

Copyright (C) 1991, 1999 Free Software Foundation, Inc.


51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]

Preamble

The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some


specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.

When we speak of free software, we are referring to freedom of use,


not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

To protect your rights, we need to make restrictions that forbid


distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis


or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the


library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

Finally, software patents pose a constant threat to the existence of


any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the


ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

When a program is linked with a library, whether statically or using


a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.

We call this license the "Lesser" General Public License because it


does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.

For example, on rare occasions, there may be a special need to


encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free


programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

Although the Lesser General Public License is Less protective of the


users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and


modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other


program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data


prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work


which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.

Activities other than copying, distribution and modification are not


covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's


complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

a) The modified work must itself be a software library.

b) You must cause the files modified to carry prominent notices


stating that you changed the files and the date of any change.

c) You must cause the whole of the work to be licensed at no


charge to all third parties under the terms of this License.

d) If a facility in the modified Library refers to a function or a


table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.

(For example, a function in a library to compute square roots has


a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)

These requirements apply to the modified work as a whole. If


identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest


your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library


with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.

Once this change is made in a given copy, it is irreversible for


that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or


derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

If distribution of object code is made by offering access to copy


from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data


structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may


distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or


link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:

a) Accompany the work with the complete corresponding


machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)

b) Use a suitable shared library mechanism for linking with the


Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.

c) Accompany the work with a written offer, valid for at least


three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.

d) If distribution of the work is made by offering access to copy


from a designated place, offer equivalent access to copy the above
specified materials from the same place.

e) Verify that the user has already received a copy of these


materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

It may happen that this requirement contradicts the license


restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

a) Accompany the combined library with a copy of the same work


based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.

b) Give prominent notice with the combined library of the fact


that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute


the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

11. If, as a consequence of a court judgment or allegation of patent


infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under


any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any


patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to


be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in


certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library


specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO


WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN


WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest


possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).

To apply these terms, attach the following notices to the library.


It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.

<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>

This library is free software; you can redistribute it and/or


modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,


but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the


library `Frob' (a library for tweaking knobs) written by James
Random Hacker.

<signature of Ty Coon>, 1 April 1990


Ty Coon, President of Vice

That's all there is to it!

Python License

1. This LICENSE AGREEMENT is between the Python Software Foundation


("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using Python 2.3 software in source or binary form and its
associated documentation.

2. Subject to the terms and conditions of this License Agreement, PSF


hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python 2.3
alone or in any derivative version, provided, however, that PSF's
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
2001, 2002 Python Software Foundation; All Rights Reserved" are
retained in Python 2.3 alone or in any derivative version prepared by
Licensee.

3. In the event Licensee prepares a derivative work that is based on


or incorporates Python 2.3 or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python 2.3.

4. PSF is making Python 2.3 available to Licensee on an "AS IS"


basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.

5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON


2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

6. This License Agreement will automatically terminate upon a material


breach of its terms and conditions.

7. Nothing in this License Agreement shall be deemed to create any


relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.

8. By copying, installing or otherwise using Python 2.3, Licensee


agrees to be bound by the terms and conditions of this License
Agreement.

Jpeg License

In plain English:

1. We don't promise that this software works. (But if you find any bugs,
please let us know!)
2. You can use this software for whatever you want. You don't have to pay us.
3. You may not pretend that you wrote this software. If you use it in a
program, you must acknowledge somewhere in your documentation that
you've used the IJG code.

In legalese:

The authors make NO WARRANTY or representation, either express or implied,


with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.

This software is copyright (C) 1991-1998, Thomas G. Lane.


All Rights Reserved except as specified below.

Permission is hereby granted to use, copy, modify, and distribute this


software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.

These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.

Permission is NOT granted for the use of any IJG author's name or company name
in advertising or publicity relating to this software or products derived from
it. This software may be referred to only as "the Independent JPEG Group's
software".

We specifically permit and encourage the use of this software as the basis of
commercial products, provided that all warranty or liability claims are
assumed by the product vendor.

PNG License

The PNG Reference Library is supplied "AS IS". The Contributing Authors
and Group 42, Inc. disclaim all warranties, expressed or implied,
including, without limitation, the warranties of merchantability and of
fitness for any purpose. The Contributing Authors and Group 42, Inc.
assume no liability for direct, indirect, incidental, special, exemplary,
or consequential damages, which may result from the use of the PNG
Reference Library, even if advised of the possibility of such damage.
Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, without fee, subject
to the following restrictions:

1. The origin of this source code must not be misrepresented.

2. Altered versions must be plainly marked as such and must not


be misrepresented as being the original source.

3. This Copyright notice may not be removed or altered from any


source or altered source distribution.

The Contributing Authors and Group 42, Inc. specifically permit, without
fee, and encourage the use of this source code as a component to
supporting the PNG file format in commercial products. If you use this
source code in a product, acknowledgment is not required but would be
appreciated.

Zlib License

This software is provided 'as-is', without any express or implied


warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,


including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

Bzip2 License

This program, "bzip2", the associated library "libbzip2", and all


documentation, are copyright (C) 1996-2005 Julian R Seward. All
rights reserved.

Redistribution and use in source and binary forms, with or without


modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright


notice, this list of conditions and the following disclaimer.

2. The origin of this software must not be misrepresented; you must


not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.

3. Altered source versions must be plainly marked as such, and must


not be misrepresented as being the original software.

4. The name of the author may not be used to endorse or promote


products derived from this software without specific prior written
permission.
permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Modified BSD License

Redistribution and use in source and binary forms, with or without


modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,


this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

Artistic License

The Artistic License


Version 2.0beta4, October 2000

Copyright (C) 2000, Larry Wall.


Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

This copyright license states the terms under which a given free
software Package may be copied, modified and/or redistributed, while the
Originator(s) maintain some artistic control over the future development
of that Package (at least as much artistic control as can be given under
copyright law while still making the Package open source and free software).

This license is bound by copyright law, and thus it legally applies only
to works which the copyright holder has permitted copying, distribution
or modification under the terms of the Artistic License, Version 2.0.

You are reminded that You are always permitted to make arrangements
You are reminded that You are always permitted to make arrangements
wholly outside of a given copyright license directly with the copyright
holder(s) of a given Package. If the terms of this license impede your
ability to make full use of the Package, You are encouraged to contact
the copyright holder(s) and seek a different licensing arrangement.

Definitions

"Package" refers to the collection of files distributed by the


Originator(s), and derivatives of that collection of files created
through textual modification.

"Standard Version" refers to the Package if it has not been modified, or


has been modified only in ways suggested by the Originator(s).

"Modified Version" refers to the Package, if it has been changed by You


via textual modification of the source code, and such changes were not
suggested by the Originator(s).

"Originator" refers to the author(s) and/or copyright holder(s) of the


Standard Version of the Package.

"You" and "Your" refers to any person who would like to copy,
distribute, or modify the Package.

"Distribution Fee" is any fee that You charge for providing a copy of
this Package to another party. It does not refer to licensing fees.

"Freely Available" means that:

(a) no fee is charged for the right to use the item (though a
Distribution Fee may be charged).

(b) recipients of the item may redistribute it under the same


conditions they received it.

(c) If the item is a binary, object code, bytecode, the complete


corresponding machine-readable source code is included with the
item.

Permission for Use and Modification Without Redistribution

(1) You are permitted to use the Standard Version and create and use
Modified Versions for any purpose without restriction, provided that
you do not redistribute the Modified Version to others outside of your
company or organization.

Permissions for Redistribution of the Standard Version

(2) You may make available verbatim copies of the source code of the
Standard Version of this Package in any medium without restriction,
either gratis or for a Distribution Fee, provided that you duplicate
all of the original copyright notices and associated disclaimers. At
Your discretion, such verbatim copies may or may not include compiled
bytecode, object code or binary versions of the corresponding source
code in the same medium.

(3) You may apply any bug fixes, portability changes, and other
modifications made available from any of the Originator(s). The
resulting modified Package will still be considered the Standard
Version, and may be copied, modified and redistributed under the terms
of the original license of the Standard Version as if it were the
Standard Version.

Permissions for Redistribution of Modified Versions of the Package as Source

(4) You may modify your copy of the source code of this Package in any way
and distribute that Modified Version (either gratis or for a
Distribution Fee, and with or without a corresponding binary, bytecode
or object code version of the Modified Version) provided that You
clearly indicate what changes You made to the Package, and provided
that You do at least ONE of the following:

(a) make the Modified Version available to the Originator(s) of the


Standard Version, under the exact license of the Standard
Version, so that the Originator(s) may include your modifications
into the Standard Version (at their discretion).

(b) modify any installation scripts and procedures so that


installation of the Modified Version will never conflict with an
installation of the Standard Version, include for each program
installed by the Modified Version clear documentation describing
how it differs from the Standard Version, and rename your
Modified Version so that the name is substantially different from
the Standard Version.

(c) permit and encourage anyone who receives a copy of the Modified
Version permission to make your modifications Freely Available in
some specific way.

If Your Modified Version is in turn derived from a Modified Version


made by a third party, then You are still required to ensure that Your
Modified Version complies with the requirements of this license.

Permissions for Redistribution of Non-Source Versions of Package

(5) You may distribute binary, object code, bytecode or other non-source
versions of the Standard Version of the Package, provided that you
include complete instructions on where to get the source code of the
Standard Version. Such instructions must be valid at the time of Your
distribution. If these instructions, at any time while You are
carrying our such distribution, become invalid, you must provide new
instructions on demand or cease further distribution. If You cease
distribution within thirty days after You become aware that the
instructions are invalid, then You do not forfeit any of Your rights
under this license.

(6) You may distribute binary, object code, bytecode or other non-source
versions of a Modified Version provided that You do at least ONE of
the following:

(a) include a copy of the corresponding source code for the Modified
Version under the terms indicated in (4).

(b) ensure that the installation of Your non-source Modified Version


does not conflict in any way with an installation of the Standard
Version, include for each program installed by the Modified
Version clear documentation describing how it differs from the
Standard Version, and rename your Modified Version so that the
name is substantially different from the Standard Version.

(c) ensure that the Modified Version includes notification of the


changes made from the Standard Version, and offer to provide
machine-readable source code (under a license that permits making
that source code Freely Available) of the Modified Version via
mail order.

Permissions for Inclusion of the Package in Aggregate Works

(7) You may aggregate this Package (either the Standard Version or
Modified Version) with other packages and distribute the resulting
aggregation provided that You do not charge a licensing fee for the
Package. Distribution Fees are permitted, and licensing fees for
other packages in the aggregation are permitted. Your permission to
distribute Standard or Modified Versions of the Package is still
subject to the other terms set forth in other sections of this
license.

(8) In addition to the permissions given elsewhere by this license, You


are also permitted to link Modified and Standard Versions of this
Package with other works and distribute the result without
restriction, provided You have produced binary program(s) that do not
overtly expose the interfaces of the Package. This includes
permission to embed the Package in a larger work of your own without
exposing a direct interface to the Package. This also includes
permission to build stand-alone binary or bytecode versions of your
scripts that require the Package, but do not otherwise give the casual
user direct access to the Package itself.

Items That are Never Considered Part of a Modified Version Package

(9) Works (including, but not limited to, subroutines and scripts) that
you have linked or aggregated with the Package that merely extend or
make use of the Package, but are not intended to cause the Package to
operate differently from the Standard Version, do not, by themselves,
cause the Package to be a Modified Version. In addition, such works
are not considered parts of the Package itself, and are not bound by
the terms of the Package's license.

Acceptance of License and Disclaimer of Warranty

(10) You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to copy, modify or
distribute the Standard or Modified Versions of the Package. These
actions are prohibited by copyright law if you do not accept this
License. Therefore, by copying, modifying or distributing Standard
and Modified Versions of the Package, you indicate your acceptance of
the license of the Package.

(11) Disclaimer of Warranty:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS


"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT UNLESS REQUIRED BY
LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER OR CONTRIBUTOR
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Indices
Style Property Index
Transform Property Index
Variable and Definition Index
Function and Class Index
General Index