Ren%27Py Documentation

December 23, 2016 | Author: Aníbal | Category: N/A
Share Embed Donate


Short Description

Download Ren%27Py Documentation...

Description

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 rightclicking 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 ingame-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 4tuple (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 layerrelated 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. 2. 3. 4. 5.

Translating text. Interpolating data into the text. Styling the text using styles and text tags. Laying out the styled text. 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, "[email protected]" is the first font in a collection, "[email protected]" 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.r egister_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.r egister_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.r egister_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.A lphaMask(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.C omposite(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.C rop(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.F actorScale(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.F lip(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.G rayscale(im, **properties)

An image manipulator that creats a desaturated version of the image manipulator im. im.S cale(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.S epia(im, **properties)

An image manipulator that creates a sepia-toned version of the image manipulator im. im.T ile(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.M atrixColor(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.m atrix()

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.b rightness(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.c olorize(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.c ontrast(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.d esaturate()

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

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

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

Returns an im.matrix that inverts the red, green, and blue channels of the image without changing the alpha channel. im.matrix.o pacity(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.s aturation(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.t int(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.m ove_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. 2. 3. 4. 5.

crop, corner1, corner2 size zoom, xzoom, yzoom rotate 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 (no prefix) insensitive_ idle_ selected_ selected_idle_ selected_hover_

states implied by prefix insensitive, idle, hover, selected_idle, selected_hover insensitive idle, selected_idle selected_idle, selected_hover selected_idle 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 "[email protected]"or "[email protected]"). 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. 2. 3. 4. 5. 6.

style.mm_button["Start Game"] style.mm_button style.button["Start Game"] style.button style.default["Start Game"] 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.g et_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.r egister_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.s et_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.r ebuild()

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

first page is slowing, this returns "2". second page is showing, this returns "12". auto page is showing, this returns "a2". 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-tocontinue, 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 latestversion 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 nontransparent 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.h ide(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.i mage(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.s cene(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.s how(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.w ith_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 The The The The

current statement, and all statements that can be returned to. images and displayables that are being shown. screens being shown, and the values of variables within those screens. music that Ren'Py is playing. 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.c an_load(filename, test=False)

Returns true if filenameexists as a save file, and False otherwise. renpy.l ist_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.l oad(filename)

Loads the game state from filename. This function never returns. renpy.r ename_save(old, new)

Renames a save from oldto new. renpy.s ave(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.t ake_screenshot(scale=None, background=False)

Causes a screenshot to be taken. This screenshot will be saved as part of a save game. renpy.u nlink_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.c heckpoint(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.i n_rollback()

Returns true if the game has been rolled back. renpy.r oll_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.b lock_rollback()

Prevents the game from rolling back to before the current statement. renpy.f ix_rollback()

Prevents the user from changing decisions made before the current statement. renpy.i n_fixed_rollback()

Returns true if rollback is currently occurring and the current context is before an executed renpy.fix_rollback() statement. ui.C hoiceJump(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.C hoiceReturn(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.c all_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.d efine_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.g et_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.g et_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.h ide_screen(tag, layer='screens')

The programmatic equivalent of the hide screen statement. Hides the screen with tagon layer. renpy.s how_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.v ariant(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.a djustment(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.a t(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.c lose()

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.d etached()

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.l ayer(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.m ode(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.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 creatordefined 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.d isplayable(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.r ender(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.t imeout(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.r edraw(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.c all(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.c lear_game_runtime()

Resets the game runtime counter. renpy.f ocus_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.f sdecode(s)

Converts s from filesystem encoding to unicode. renpy.f sencode(s)

Converts s from unicode to the filesystem encoding. renpy.g et_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.g et_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.g et_physical_size()

Returns the size of the physical window. renpy.g et_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.g et_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.g et_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.i mage_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.l ist_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.n otify(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.s et_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.v ibrate(duration)

Causes the device to vibrate for durationseconds. Currently, this is only supported on Android. renpy.music.r egister_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.y esno_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.f sencode(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 spaceseparated 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.a rchive(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.c lassify(pattern, file_list)

Classifies files that match patterninto file_list. build.c lear()

Clears the list of patterns used to classify files. build.d ocumentation(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.e xecutable(pattern)

Adds a pattern marking files as executable on platforms that support it. (Linux and Macintosh) build.p ackage(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. 2. 3. 4. 5.

Downloading an index file that controls what is updated. Asking the user if he or she wants to proceed with the update. Producing an archive file from the files on disk. Downloading a zsync control file from the server. 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.U pdate(*args, **kwargs)

An action that calls updater.update(). All arguments are stored and passed to that function. updater.c an_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.g et_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.u pdate(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 import subprocess File "C:\Python27\lib\subprocess.py", line 444, in 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 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 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. 2. 3. 4.

OpenGL 2.0 or greater. DirectX 9, provided that all libraries are available. OpenGL 1.x. 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 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 semiautomatically 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 screenlocal 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 (windowlevel) 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 Búr.)

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

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF