Text - Ren'Py Visual Novel Engine

documentation index ◦ reference manual ◦ function index

# Text

This section covers aspects of text in Ren'Py. It first covers interpolation, supported by the say and menu statements, which allows values to be substituted into text. It next discusses text tags, which allow the style of portions of strings of text to be customized. Finally, it covers how Ren'Py handles fonts.

## Interpolation

Interpolation is supported by the `say` and `menu` statements. These statements support python string interpolation over the contents of the store. The strings used by the statements support conversion specifiers of the form `%(variable)s`, where `variable` is the name of a variable and `s` is a conversion. Useful conversions include 's', which interpolates a string; 'd', which interpolates an integer; and 'f', which interpolates a floating point number. Conversions may also include characters that modify how the string is converted. More information about conversions can be found at the Python string formatting operations reference.

In strings where interpolation is supported, percent characters (%) must be duplicated (to %%) to prevent them from being interpreted as introducing interpolation.

    $ name = 'Samantha'
    $ age = 19
    $ withyou = 110

    girl "My name is %(name)s, and I am %(age)d years old. I'm with you %(withyou)d%%"

When interpolation is not supported, the effect can often be faked by formatting a string against the result of calling the globals() function.

    ui.text("%(name)s's Vital Statistics" % globals())

Text tag processing is performed after interpolation, so it's important to ensure interpolation does not introduce text tags.

## Text Tags

Text displayed by Ren'Py supports text tags. While styles can only be applied to an entire Text displayable, allow only a portion of the text in the displayable to be customized. As text tags are part of the Text displayable, they may be used in any string that is displayed on the screen. However, some of the text tags will only have effect if used in the appopriate context.

Text tags should be used fairly sparingly. If you find you're using text tags on every line of the game, it's quite possible text tags are not the right solution for the problem at hand. Investigate text styles as a possible alternative to text tags.

Text tags start with a left brace ({), and continue to the matching right brace (}). Immediately following the left brace is the tag name. The name may be followed by an argument, which is separated from the tag name by an equals sign (=). Some tags require an argument, while others require that the argument be omitted. Text tags are sensitive to case and white space.

Some tags require a corresponding closing tag. A closing tag is any text tag where the name begins with a slash (/). Closing tags should be properly nested: "{b}{i}this is okay{/i}{/b}", while "{b}{i}this is wrong{/b}{/i}". While improper nesting of text tags will generally not cause an error, this problem may cause undesirable rendering results. The text between a tag and the corresponding closing tag is called the enclosed text. All tags must be closed by the end of the text string.

