Language Basics
Before we can describe the Ren'Py language, we must first describe the structure of a Ren'Py script. This includes how 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 the Unicode order of their paths), and will
use the contents of the files as the script.
Generally, there's no difference between a script written in one big file and a script broken into multiple files. Control can be transferred within the script (including 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 creators 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 .rpy
files into
.rpyc
files when it starts up. When a .rpy
file is changed, the
.rpyc
file will be updated when Ren'Py starts up. However, if a
.rpyc
file exists without a corresponding .rpy
file, the
.rpyc
file will be used. This can lead to problems if a .rpy
file is deleted, or renamed, or moved, without deleting the .rpyc
file : the script it contains will still get executed.
Filenames must begin with a letter or number, but may not begin with "00", as Ren'Py uses such files for its own purposes.
Base Directory
The base directory is the directory that contains all files that are distributed with the game (even though not all the files in the base directory are usually distributed). See also : Building Distributions. Things like README files should be placed in the base directory.
The base directory is created within the "Projects Directory", which can be set
in the Launcher, when you create a new game. For example, if your Projects
Directory is named renpygames
, and your game is named "HelloWorld", your
base directory will be renpygames/HelloWorld
.
Game Directory
The game directory is a directory named "game" inside the base directory. For
example, if your base directory is renpygames/HelloWorld
, your game
directory will be renpygames/HelloWorld/game
.
The game directory contains all the files used by the game. It, including all
subdirectories, is scanned for .rpy
and .rpyc
files, and those
are combined to form the game script. It is scanned for .rpa
archive
files, and those are automatically used by the game. Finally, when Ren'Py takes
or considers a path to a file, the path is (with very few exceptions) relative
to the game directory (but note that config.searchpath
can change this).
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 closing parenthesis character ()
,}
, or]
, respectively).The end of the line occurs during a string - any string, even with single quotes, as opposed to Python rules.
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.
"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 lines are ignored and do not count as logical lines.
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 non-empty logical line is encountered with less indentation than the lines in the block.
Indentation is very important in Ren'Py, as it is in Python, and it can cause syntax or logical errors when it's incorrect. At the same time, the use of indentation to express the block structure is far simpler than other languages using other delimiters.
"This statement, and the if statement that follows, are 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 script of the game. Keywords are typically used to introduce statements and properties.
- 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.
Warning
Names beginning with a single underscore (_) are reserved for Ren'Py internal use, unless otherwise documented.
When a name begins with two underscores (__) but doesn't end with two underscores, it is changed to a file-specific version of that name.
- Image Name
An image name consists of one or more components, 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. An image component consists of a string of letters, numbers, and underscores.
For example, take the image name
mary beach night happy
. The image tag ismary
, while the image attributes are,beach
,night
, andhappy
.The words
at
,as
,behind
,onlayer
,with
, andzorder
, may not be used as parts of an image name.- 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 \%), [ (written as \[), and { (written as \{). It's also used to include newlines, using the \n sequence.
Inside a Ren'Py string, consecutive sequences of whitespace and line breaks are compressed into a single whitespace character, unless a space is preceded by a backslash.
'Strings can\'t contain their delimiter, unless you escape it.' "There will be a space between the two following words." "There will be a line break between\nthese." "And there will be three spaces between\ \ \ these."
The
r
prefix is supported, and follow more or less the same rules as in Python. Other prefixes, likeu
,b
orf
, are not supported. Triple-quoted strings are generally not accepted in places where a normal string is expected, and when they are, they usually yield a different result - see Monologue Mode for an example.Note
This applies to strings found directly in Ren'Py script, such as in Say Statement or In-Game Menus. Strings found inside python statements, or in expressions (see below), follow ordinary Python rules.
- 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
, andfoo(42)
are all simple expressions. But3 + 4
is not, as the expression ends at the end of a string.- 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.
3
and42
are integers.- Float
A float (short for floating-point number) is a number with a decimal point.
.5
,7.
, and9.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 several lines, or be delimited with `.
- True, False, None
There are three special values.
True
is a true value,False
is a false value.None
represents the absence of a value.- 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 comma 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 the Default Statement. A variable name follows the rules of a name as explained in Elements of Statements. For example:
playername love_love_points trebuchet2_range
- Field Access
Python modules and objects have fields, which can be accessed 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, an equals sign, and an expression. In this 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:type
with the value of theadv
variable, andcolor
with a string value of"#0f0"
.Other objects than functions can be called, and are widely known as callables.
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 positional parameters, and **kwargs
, which means
that it takes a wide range of keyword parameters which are usually explained
in the function's documentation.
When you see a /
symbol on its own in a function signature, it means that
the parameters before it are positional-only, and should not be passed by
keyword. When you see a *
symbol on its own, conversely, it means that the
parameters after it are keyword-only, which means that they should only be
passed using the name=value
syntax.
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 a deep knowledge of Python is not necessary to work with Ren'Py, knowing the basics of Python statements and expressions is often helpful.
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.Ren'Py ignores comments, so the script is treated like the comment wasn't there.