This page is out of date

You've reached a page on the Ren'Py wiki. Due to massive spam, the wiki hasn't been updated in over 5 years, and much of the information here is very out of date. We've kept it because some of it is of historic interest, but all the information relevant to modern versions of Ren'Py has been moved elsewhere.

Some places to look are:

Please do not create new links to this page.


Multiple Language Support

This recipe will explain how to add multiple language support to a Ren'Py game. This support allows fonts and menu translations to be changed to support the language the user selects. We will also give two strategies for translating the text of the game.

Selecting a Default Language

The following code will specify a default language for the game. A default language is necessary so that Ren'Py can start up, and begin displaying the language chooser.

init -3 python:
    if persistent.lang is None:
        persistent.lang = "english"

    lang = persistent.lang

This code will set the default language to "english". It also stores the current language, whatever it's set to, into the lang variable, so that it can be accessed by init code.

Language Chooser

The language chooser allows the user to select a message. It's simply a Ren'Py menu, where each menu option sets persistent.lang to the appropriate value. The code following the menu then causes Ren'Py to restart, re-running init code.

label language_chooser:
    scene black
    
    menu:
        "{font=DejaVuSans.ttf}English{/font}":
            $ persistent.lang = "english"
        "{font=mikachan.ttf}日本語{/font}":
            $ persistent.lang = "japanese"

    $ renpy.utter_restart()

Note that this is just normal Ren'Py code, and so it's possible to change the scene command to display a different image.

As we'll want the user to be able to change the language from the main menu, we add a menu option to .

init python:
    config.main_menu.insert(3, (u'Language', "language_chooser", "True"))

Finally, we may want to automatically display the language chooser the first time the game starts up. This can be done by conditionally jumping to language_chooser from the splashscreen, using the following code:

label splashscreen:

    if not persistent.chose_lang:
        $ persistent.chose_lang = True
        jump language_chooser

    return

Language-Dependent Initialization

The lang variable can be used during initialization to change styles, images, configuration variables, and other properties in accordance with the chosen language.

It can be used inside init python blocks:

init python:

    if lang == "english":
        style.default.font = "DejaVuSans.ttf"

        e = Character("Eileen")

        # ...
        
    elif lang == "japanese":
        style.default.font = "mikachan.ttf"
        style.default.language = "eastasian"

        config.translations["Language"] = u"言語を選択"

        e = Character(u"光")

        # ...

It can also be used inside init blocks, to redefine images:

init:
    if lang == "english":
        image bg city = "city_en.jpg"
    elif lang == "japanese":
        image bg city = "city_jp.jpg"

Translating the Script

There are two approaches to translating the script: multi-path translation, and in-line translation. In the former, each language has its own blocks of script, while in the latter, the languages are intermixed.

Multi-Path Translation

The key to multi-path translation is branching based on the language, to a separate set of labels for each language. This branching is best done at the start statement, which might look like:

label start:
    $ game_lang = lang
    
    if lang == "english":
         jump start_en
    else:
         jump start_jp


label start_en:
    "It was a dark and stormy night..."

    e "But we're inside, so it's okay."

    # ...

label start_jp:
    "それは暗い嵐の夜だった..."

    e "しかし、我々の中なので、大丈夫だ。"

    # ...

Note that the multi-path translation lets you use the same characters (in this case, the narrator) in both languages.

A limitation of the multi-path approach is that it cannot load a game saved in a different language. To work around this, we store lang in game_lang when starting a new game. We then use an after_load hook to check that the languages match, and report an error if they do not.

label after_load:
    if lang == game_lang:
        return

    if lang == "english":
        "The language of the save file is not the current selected language."
    elif lang == "japanese":
        "ファイルを保存した言語は、現在の選択された言語ではありません。"

    $ renpy.full_restart()

In-line translation

In-line translation works by defining characters that display text only if a given language is selected.

init python:
    en = Character(None, condition='lang == "english"')
    jp = Character(None, condition='lang == "japanese"')

    en_e = Character("Eileen", condition='lang == "english"')
    jp_e = Character(u"光", condition='lang == "japanese"')

The script can then give lines in each language.

label start:
    en "It was a dark and stormy night..."

    jp "それは暗い嵐の夜だった..."

    en_e "But we're inside, so it's okay."

    jp_e "しかし、我々の中なので、大丈夫だ。"

    # ...

The in-line approach supports switching between languages. The downside to this approach is that each line of dialogue must specify both the language and the character.