To include a single left brace in text, two left braces ({{) musty be included instead.

Ren'Py supports the following text tags:

- {a=argument} and {/a} cause their enclosed text to be rendered as a hyperlink. The enclosed text may contain text tags, but may not contain another hyperlink. A hyperlink is rendered as a button containing the enclosed text. The text in the button does not participate in line-breaking. Rather, if the text grows too big for the line it is on, the whole button is moved to the start of the next line.

  When a a hyperlink is clicked, the callback function defined in config.hyperlink_callback is called with the text of the argument of the hyperlink.

  The default hyperlink checks to see if the hyperlink begins with "http:". If it does, the link is opened in the user's web browser. If not, the hyperlink is interpreted as a label, which is called in a new context. This is an appropriate behavior when using hyperlinks to definitions of unfamiliar terms.

  Hyperlinks should not be used as a general control-flow tool, as they transfer control to a new context when clicked. If the user saves while inside that context, when he loads the game he will be returned to the screen containing the hyperlink.

    init:
        $ definition = Character(None, window_yfill=True, window_xmargin=20,
                                 window_ymargin=20, window_background=Solid((0, 0, 0, 192)))

    label start:

        "A game that instructs on how to make a game? Isn't that a sort of {a=define_quine}Quine{/a}?"

        # ...

    label define_quine:

        definition "Quine:\n\nA program that prints itself to its output."

        return

- {b}text{/b} renders the enclosed text in a bold font.
- {color=spec}text{/color} changes the color of the enclosed text. The color may be a hex triple or a hex sextuple, optionally preceded by a hash mark. (The same format that color() accepts. f00, ff0000, #f00, and #ff0000 are all valid representations of red.)
- {fast} causes the immediated display of text before it. It can be used to specify where slow text shold begin to display from. It only has an effect if the text speed preference is not infinite. Use this if you have two lines of dialogue where the second is an extension of the first, as a variant of the pause effect that allows for changes to occur while paused. This tag does not take a closing tag.
- {font=filename.ttf}text{/font} renders the enclosed text in the supplied font.
- {i}text{/i} makes the enclosed text in an italic font.
- {image=filename} causes the supplied image to be loaded and included into text. The image should are treated as if they were text, and should not be taller than a single line of text. {image} does not take a closing tag.
- {nw}, at the end of a block of text, causes the current interaction to terminate immediately once the text is fully shown. It only makes sense to use this in dialogue text, where the effect is to cause slow text to dismiss the interaction once it has been fully displayed.
- {p} causes the display of text to be paused until the user clicks to continue, or until an auto-forward occurs. This allows text to be displayed incrementally. {p} does not take closing tags, and causes a newline to be inserted after the given text. The logic to handle pausing is implemented in the Character object, and may not work for other text widgets.
- {plain}text{/plain} makes the enclosed text plain, eliminating bold, italic, and underline styles
- {s}text{/s} makes the encolosed text struck-through. (new in 6.6.2)
- {size=spec}text{/size} changes the size of the text. The supplied spec may be a number, in which case it is the number of pixels high that the text will be. If it is a number preceded by a plus (like "+10"), it means to increase the size by that number of pixels, while if it is preceded by a minus it means to decrease.
- {u}text{/u} renders the enclosed text with an underline.
- {w} is similar to {p}, except that it does not cause a newline. We also support the form {w=number}, which pauses for number seconds. (For example, {w=.5} pauses for .5 seconds before continuing.
- {=style}text{/=style}} applies the named style to the enclosed text. Think of this as a way to design your own text tags. (new in 6.6.2)

The last {fast} tag is the one that is used. {nw}, {p}, and {w} tags only take effect if they are after the last {fast} tag in the text.

The following is an example of a say statement that uses many text tags. Use of this many text tags is not recommended in a high-quality game.

    "Using text tags, we can make text {size=+12}bigger{/size} or
     {size=-8}smaller{/size}. We can make it {b}bold{/b}, {i}italic{/i},
     or {u}underlined{/u}. We can even change its {color=#f88}color{/color}."

## Fonts

The Text displayable attempts to find an an appropriate font using information about the font name, boldness, italics, underline and size. This information is supplied to the Text displayable using style properties, but may then be modified using text tags. Ren'Py translates this into a font using the following algorithm.

- A (name, boldness, italics) triple is looked up in config.font_replacement_map. If present, it is expected to map to a triple giving replacement values for name, boldness, and italics. This lookup is not recursive, so only one lookup is performed. This lookup allows specific bold or italic font shapes to be used.
- If a SFont has been registered with the same name, size, boldness, italics, and underline, that SFont is used.
- Otherwise, Ren'Py interprets the font name as the filename of a truetype font. This filename is searched for in the searchpath and archives. If found, it is used as the font file.
- Otherwise, Ren'Py searches for a font with the given filename in the system font directory. If found, that file is used.
- Otherwise, Ren'Py interprets the filename as the name of a truetype font, which is loaded if found.

The truetype font loading code will automatically scale and underline the font as required. If you have not provided bold and italic font mappings, it will also artificially thicken and slant the font when necessary.

For best results, fonts should be truetype files that ship with the game. This ensures that required fonts are always present on the user's system.

## Image-Based Fonts

Along with the usual TrueType fonts, Ren'Py supports image-based SFonts, MudgeFonts, and BMFonts.

Image-based fonts have several advantages and several disadvantages. One of the advantages is that these fonts are bitmap-based, which means it is easy to create custom fonts and to find free examples (in contrast, the licenses of high quality TrueType fonts rarely permit redistribution). Also, since the fonts are images, it's possible to apply effects to them that Ren'Py would not otherwise support. The downsides of image-based fonts come from the fact that Ren'Py doesn't render them, but instead merely copies characters out of them. Because of this, one needs to supply another image to Ren'Py if one wants the font to be scaled, made bold, made italic, or underlined. Ren'Py will recolor the image fonts, with white being mapped to the supplied color, and other colors interpolated on a channel-by-channel basis.

Please note that you must register an image-based font for each combination of font, size, bold, italic, and underline your game uses. They can then be used by setting the font property of a style to the name of the font.

To use SFonts, they must first be registered with Ren'Py using the renpy.register_sfont function. For more information about SFonts, see [1].

To use MudgeFonts, they must be registered with the renpy.register_mudgefont function. For more information about MudgeFonts, see [2].

To use BMFonts, they must be registered with the renpy.register_bmfont function. For more information about BMFonts, see [3]. We recommend BMFont for bitmap fonts, as BMFonts support unicode and proper kerning.

Legal issues regarding the use of copyrighted outline fonts in creating image-based fonts are discussed in Bitmap Fonts and Copyright.

documentation index ◦ reference manual ◦ function index