Implementing Runtime Language Switching in Ren'Py Visual Novels
When Ren'Py language selectors fail to switch dialogue text, proper translate block configuration and UTF-8 catalog encoding are the fix. This guide covers the procedure and verification steps.
11 Jul 2025, 18:36 UTC

Ren'Py developers often encounter a frustrating gap: the language selector in the launcher appears functional, but on-screen text stays locked in the source language after switching. This usually stems from misconfigured translate blocks, catalog encoding mismatches, or a runtime context that hasn't refreshed the translation map. The useful takeaway is that by correctly placing translate blocks, ensuring UTF-8 catalog files, and using the init-python language-switch API, every string updates dynamically without manual extraction. This guide walks through exactly that fix, drawing on Ren'Py's built-in internationalization system.
Desired Outcome
Configure a Ren'Py project so that the in-game language selector switches every translate-block string at runtime, and that non-ASCII characters display correctly across all supported languages without falling back to the source language. The solution relies on Ren'Py's automatic catalog generation from translate blocks, proper file encoding, and the runtime language API.
- A Ren'Py project (version 8.x or later; the translate-block catalog system is the focus of this guide)
- A text editor that preserves UTF-8 encoding without a byte-order mark (VS Code, Notepad++, Sublime Text)
- Familiarity with Ren'Py's .rpy script syntax and the project's game/ directory structure
- Access to the Ren'Py launcher to enable the language selector in preferences
Focused Procedure
- Replace static text with translate blocks. In any .rpy file, wrap dialogue or UI strings using the translate syntax: the source language tag followed by the string. For example,
translate english: Hello, world!tells Ren'Py to manage this string in the message catalog. You may use any language tag your project supports;englishis the default source language. - Generate the message catalog. When the project runs with the language selector enabled, Ren'Py automatically creates a catalog file, typically
game/translations.rpyc, or a path specified in project preferences. Ensure the catalog file resides in the expected location; if using a custom path, configure it before the first run. - Verify UTF-8 encoding. Open the catalog file in a UTF-8-aware editor and confirm that all string entries are valid UTF-8. Non-UTF-8 bytes will cause Ren'Py to silently fall back to the source language or raise a runtime error when non-ASCII characters appear in dialogue. If the file was saved with a different encoding, re-save it as UTF-8 (no BOM).
- Add runtime language switching. In an init python block, set the active language code and reload the translation catalog so that subsequent text renders in the newly selected language. Example:
init python: renpy.translate_language = 'fr'; renpy.reload_translations() - Subsequent text using translate blocks will render in French if a French catalog entry exists.
Expected Checks
- Open the Ren'Py launcher, navigate to Preferences > Language, and select a language other than the default. Start a new game or load a save.
- Confirm that every translate-block string updates to the selected language. If some strings remain in the source language, the catalog may be missing an entry for that string or the language code may not match.
- Inspect the generated catalog file. Using a text editor, open game/translations.rpyc (or the custom path) and look for the language-specific entry block. Expected format includes language codes mapped to string identifiers; if entries are absent or malformed, the fallback behavior occurs.
Recovery Options
If the language switcher stops working after a change:
- Delete or rename the catalog file (e.g.,
translations.rpyc) and restart the project; Ren'Py will regenerate it from the .rpy scripts, which can resolve corruption or encoding mismatches. - Re-encode the catalog file to UTF-8 if non-UTF-8 bytes were introduced. Save the file with UTF-8 (no BOM) encoding, then restart.
- Migrate from the older
languagestatement syntax totranslateblocks, as the older syntax may not participate in the automatic catalog generation flow and can cause the language switcher to ignore affected strings.
After applying any recovery step, repeat the expected checks to confirm the fix.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.