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:
This chapter discusses the process of text display in Ren'Py.
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.
The backslash character is used to introduce when writing a Ren'Py or Python string. Some common escape codes are:
Ren'Py supports interpolating data into the text string before it is displayed. For example, if the player's name is stored in the playername variable, 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]."
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.
Tags that apply to all text are:
The anchor tag creates a hyperlink between itself and its closing tag. While the behavior of the hyperlink is controlled by the hyperlink_functions style property, the default handler has the following behavior.
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
The bold tag renders the text between itself and its closing tag in a bold font.
"An example of {b}bold test{/b}."
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}"
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}
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}."
The italics tag renders the text between itself and its closing tag in italics.
"Visit the {i}leaning tower of Pisa{/i}."
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}"
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}"
The strikethrough tag draws a line through text between itself and its closing tag.
g "It's good {s}to see you{/s}."
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.
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.
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}."
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."
The underline tag underlines the text between itself and its closing tag.
g "It's good to {u}see{/u} you."
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"
Text tags that only apply to dialogue are:
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."
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."
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"
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"
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:
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 (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:
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.
Ren'Py supports Truetype and Image-Based fonts.
A Truetype font is specified by giving the name of the font file. The file must be present in the game directory, or one of the archive files.
Ren'Py also supports Truetype collections that define more than one font. When accessing a collection, use the 0-based font index, followed by an at-sign and the file name. For example, "0@font.ttc" is the first font in a collection, "1@font.ttc" the second, and so on.
The config.font_replacement_map variable 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", False, False)
This mapping can improve the look of italic text.
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.
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.
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.
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.
the order in which they are found in the image. The default character set for a SFont is:
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
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."
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.
A displayable that displays text on the screen.
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_leading and 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.
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:
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.
Ren'Py has support for automatically creating translation files. Taking advantage of this is a three-step process.
Ren'Py will add an entry to the translations file for each unit of text shown. This text can then be translated.
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.
Whenever text is displayed that overflows the available area, Ren'Py will log an error to the text_overflow.txt file.