Typography

The typography of text in Ren'Py is controlled by styles and text tags. Text tags appear inline within curly braces {}.
See Ren'Py text tags 

There are two types of tags: many have opening {x} and closing tags {/x} and come in pairs that most be opened and closed in order like HTML or XML elements. Others are self-closing, just {y} and stand on their own (unlike HTML or XML their tags do not have a trailing /).

Current Ren'Py documentation says that open text tags don't have to be closed and this happens automatically at the end of the text. Historically this has not always been the case, so it is probably good practice to explicitly close them.

Basic character styles

These apply to the characters between the tags. Multiple tags can be nested as needed.

TagFunction
{b}text{/b} The text is displayed in bold.
{i}text{/i} The text is displayed in italics.
{plain}text{/plain} The text is displayed normally, even if it is inside these other tags.
{s}text{/s} The text is displayed with a line through it so it is struck out.
{u}text{/u} The text is displayed underlined.

Font styles

TagFunction
{alpha=0.5}text{/alpha}
{alpha=+0.1}text{/alpha}
{alpha=-0.1}text{/alpha}
{alpha=*0.7}text{/alpha}
Controls the opacity (alpha) of the text. A value of 1.0 is completely opaque, 0.0 is completely transparent. The =+ and =- adjust the current value by the given amount. The =* version multiplies the current value by the given amount.
{color=#rbg}text{/color}
{color=#rbga}text{/color}
{color=#rrbbgg}text{/color}
{color=#rrbbggaa}text{/color}
Controls the colour of the text between the tags. The intensity of each colour is specified using either one or two hexadecimal digits, and an alpha value may be supplied in the same way.
{font=filenameOrAlias}text{/font} The text between the tags is rendered in the font given by the filename or alias.

A font filename should include the extension (such as .ttf). Ren'Py will look in:

  1. game
  2. game/fonts

To create an alias see Ren'Py Fonts 

{k=0.5}text{/k}
{k=-0.5}text{/k}
Adjusts the kerning  between adjacent characters by a number of pixels that can be specified as a floating point value which can be negative. Modern digital fonts include detailed kerning information so it is unlikely to have to fix kerning of particular character pairs this way. It can be used for visual effects.
{outlinecolor =#rbg}text{/outlinecolor }
{outlinecolor =#rbga}text{/outlinecolor }
{outlinecolor =#rrbbgg}text{/outlinecolor }
{outlinecolor =#rrbbggaa}text{/outlinecolor }
Controls the outline colour and drop shadows of the text between the tags. The intensity of each colour is specified using either one or two hexadecimal digits, and an alpha value may be supplied in the same way.
{size=12}text{/size}
{size=+2}text{/size}
{size=-2}text{/size}
{size=*1.5}text{/size}
Controls the size of the text in pixels. The =+ and =- adjust the current value by the given integer amount. The =* version multiplies the current value by the given float amount (rounded down). The default size is defined by gui.text_size in gui.rpy. There are two definitions, the default (e.g. 22), and a larger size (e.g. 30) used on mobile devices. Avoid using an absolute size if you are intending to have your game run on mobile devices.

Spacing

Two tags directly control spacing within the text:

TagFunction
{space=20} Adds a horizontal space of the given number of pixels.
{vspace=20} Adds a vertical space of the given number of pixels.

Self-voicing tags

A pair of tags control what is displayed and spoken while self-voicing is turned on. Using them both together allows alternatives to be presented and spoken for self-voicing.

TagFunction
{alt}text{/alt} The text between the alt tags is not rendered, but is spoken when self-voicing.
{noalt}text{/noalt} The text between the noalt tags is rendered, but it is not spoken even when self-voicing.

Hyperlinks

The tag {a=urlLikeThing}text{/a} creates a hyperlink-like piece of text that the player can click on, similar to HTML's own <a href="url"> element. For the purposes of this section the urlLikeThing is divided into the protocol (before the colon :) and the address that follows it. If no protocol is given the value of config.hyperlink_protocol is used. By default this is call_in_new_context.

ProtocolFunction
call The address is a Ren'Py label that is called.
call_in_new_context The address is a Ren'Py label that is called in a new context. See Ren'Py contexts 
jump The address is a Ren'Py label that is jumped to.
show The address is the name of a screen to show.
showmenu The address is the name of a game menu screen to show.

New protocol handlers can be added to the set config.hyperlink_handlers if needed.

If the protocol isn't one of the above the whole urlLikeThing is passed to the system browser. This would be the case for an actual url like https://renpy.org. Exactly what happens next is going to be system dependent. Typically the system browser will be launched (if it isn't already) and a new tab created to attempt to display the URL. Some care may be needed to correctly escape the characters in the urlLikeThing so they aren't subject to further interpretation by Ren'Py.

Inline images

An image tag is a self closing tag that is replaced by an image. For self-voicing images included should typically have alt text for them.

TagFunction
{image=filenameOrImageName} The image used should be the same height as the text (which can vary between desktop and mobile, see size). If a filename is used it should include the extension. Alternatively an image name defined using the image statement can be used.

Style references

A tag with no tag name but an = applies a style to the enclosed text.

TagFunction
{=styleName}text{/} The antialias, black_color, bold, color, font, italic, kerning, size, strikethrough, and underline properties of the named style will be applied to the text.

Ruby text (furigana)

Ruby text using the tags art, rb, rt and lenticular brackets is beyond the scope of this introduction.
See Ren'Py Ruby text 

Translation markers

When translating text there is not always a one-to-one mapping between words in one language and another. Care needs to be taken with homographs . To distinguish between different meanings a tag with a # can be added. The tag is does not appear or affect the text, but causes them to be treated as different strings for translation:


define englishIsConfusing = (
    _("lead{#element}"),     # The element with the symbol Pb
    _("lead{#pencil}"),      # Pencil lead is made from graphite
    _("lead{#leash}"),       # Keep your dogs on a lead
    _("lead{#cable}"),       # Make sure the lead is plugged in
    _("lead{#actor}"),       # Who was the lead in that film?
    _("lead{#clue}"),        # We need to follow this lead to crack the case
    _("lead{#dancing}"),     # Traditionally the male dancer is the lead
    _("lead{#winning}"),     # She's in the lead
    _("lead{#control}"),     # He'll be sure to lead the panel
    _("lead{#show}"),        # I'll go first and lead the way
)

Custom tags

It is also possible to define custom tags .

Opinions

There are a lot of options here for controlling the appearance of your text. Readability is key though so they need to be used judiciously. It's definitely a case of less-is-more: the occasional enhancement can really offer impact, but use them too much and you'll end up with something that looks like a Victorian play-bill or MySpace page.