Posted April 11, 2019 by MysteryCorgi
#renpy #sourcecode
In this tutorial I'll be discussing how to add a language option to your Ren'Py game. This is solely for the implementation of a translation, NOT to generate a translation from the script. There is no automated translation button built into Ren'Py, and I highly recommend against using machine translation for official game releases, as the practice is highly frowned upon and has substandard results.
When working for Afterthought Studios, I worked with a team of translators to make the Russian translations of Afterthoughi's games. I then implemented the translations into the scripts. However, the process can be confusing when you only do it once every six-to-twelve months or so. Thus I made a guide for myself some time back to avoid confusion. I've decided to share and update the tutorial for anyone who might find it useful.
WARNING: As a heads up, this code was written for a version of Ren'Py that is now long out of date. It may no longer work as intended. I'm leaving this here so folks can use it as a reference point to get familiar with the process.
To get a basic understanding of the translation framework built into Ren'Py, I recommend reading this Documentation page.
Once you have your game's script completed in the original language (I'll be using English in the example), you will want to generate a blank script for translation into another language (Russian, in this example.) To do this, you will select the project in The Ren'py Launcher and go to the Actions menu, where you will click "Generate Translations."
This will take you to a second menu, in which you will input the name of the language you are generating scripts for. Be sure to use all lowercase letters.
Now press "Generate Translation," making sure to have the box next to 'generate empty strings for translations' checked.
Ren'Py will generate blank files for your project, which can take a few moments depending on how large your project is. Once it's done you'll find the blank scripts for translation in your project's "game" folder, like so:
[Your Game]/game/tl/russian
Your files will be ready for the translation to be input. This will be done manually. The team we worked with input the translation into the script as they worked, so everything could be matched up and double checked. Some programmers receive translations via spreadsheets, some scripters input the translations themselves. It all depends on what you/your team and the translator's preferences are.
Here's what one of the scripts looks like before the translation is filled in.
You can see that the contents of original script (in this case, the English text) is available in comments. The lines above the comments are what allows Ren'py to replace the English line with the Russian line, when the game is played in Russian. Below the comment is an empty dialogue line with the appropriate character label defined, which will eventually be filled with the translation.
# game/script.rpy <--file from which the lines are taken translate language script_#######: #<--string for replacing original script with translation # n "Commented version of line from original script." n "Translated version of line."
Here is what the same script looks like after the translation is implemented:
!! Important !!
Be sure that any strings like the following:
translate russian script1_f978b7f5:
match the capitalization of your game folders. If the folder is "/game/tl/russian" make sure "russian" is always lowercase, or you might get weird issues. At one point I had an error in which only the menus appeared translated, but all of the text was still in English. It was because of a mismatch in capitalization.
Another issue that sometimes crops up has to do with how characters are defined. When Ren'Py converts a script into an empty script to be filled with translations, it will automatically convert some lines that won't be translated in the same manner as the rest of the script.
For example, the script we generated for Forgotten, Not Lost included the character definitions, which our translators naturally translated.
# game/script.rpy:79 translate russian start_3989d14d: #define mad1 = Character("Madalene") define mad1 = Character("Мадалена")
But this caused the translated names to override the names in English, no matter which language you played the game in, due to how Ren'Py works. To prevent this, you must do the following:
define e = Character(_('Eileen'), color="#c8ffc8")
You will find this in the scripts of the Russian translation:
translate russian strings: old "Eileen" new "Эйлин"
In the end, our Russian Strings looked like this:
and the error was resolved.
Now that the above is done, you should have a functioning translated script. Be sure that your UI is also translated. If you use imagemaps for your GUI, you'll want to have translated versions of any UI images and add them to your translated file folder, like so:
[Your Game]/game/tl/russian/images
Now, you'll need a way to allow your players to select the language they want to play in. For Afterthought Studio's games, I had the option pop up in a splash screen upon opening the game. If the player has already made their selection, the splash screen won't pop up again.
To do this, I used the following code in options.rpy:
init -3 python: if persistent.lang is None: persistent.lang = "english" lang = persistent.lang init python: config.main_menu.insert(3, (u'Language', "language_chooser", "True")) init python: if lang == "english": style.default.font = "font_name_here_1.ttf" #english font here elif lang == "russian": style.default.font = "font_name_here_2.ttf" #russian font here
Please note that not all fonts will be compatible with a given language, so you may need to change the font depending on the language selection.
If you want players to be able to choose the language upon opening the game, put the following in script.rpy:
label language_chooser: scene black menu: "{font=Arimo-Regular.ttf}English{/font}": $ renpy.change_language(None) "{font=Arimo-Regular.ttf}Русский{/font}": $ renpy.change_language("russian") $ renpy.utter_restart() #alternatively, use "return" if you don't want to go to the main menu.
And in case your players want to switch languages after starting the game:
Put the following in your imagemap for the Main Menu or Options Menu for screens.rpy:
hotspot(#,#,#,#) action ShowMenu("language_chooser") #insert coordinates appropriately
This is how I've implemented translations in the past. As Ren'Py updates, I'll try to improve on this tutorial as I am able to.
This code is compatible with SteamAPI, so you can use it in conjunction with achievements and such. (ie. having an achievement unlock when players change the language.)
I hope this helps anyone who might need it. If you have any questions, please feel free to leave a comment and I will try to get back to you.
If you found this helpful at all, please consider leaving me a token of your appreciation, if you are able to.