Ren'Py Examples: Language basics

The Ren’Py script language is not the Python language
The relationship between Python and Ren’Py is:
-
The Ren’Py engine and SDK (software development kit) is written in Python using pygame libraries.
-
You can include Python code in your games
-
The Ren’Py script language is similar to Python in having a line-oriented block syntax structure. But it is much more convenient for writing screenplay-like game scripts than raw Python would be.
When you’re writing a Ren’Py game in a file ending in the file extension .rpy
,
you are writing in the Ren’Py script language.
Including Python code allows you to perform more powerful programmatic actions. You can embed Python within the screenplay-like Ren’Py language.
Fun fact: Python creator Guido van Rossum named "Python" after Monty Python’s Flying Circus, which is a favorite of mine as well.

Ren’Py script language basics
In a "typical" Ren’Py game, you’ll be writing character dialog and menu choices in the Ren’Py script language.
There aren’t too many concepts in the language itself, so let’s dive in.
Indenting
Like Python, Ren’Py script requires indenting to indicate blocks of code.
You can indent a block with tab characters or space characters.
(It will perhaps amuse you to learn that programmers have been arguing over using spaces versus tabs to indent code for decades.)
Here’s what we mean when we say "blocks" of code:
block indented with two spaces block indented with two spaces block indented with eight spaces block indented with eight spaces block indented with four spaces block indented with four spaces
The key thing with indenting is that it has to be consistent. If you indent one line with four spaces, another with two, and then another with a tab, you have caused a sinful insult to the computer (and a situation that will be confusing to you, the human).
If you aren’t consistent about indenting, you’ll see something like this:
File "game/script.rpy", line 14: Indentation mismatch.
A proper text editor is a completely free piece of software and, amongst other things, it will assist you with indenting. (Typically, you can select a block of text and use the Tab key to indent and Shift+Tab to un-indent. (If your editor uses different keys for this, you’re probably using Vim or Emacs and you do not need to be reading this parenthetical.))
Labels
A label is a way of identifying a block of Ren’Py script. It’s the keyword "label" followed by a name and then a colon (":") character.
Everything after the label needs to be indented in order to be considered part of the label.
label foo: STUFF INSIDE THE LABEL MORE STUFF STUFF NO LONGER IN THE LABEL
Your game will need a script containing a start
label.
If you don’t have one, you’ll get an error. Example:
define e = Character("Eileen") e "Hello from the dawn of the Universe"
Ren’Py freaks right out with this error message:
ScriptError: could not find label 'start'.
So let’s put in a start
label.
define e = Character("Eileen") e "Hello from the dawn of the Universe" label start: e "Hi, I'm Eileen and this is a Ren'Py script!"
Note how the "Hello from the dawn of the Universe" message is not displayed?
That’s because the game starts with the start
label! Where did that other
message go? Best not to think about it.
Jumping to a label
The purpose of labels is to allow you to control how the script flows as the player progresses through your game and makes choices.
The simplest way to get from one block of Ren’Py script to another is
with the jump
keyword.
define e = Character("Eileen") label beans: e "Have you ever really thought about beans?" label start: e "Hello, I'm Eileen. Is this seat taken?" jump beans
Let’s see it in action:
Then, when you click to advance the dialog, our jump
to
the beans block happens and we see the next line of dialog:
Notice how the order of the labels in your script doesn’t matter? Blocks will be called as needed.
For example, the label beans
came before start
, but we don’t see it
until we jump to it.
Quick Aside: Characters and saying stuff
The define e = Character("Eileen")
statement in the example above is
important and deserves further discussion. For now, know that we have a
character named "Eileen" and assigned her to the e
variable name. This
is a handy shortcut that will cut down on typing (and mistakes)!
A "say" statement does not have to use a pre-defined character.
Here’s an example of saying something with no specified character, and saying something with a character identified by name:
label start: "I am a voice from the Beyond!!!" "Beyond" "No, actually, I'm Beyond. Who are you?"
Displays character-less "narrator" dialog or text:
And here’s that "Beyond" character identified only by name:
Like define
, saying things is a topic that deserves its own section,
but this should be enough to get you going.
Including Python code in your Ren’Py scripts
There are two ways to include Python code in your scripts.
TODO: There may be a third way, "simple expressions", but I do not understand these yet.
If you have just a single line of Python, you can write it neatly and compactly by starting the line with a dollar sign at the beginning of the line:
$ ONE LINE OF PYTHON
If you have more than one line of Python code, use the block syntax which
starts with a python:
label followed by any number of lines of Python code.
The code continues as long as the statements are indented.
python: PYTHON CODE MORE PYTHON CODE
Complete example:
define e = Character("Eileen") label start: e "Hi, I'm Eileen and this is a Ren'Py script!" $ say(e, "This is still me talking, but via a line of Python code.") python: say(e, "And now I'm talking in a Python code block.") say(e, "Still talking.") say(e, "Also talking here. Still in a Python block.")
Which produces this in-game dialog from the script:
And this one from the Python line:
And these three from the Python block:
It’s probably safe to say that understanding how Python code interacts with Ren’Py scripts will be the subject of most of the examples I’ll be making.