renpy/doc/translation.html
2023-01-18 23:13:55 +01:00

777 lines
49 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Translation &#8212; Ren&#39;Py Documentation</title>
<link rel="stylesheet" href="_static/renpydoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-3.3.6/css/bootstrap-theme.min.css" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="_static/js/jquery-fix.js"></script>
<script type="text/javascript" src="_static/bootstrap-3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="_static/bootstrap-sphinx.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Displayables" href="displayables.html" />
<link rel="prev" title="Text" href="text.html" />
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
</head><body>
<div id="navbar" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">
Ren&#39;Py Documentation</a>
<span class="navbar-text navbar-version pull-left"><b>7.5.3</b></span>
</div>
<div class="collapse navbar-collapse nav-collapse">
<ul class="nav navbar-nav">
<li><a href="https://www.renpy.org">Home Page</a></li>
<li><a href="https://www.renpy.org/doc/html/">Online Documentation</a></li>
<li class="dropdown globaltoc-container">
<a role="button"
id="dLabelGlobalToc"
data-toggle="dropdown"
data-target="#"
href="index.html">Site <b class="caret"></b></a>
<ul class="dropdown-menu globaltoc"
role="menu"
aria-labelledby="dLabelGlobalToc"><ul>
<li class="toctree-l1"><a class="reference internal" href="quickstart.html">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="gui.html">GUI Customization Guide</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="language_basics.html">Language Basics</a></li>
<li class="toctree-l1"><a class="reference internal" href="label.html">Labels &amp; Control Flow</a></li>
<li class="toctree-l1"><a class="reference internal" href="dialogue.html">Dialogue and Narration</a></li>
<li class="toctree-l1"><a class="reference internal" href="displaying_images.html">Displaying Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="menus.html">In-Game Menus</a></li>
<li class="toctree-l1"><a class="reference internal" href="python.html">Python Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="conditional.html">Conditional Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="audio.html">Audio</a></li>
<li class="toctree-l1"><a class="reference internal" href="movie.html">Movie</a></li>
<li class="toctree-l1"><a class="reference internal" href="voice.html">Voice</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="text.html">Text</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Translation</a></li>
<li class="toctree-l1"><a class="reference internal" href="displayables.html">Displayables</a></li>
<li class="toctree-l1"><a class="reference internal" href="transforms.html">Transforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="transitions.html">Transitions</a></li>
<li class="toctree-l1"><a class="reference internal" href="atl.html">Animation and Transformation Language</a></li>
<li class="toctree-l1"><a class="reference internal" href="matrixcolor.html">Matrixcolor</a></li>
<li class="toctree-l1"><a class="reference internal" href="layeredimage.html">Layered Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="3dstage.html">3D Stage</a></li>
<li class="toctree-l1"><a class="reference internal" href="live2d.html">Live2D Cubism</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="style.html">Styles</a></li>
<li class="toctree-l1"><a class="reference internal" href="style_properties.html">Style Properties</a></li>
<li class="toctree-l1"><a class="reference internal" href="screens.html">Screens and Screen Language</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_actions.html">Screen Actions, Values, and Functions</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_special.html">Special Screen Names</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_optimization.html">Screen Language Optimization</a></li>
<li class="toctree-l1"><a class="reference internal" href="config.html">Configuration Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="preferences.html">Preference Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="store_variables.html">Store Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="mouse.html">Custom Mouse Cursors</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="launcher.html">Launcher</a></li>
<li class="toctree-l1"><a class="reference internal" href="developer_tools.html">Developer Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="director.html">Interactive Director</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="nvl_mode.html">NVL-Mode Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="input.html">Text Input</a></li>
<li class="toctree-l1"><a class="reference internal" href="side_image.html">Side Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="rooms.html">Image Gallery, Music Room, and Replay Actions</a></li>
<li class="toctree-l1"><a class="reference internal" href="drag_drop.html">Drag and Drop</a></li>
<li class="toctree-l1"><a class="reference internal" href="sprites.html">Sprites</a></li>
<li class="toctree-l1"><a class="reference internal" href="keymap.html">Customizing the Keymap</a></li>
<li class="toctree-l1"><a class="reference internal" href="achievement.html">Achievements</a></li>
<li class="toctree-l1"><a class="reference internal" href="history.html">Dialogue History</a></li>
<li class="toctree-l1"><a class="reference internal" href="multiple.html">Multiple Character Dialogue</a></li>
<li class="toctree-l1"><a class="reference internal" href="splashscreen_presplash.html">Splashscreen and Presplash</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="statement_equivalents.html">Statement Equivalents</a></li>
<li class="toctree-l1"><a class="reference internal" href="save_load_rollback.html">Saving, Loading, and Rollback</a></li>
<li class="toctree-l1"><a class="reference internal" href="persistent.html">Persistent Data</a></li>
<li class="toctree-l1"><a class="reference internal" href="trans_trans_python.html">Transforms and Transitions in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="gui_advanced.html">Advanced GUI</a></li>
<li class="toctree-l1"><a class="reference internal" href="screen_python.html">Screens and Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="modes.html">Modes</a></li>
<li class="toctree-l1"><a class="reference internal" href="cdd.html">Creator-Defined Displayables</a></li>
<li class="toctree-l1"><a class="reference internal" href="cds.html">Creator-Defined Statements</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom_text_tags.html">Custom Text Tags</a></li>
<li class="toctree-l1"><a class="reference internal" href="character_callbacks.html">Character Callbacks</a></li>
<li class="toctree-l1"><a class="reference internal" href="file_python.html">File Access</a></li>
<li class="toctree-l1"><a class="reference internal" href="color_class.html">Color Class</a></li>
<li class="toctree-l1"><a class="reference internal" href="matrix.html">Matrix</a></li>
<li class="toctree-l1"><a class="reference internal" href="model.html">Model-Based Rendering</a></li>
<li class="toctree-l1"><a class="reference internal" href="other.html">Other Functions and Variables</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="build.html">Building Distributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="updater.html">Web Updater</a></li>
<li class="toctree-l1"><a class="reference internal" href="android.html">Android</a></li>
<li class="toctree-l1"><a class="reference internal" href="chromeos.html">Chrome OS/Chromebook</a></li>
<li class="toctree-l1"><a class="reference internal" href="ios.html">iOS</a></li>
<li class="toctree-l1"><a class="reference internal" href="iap.html">In-App Purchasing</a></li>
<li class="toctree-l1"><a class="reference internal" href="gesture.html">Gestures</a></li>
<li class="toctree-l1"><a class="reference internal" href="raspi.html">Raspberry Pi</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="security.html">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="problems.html">Dealing with Problems</a></li>
<li class="toctree-l1"><a class="reference internal" href="environment_variables.html">Environment Variables</a></li>
<li class="toctree-l1"><a class="reference internal" href="self_voicing.html">Self-Voicing</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="editor.html">Text Editor Integration</a></li>
<li class="toctree-l1"><a class="reference internal" href="skins.html">Skins</a></li>
<li class="toctree-l1"><a class="reference internal" href="translating_renpy.html">Translating Ren'Py</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog (Ren'Py 7.x-)</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog6.html">Changelog (Ren'Py 6.11 - 6.99)</a></li>
<li class="toctree-l1"><a class="reference internal" href="incompatible.html">Incompatible Changes</a></li>
<li class="toctree-l1"><a class="reference internal" href="distributor.html">Distributor Notes</a></li>
<li class="toctree-l1"><a class="reference internal" href="license.html">License</a></li>
<li class="toctree-l1"><a class="reference internal" href="credits.html">Credits</a></li>
<li class="toctree-l1"><a class="reference internal" href="sponsors.html">Ren'Py Development Sponsors</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="thequestion.html">Script of The Question</a></li>
<li class="toctree-l1"><a class="reference internal" href="thequestion_nvl.html">NVL-mode script for The Question</a></li>
</ul>
</ul>
</li>
</ul>
<form class="navbar-form navbar-right" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search" />
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3">
<div id="sidebar" class="bs-sidenav" role="complementary"><ul>
<li><a class="reference internal" href="#">Translation</a><ul>
<li><a class="reference internal" href="#primary-and-alternate-languages">Primary and Alternate Languages</a></li>
<li><a class="reference internal" href="#generating-translation-files">Generating Translation Files</a></li>
<li><a class="reference internal" href="#translating-dialogue">Translating Dialogue</a><ul>
<li><a class="reference internal" href="#translation-units">Translation Units</a></li>
<li><a class="reference internal" href="#translate-statement">Translate Statement</a></li>
<li><a class="reference internal" href="#more-complex-translations">More Complex Translations</a></li>
<li><a class="reference internal" href="#tips">Tips</a></li>
</ul>
</li>
<li><a class="reference internal" href="#menu-and-string-translations">Menu and String Translations</a><ul>
<li><a class="reference internal" href="#translating-substitutions">Translating Substitutions</a></li>
<li><a class="reference internal" href="#extracting-and-merging-string-translations">Extracting and Merging String Translations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#image-and-file-translations">Image and File Translations</a></li>
<li><a class="reference internal" href="#style-translations">Style Translations</a></li>
<li><a class="reference internal" href="#default-language">Default Language</a></li>
<li><a class="reference internal" href="#translation-actions-functions-and-variables">Translation Actions, Functions, and Variables</a></li>
<li><a class="reference internal" href="#unsanctioned-translations">Unsanctioned Translations</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="col-md-9 content">
<div class="section" id="translation">
<span id="id1"></span><h1>Translation<a class="headerlink" href="#translation" title="Permalink to this headline"> link</a></h1>
<p>Ren'Py contains a comprehensive framework for the translation of
visual novels. There are four main types of things that can be
translated:</p>
<dl class="docutils">
<dt>Dialogue</dt>
<dd>The main dialogue of the script can be translated, including a
provision for splitting, combining, omitting, and reordering
lines.</dd>
<dt>Menus and Interface Strings</dt>
<dd>All interface text can be translated.</dd>
<dt>Images and Files</dt>
<dd>It's possible to include variant images and other files that are
used when a language is selected.</dd>
<dt>Styles</dt>
<dd>It's possible to customize styles based on the language, so that
the game can automatically switch to a font appropriate for the
language that was chosen.</dd>
</dl>
<p>Ren'Py's translation support is currently focused on sanctioned
translations, where the game's creators either release the game
scripts to the translator or create translation templates
themselves. Support for unsanctioned translations is more limited.</p>
<div class="section" id="primary-and-alternate-languages">
<h2>Primary and Alternate Languages<a class="headerlink" href="#primary-and-alternate-languages" title="Permalink to this headline"> link</a></h2>
<p>Ren'Py expects each game to be written in a single primary
language. This is called the None language, regardless of what
language it actually is. (For example, if the game was written in
English, English will be the None language.)</p>
<p>Alternate languages are referred to by names which can double as
Python identifiers (starts with a letter or underscore, followed by
letters, numbers, and underscores).</p>
<p>When the None language is selected, most of Ren'Py's translation
functionality is disabled, with the notable exception of Renpy's
internal built-in strings, from the accessibility menu for example.
Theses strings are not found in your project's code, yet they will
still be included in the distributed version of the game. You can
find them in the <code class="docutils literal notranslate"><span class="pre">game/tl/None/common.rpym</span></code> file, whose only
purposes are 1) to provide translations to these strings when the None
language is not english, and 2) to allow creators to customize these
strings for their game.</p>
<p>The language of the launcher at the time when the project is
created will be the language this file will initially translate the
internal strings to.</p>
</div>
<div class="section" id="generating-translation-files">
<h2>Generating Translation Files<a class="headerlink" href="#generating-translation-files" title="Permalink to this headline"> link</a></h2>
<p>When the project scripts are available, translation files can be
generated by opening the project in the Ren'Py Launcher, and choosing
&quot;Generate Translations&quot;. The launcher will prompt you for the name of
the language to generate, and will then proceed to create or update
the translation files.</p>
<p>The translation files live in directories underneath the &quot;tl&quot;
subdirectory of the game directory. For example, if you create a
piglatin translation of the tutorial project, translation files will
be placed under <code class="docutils literal notranslate"><span class="pre">tutorial/game/tl/piglatin</span></code>.</p>
<p>There will be one translation file created per game script file. The
common.rpy file will also be created to contain translations of
strings that are common to all games made using Ren'Py.</p>
</div>
<div class="section" id="translating-dialogue">
<h2>Translating Dialogue<a class="headerlink" href="#translating-dialogue" title="Permalink to this headline"> link</a></h2>
<p>As Ren'Py is a visual novel engine, we expect most translation to
involve dialogue. Ren'Py includes a flexible framework that allows
dialogue to be split, combined, reordered, and omitted entirely.</p>
<div class="section" id="translation-units">
<h3>Translation Units<a class="headerlink" href="#translation-units" title="Permalink to this headline"> link</a></h3>
<p>The fundamental unit of translation is a block of zero or more
translatable statements, optionally followed by a single say
statement. Translatable statements are the voice and nvl statements. For example,
take the following game:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">label</span> <span class="n">start</span><span class="p">:</span>
<span class="n">e</span> <span class="s2">&quot;Thank you for taking a look at the Ren&#39;Py translation framework.&quot;</span>
<span class="k">show</span> <span class="n">eileen</span> <span class="n">happy</span>
<span class="n">e</span> <span class="s2">&quot;We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;Pretty much everything your game needs!&quot;</span>
</pre></div>
</div>
<p>This is broken up into multiple translation units. Each unit has an
identifier assigned to it, with the identifier being generated from
the label preceding the unit, and the statements inside the unit. (If
multiple units would be assigned the same translation number, a serial
number to the second and later units to distinguish them.)</p>
<p>In the example above, the first unit generated is assigned the identifier
start_636ae3f5, and contains the statement:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="s2">&quot;Thank you for taking a look at the Ren&#39;Py translation framework.&quot;</span>
</pre></div>
</div>
<p>The second unit is given the identifier start_bd1ad9e1m and contains:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="s2">&quot;We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles.&quot;</span>
</pre></div>
</div>
<p>The third unit has the identifier start_9e949aac, and contains:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="s2">&quot;Pretty much everything your game needs!&quot;</span>
</pre></div>
</div>
<p>These units are created automatically by Ren'Py when the game script
is loaded.</p>
</div>
<div class="section" id="translate-statement">
<h3>Translate Statement<a class="headerlink" href="#translate-statement" title="Permalink to this headline"> link</a></h3>
<p>When you generate translations for a language, Ren'Py will generate a
translate statement corresponding to each translation unit. When
translating the script above, Ren'Py will generate:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="c1"># game/script.rpy:95</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_636ae3f5</span><span class="p">:</span>
<span class="c1"># e &quot;Thank you for taking a look at the Ren&#39;Py translation framework.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># game/script.rpy:99</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_bd1ad9e1</span><span class="p">:</span>
<span class="c1"># e &quot;We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># game/script.rpy:101</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_9e949aac</span><span class="p">:</span>
<span class="c1"># e &quot;Pretty much everything your game needs!&quot;</span>
<span class="n">e</span> <span class="s2">&quot;&quot;</span>
</pre></div>
</div>
<p>This can be translated by editing the generated files. A finished
translation might look like:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="c1"># game/script.rpy:95</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_636ae3f5</span><span class="p">:</span>
<span class="c1"># e &quot;Thank you for taking a look at the Ren&#39;Py translation framework.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;Ankthay ouyay orfay akingtay away ooklay atway ethay En&#39;Pyray anslationtray ameworkfray.&quot;</span>
<span class="c1"># game/script.rpy:99</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_bd1ad9e1</span><span class="p">:</span>
<span class="c1"># e &quot;We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;Eway aimway otay ovidepray away omprehensivecay ameworkfray orfay anslatingtray ialogueday, ingsstray, imagesway, andway ylesstay.&quot;</span>
<span class="c1"># game/script.rpy:101</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_9e949aac</span><span class="p">:</span>
<span class="c1"># e &quot;Pretty much everything your game needs!&quot;</span>
<span class="n">e</span> <span class="s2">&quot;Ettypray uchmay everythingway ouryay amegay eedsnay!&quot;</span>
</pre></div>
</div>
<p>When a block in the main script is encountered, Ren'Py checks to see
if a translate statement corresponding to that block exists. If so, it
executes the translate statement instead of the translated block,
showing the user the translation.</p>
</div>
<div class="section" id="more-complex-translations">
<h3>More Complex Translations<a class="headerlink" href="#more-complex-translations" title="Permalink to this headline"> link</a></h3>
<p>Translate statements do not need to contain 1-to-1 translations of the
original language. For example, a long line could be split:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="c1"># game/script.rpy:99</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_bd1ad9e1</span><span class="p">:</span>
<span class="c1"># e &quot;We aim to provide a comprehensive framework for translating dialogue, strings, images, and styles.&quot;</span>
<span class="n">e</span> <span class="s2">&quot;Eway aimway otay ovidepray away omprehensivecay ameworkfray...&quot;</span>
<span class="n">e</span> <span class="s2">&quot;...orfay anslatingtray ialogueday, ingsstray, imagesway, andway ylesstay.&quot;</span>
</pre></div>
</div>
<p>Or a statement can be removed, by replacing it with the <code class="docutils literal notranslate"><span class="pre">pass</span></code> statement:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="c1"># game/script.rpy:101</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_9e949aac</span><span class="p">:</span>
<span class="c1"># e &quot;Pretty much everything your game needs!&quot;</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>It's also possible to run non-dialogue statements, such as
conditionals or Python. For example, we can translate:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="s2">&quot;You scored [points] points!&quot;</span>
</pre></div>
</div>
<p>into:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="c1"># game/script.rpy:103</span>
<span class="k">translate</span> <span class="n">piglatin</span> <span class="n">start_36562aba</span><span class="p">:</span>
<span class="c1"># e &quot;You scored [points] points!&quot;</span>
<span class="k">$</span> <span class="n">latin_points</span> <span class="o">=</span> <span class="n">to_roman_numerals</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
<span class="n">e</span> <span class="s2">&quot;Ouyay oredscay [latin_points] ointspay!&quot;</span>
</pre></div>
</div>
<p>Sometimes it might be desirable to change a line of
dialogue in the original language, without requiring
the translators to retranslate the line. For example,
a typo in English is unlikely to have surved the process
of being translated into Russian.</p>
<p>This can be done by including an <code class="docutils literal notranslate"><span class="pre">id</span></code> clause as part of the
say statement, giving the translation ID to use for this
statement. For example:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">label</span> <span class="n">start</span><span class="p">:</span>
<span class="n">e</span> <span class="s2">&quot;This used to have a typo.&quot;</span> <span class="na">id</span> <span class="n">start_61b861a2</span>
</pre></div>
</div>
</div>
<div class="section" id="tips">
<h3>Tips<a class="headerlink" href="#tips" title="Permalink to this headline"> link</a></h3>
<p>Be very careful when changing dialogue that has been translated,
especially when that dialogue is repeated in more than one place
inside a label. In some cases, it may be necessary to assign
a translation identifier directly, using a statement like:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="kc">None</span> <span class="n">mylabel_03ac197e_1</span><span class="p">:</span>
<span class="s2">&quot;...&quot;</span>
</pre></div>
</div>
<p>Adding labels can also confuse the translation process. To prevent
this, labels that are given the <code class="docutils literal notranslate"><span class="pre">hide</span></code> clause are ignored when generating
translations.:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">label</span> <span class="n">ignored_by_translation</span> <span class="k">hide</span><span class="p">:</span>
<span class="s2">&quot;...&quot;</span>
</pre></div>
</div>
<p>While translation blocks may include Python, this Python should not
have side effects visible outside of the block. That's because
changing languages will restart the translation block, causing the
side effects to occur multiple times.</p>
</div>
</div>
<div class="section" id="menu-and-string-translations">
<span id="string-translations"></span><h2>Menu and String Translations<a class="headerlink" href="#menu-and-string-translations" title="Permalink to this headline"> link</a></h2>
<p>In addition to dialogue, Ren'Py is able to translate text found in
menus and other strings. Interface translations are a 1-to-1
substitution. Wherever a string is found, it will be replaced by a
single replacement.</p>
<p>When generating translations, Ren'Py will scan the script files for
menus, and for strings enclosed inside the <code class="docutils literal notranslate"><span class="pre">_()</span></code> function. It will then
place the strings inside a <code class="docutils literal notranslate"><span class="pre">translate</span> <span class="pre">strings</span></code> block. For example, if we
have the following script:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Character</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s2">&quot;Eileen&quot;</span><span class="p">))</span>
<span class="c1"># ...</span>
<span class="k">menu</span><span class="p">:</span>
<span class="s2">&quot;Go West&quot;</span><span class="p">:</span>
<span class="c1"># ...</span>
<span class="s2">&quot;Head East&quot;</span><span class="p">:</span>
<span class="c1"># ...</span>
</pre></div>
</div>
<p>Ren'Py will generate:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="n">piglatin</span> <span class="k">strings</span><span class="p">:</span>
<span class="k">old</span> <span class="s2">&quot;Eileen&quot;</span>
<span class="k">new</span> <span class="s2">&quot;&quot;</span>
<span class="k">old</span> <span class="s2">&quot;Go West&quot;</span>
<span class="k">new</span> <span class="s2">&quot;&quot;</span>
<span class="k">old</span> <span class="s2">&quot;Head East&quot;</span>
<span class="k">new</span> <span class="s2">&quot;&quot;</span>
</pre></div>
</div>
<p>Which can then be translated:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="n">piglatin</span> <span class="k">strings</span><span class="p">:</span>
<span class="k">old</span> <span class="s2">&quot;Eileen&quot;</span>
<span class="k">new</span> <span class="s2">&quot;Eileenway&quot;</span>
<span class="k">old</span> <span class="s2">&quot;Go West&quot;</span>
<span class="k">new</span> <span class="s2">&quot;Ogay Estway&quot;</span>
<span class="k">old</span> <span class="s2">&quot;Head East&quot;</span>
<span class="k">new</span> <span class="s2">&quot;Eadhay Eastway&quot;</span>
</pre></div>
</div>
<p>String translations are also applied to dialogue strings that are not
translated as dialogue.</p>
<p>When the same string is used in multiple places, the string can
be distinguished using the {#...} text tag. Even though they display the
same, Ren'Py considers all of these distinct strings for the purpose
of translation:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="s2">&quot;New&quot;</span>
<span class="s2">&quot;New{#project}&quot;</span>
<span class="s2">&quot;New{#game}&quot;</span>
<span class="s2">&quot;New{#playlist}&quot;</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">translate</span> <span class="pre">strings</span></code> statement can also be used to translate the None
language. This can be used to when the game is written in a non-English
language, to translate the Ren'Py user interface.</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="kc">None</span> <span class="k">strings</span><span class="p">:</span>
<span class="k">old</span> <span class="s2">&quot;Start Game&quot;</span>
<span class="k">new</span> <span class="s2">&quot;Artstay Amegay&quot;</span>
</pre></div>
</div>
<div class="section" id="translating-substitutions">
<h3>Translating Substitutions<a class="headerlink" href="#translating-substitutions" title="Permalink to this headline"> link</a></h3>
<p>String substitutions can be translated using the <code class="docutils literal notranslate"><span class="pre">!t</span></code> conversion
flag. So the following will be translatable using a combination of
the dialogue and string translation systems:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">mood_points</span> <span class="o">&gt;</span> <span class="mi">5</span><span class="p">:</span>
<span class="k">$</span> <span class="n">mood</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;great&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">$</span> <span class="n">mood</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;awful&quot;</span><span class="p">)</span>
<span class="s2">&quot;I&#39;m feeling [mood!t].&quot;</span>
</pre></div>
</div>
</div>
<div class="section" id="extracting-and-merging-string-translations">
<span id="extract-merge-translations"></span><h3>Extracting and Merging String Translations<a class="headerlink" href="#extracting-and-merging-string-translations" title="Permalink to this headline"> link</a></h3>
<p>String translations can be extracted from one project, and moved to
another. This is a multiple-step process:</p>
<ul class="simple">
<li>Select the source project, and choose &quot;Generate Translations&quot;.</li>
<li>Enter the language to extract, and click &quot;Extract String Translations&quot;.</li>
<li>Return to the main menu, select the target project, and choose &quot;Generate Translations&quot;.</li>
<li>Enter the language to merge to (often the same language), and choose &quot;Merge String Translations&quot;.</li>
</ul>
<p>There are a couple of options that control merging:</p>
<dl class="docutils">
<dt>Replace existing translations</dt>
<dd>When checked, this will cause non-trivial existing translations (those
that are not empty or the source string) to be replaced. By default,
merging will refuse to overwrite non-trivial translations that already
exist.</dd>
<dt>Reverse languages</dt>
<dd>Reverses the strings before merging. This can be used, for example,
to use a set of English -&gt; Russian translations to create a
Russian -&gt; English translation.</dd>
</dl>
</div>
</div>
<div class="section" id="image-and-file-translations">
<h2>Image and File Translations<a class="headerlink" href="#image-and-file-translations" title="Permalink to this headline"> link</a></h2>
<p>When translating a game, it may be necessary to replace a file
with a translated version. For example, if an image contains text, it
might make sense to replace it with a version of the image where the
text is in another language.</p>
<p>Ren'Py handles this by looking in the translation directory for the
image. For example, if the &quot;piglatin&quot; language is in use, and
&quot;library.png&quot; is loaded, Ren'Py will use &quot;game/tl/piglatin/library.png&quot;
in preference to &quot;game/library.png&quot;.</p>
<p>If the file is in a directory under game, that directory should be
included underneath the language. For example, the file &quot;game/gui/main_menu.png&quot;
can be translated by creating the file &quot;game/tl/piglatin/gui/main_menu.png&quot;.</p>
</div>
<div class="section" id="style-translations">
<h2>Style Translations<a class="headerlink" href="#style-translations" title="Permalink to this headline"> link</a></h2>
<p>It may be necessary to change styles especially font-related
styles when translating a game. Ren'Py handles this with <code class="docutils literal notranslate"><span class="pre">translate</span>
<span class="pre">style</span></code> blocks and <code class="docutils literal notranslate"><span class="pre">translate</span> <span class="pre">python</span></code> blocks. These blocks can
change language-related variables and styles. For example:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="n">piglatin</span> <span class="k">style</span> <span class="k">default</span><span class="p">:</span>
<span class="na">font</span> <span class="s2">&quot;stonecutter.ttf&quot;</span>
</pre></div>
</div>
<p>More usually, the font used for dialogue is set with <a class="reference internal" href="gui.html#var-gui.text_font"><code class="xref std std-var docutils literal notranslate"><span class="pre">gui.text_font</span></code></a>, which
can be customized using:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">translate</span> <span class="n">piglatin</span> <span class="k">python</span><span class="p">:</span>
<span class="n">gui</span><span class="o">.</span><span class="na">text_font</span> <span class="o">=</span> <span class="s2">&quot;stonecutter.ttf&quot;</span>
</pre></div>
</div>
<p>When a language is activated either at the start of the game, or
after a language change Ren'Py resets the styles to their contents
at the end of the init phase. It then runs all <code class="docutils literal notranslate"><span class="pre">translate</span> <span class="pre">python</span></code> blocks,
all style blocks, and all translate style blocks associated with the current
language, guaranteeing that blocks appearing earlier in a file are executed first.
Finally, it rebuilds styles, allowing the changes to take effect.</p>
<p>Style translations may be added to any .rpy file.</p>
</div>
<div class="section" id="default-language">
<h2>Default Language<a class="headerlink" href="#default-language" title="Permalink to this headline"> link</a></h2>
<p>The default language is chosen using the following method:</p>
<ul class="simple">
<li>If the RENPY_LANGUAGE environment variable is set, that language is
used.</li>
<li>If <a class="reference internal" href="config.html#var-config.language"><code class="xref std std-var docutils literal notranslate"><span class="pre">config.language</span></code></a> is set, that language is used.</li>
<li>If the game has ever chosen a language in the past, that language is
used.</li>
<li>If this is the first time the game has been run and
<a class="reference internal" href="config.html#var-config.enable_language_autodetect"><code class="xref std std-var docutils literal notranslate"><span class="pre">config.enable_language_autodetect</span></code></a> is True, Ren'Py tries to
autodetect the language using <a class="reference internal" href="config.html#var-config.locale_to_language_function"><code class="xref std std-var docutils literal notranslate"><span class="pre">config.locale_to_language_function</span></code></a>.</li>
<li>If this is the first time the game has been run,
<code class="xref std std-var docutils literal notranslate"><span class="pre">config.default_language</span></code> is used. (This defaults to the None
language.)</li>
<li>Otherwise, the None language is used.</li>
</ul>
</div>
<div class="section" id="translation-actions-functions-and-variables">
<h2>Translation Actions, Functions, and Variables<a class="headerlink" href="#translation-actions-functions-and-variables" title="Permalink to this headline"> link</a></h2>
<p>The main way to switch languages is with the Language action.</p>
<dl class="function">
<dt id="Language">
<code class="descname">Language</code><span class="sig-paren">(</span><em>language</em><span class="sig-paren">)</span><a class="headerlink" href="#Language" title="Permalink to this definition"> link</a></dt>
<dd><p>Changes the language of the game to <cite>language</cite>.</p>
<dl class="docutils">
<dt><cite>language</cite></dt>
<dd>A string giving the language to translate to, or None to use
the default language of the game script.</dd>
</dl>
</dd></dl>
<p>The Language action can be used to add a language preference to the
preferences screen:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">frame</span><span class="p">:</span>
<span class="na">style_prefix</span> <span class="s2">&quot;pref&quot;</span>
<span class="k">has</span> <span class="k">vbox</span>
<span class="k">label</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Language&quot;</span><span class="p">)</span>
<span class="k">textbutton</span> <span class="s2">&quot;English&quot;</span> <span class="na">action</span> <span class="n">Language</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="k">textbutton</span> <span class="s2">&quot;Igpay Atinlay&quot;</span> <span class="na">action</span> <span class="n">Language</span><span class="p">(</span><span class="s2">&quot;piglatin&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>There are two translation-related functions:</p>
<dl class="function">
<dt id="renpy.change_language">
<code class="descclassname">renpy.</code><code class="descname">change_language</code><span class="sig-paren">(</span><em>language</em>, <em>force=False</em><span class="sig-paren">)</span><a class="headerlink" href="#renpy.change_language" title="Permalink to this definition"> link</a></dt>
<dd><p>Changes the current language to <cite>language</cite>, which can be a string or
None to use the default language.</p>
</dd></dl>
<dl class="function">
<dt id="renpy.known_languages">
<code class="descclassname">renpy.</code><code class="descname">known_languages</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#renpy.known_languages" title="Permalink to this definition"> link</a></dt>
<dd><p>Returns the set of known languages. This does not include the default
language, None.</p>
</dd></dl>
<p>In addition, there are four functions that are related to string
translation:</p>
<dl class="function">
<dt id="_">
<code class="descname">_</code><span class="sig-paren">(</span><em>s</em><span class="sig-paren">)</span><a class="headerlink" href="#_" title="Permalink to this definition"> link</a></dt>
<dd><p>(Single underscore) Returns <cite>s</cite> unchanged. Ren'Py will scan for
strings enclosed in this function, and add them to the list of
translatable strings. The strings will not be translated until
they are displayed.</p>
</dd></dl>
<dl class="function">
<dt id="__">
<code class="descname">__</code><span class="sig-paren">(</span><em>s</em><span class="sig-paren">)</span><a class="headerlink" href="#__" title="Permalink to this definition"> link</a></dt>
<dd><p>(Double underscore) Returns <cite>s</cite> immediately translated into the
current language. Strings enclosed in this function will be added
to the list of translatable strings. Note that the string may be
double-translated, if it matches a string translation when it
is displayed.</p>
</dd></dl>
<dl class="function">
<dt id="_p">
<code class="descname">_p</code><span class="sig-paren">(</span><em>s</em><span class="sig-paren">)</span><a class="headerlink" href="#_p" title="Permalink to this definition"> link</a></dt>
<dd><p>Reformats a string and flags it as translatable. The string will be
translated when displayed by the text displayable. This is intended
to define multi-line for use in strings, of the form:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">define</span> <span class="n">config</span><span class="o">.</span><span class="n">about</span> <span class="o">=</span> <span class="n">_p</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> These two lines will be combined together</span>
<span class="s2"> to form a long line.</span>
<span class="s2"> This line will be separate.</span>
<span class="s2"> &quot;&quot;&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The reformatting is done by breaking the text up into lines,
removing whitespace from the start and end of each line. Blank lines
are removed at the end. When there is a blank line, a blank line is
inserted to separate paragraphs. The {p} tag breaks a line, but
doesn't add a blank one.</p>
<p>This can be used in a string translation, using the construct:</p>
<div class="highlight-renpy notranslate"><div class="highlight"><pre><span></span><span class="k">old</span> <span class="s2">&quot;These two lines will be combined together to form a long line.</span><span class="se">\n\n</span><span class="s2">This line will be separate.&quot;</span>
<span class="k">new</span> <span class="n">_p</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> These two lines will be combined together</span>
<span class="s2"> to form a long line. Bork bork bork.</span>
<span class="s2"> This line will be separate. Bork bork bork.</span>
<span class="s2"> &quot;&quot;&quot;</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
<dl class="function">
<dt id="renpy.translate_string">
<code class="descclassname">renpy.</code><code class="descname">translate_string</code><span class="sig-paren">(</span><em>s</em>, <em>language=&lt;renpy.object.Sentinel object at 0x7f4dff319cd0&gt;</em><span class="sig-paren">)</span><a class="headerlink" href="#renpy.translate_string" title="Permalink to this definition"> link</a></dt>
<dd><p>Returns <cite>s</cite> immediately translated into <cite>language</cite>. If <cite>language</cite>
is Default, uses the language set in the preferences.
Strings enclosed in this function will <strong>not</strong> be added
to the list of translatable strings. Note that the string may be
double-translated, if it matches a string translation when it
is displayed.</p>
</dd></dl>
<p>There are two language-related variables. One is
<a class="reference internal" href="config.html#var-config.language"><code class="xref std std-var docutils literal notranslate"><span class="pre">config.language</span></code></a>, which is used to change the default language
of the game.</p>
<dl class="var">
<dt id="var-_preferences.language">
<code class="descname">_preferences.language</code><a class="headerlink" href="#var-_preferences.language" title="Permalink to this definition"> link</a></dt>
<dd><p>The name of the current language, or None if the default language is
being used. This should be treated as a read-only variable. To
change the language, call <a class="reference internal" href="#renpy.change_language" title="renpy.change_language"><code class="xref py py-func docutils literal notranslate"><span class="pre">renpy.change_language()</span></code></a>.</p>
</dd></dl>
</div>
<div class="section" id="unsanctioned-translations">
<h2>Unsanctioned Translations<a class="headerlink" href="#unsanctioned-translations" title="Permalink to this headline"> link</a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It's best to ask a game's creators for permission before
creating an unsanctioned translation.</p>
</div>
<p>Ren'Py includes a small amount of support for creating translations
without the active assistance of the game's creators. This support
consists of the ability to automatically create a string translation
file from all of the strings in the game. Since string translations
are used for untranslated dialogue, this technique makes it possible
to translate a game.</p>
<p>To create a string translation file, perform the following steps:</p>
<ul class="simple">
<li>Set the RENPY_LANGUAGE environment variable to the language you want
to translate to.</li>
<li>Set the RENPY_UPDATE_STRINGS environment variable to a non-empty
value.</li>
<li>Play through the game until all text is seen.</li>
</ul>
<p>This will update the &quot;game/tl/language/strings.rpy&quot; file with a
translation template that contains all of the strings in it.</p>
<p>If a game doesn't include support for changing the language, it may be
appropriate to use an <code class="docutils literal notranslate"><span class="pre">init</span> <span class="pre">python</span></code> block to set <a class="reference internal" href="config.html#var-config.language"><code class="xref std std-var docutils literal notranslate"><span class="pre">config.language</span></code></a>
to the target language.</p>
<p>Along with the use of string translations for dialogue, unsanctioned
translators may be interested in using the techniques described above
to translate images and styles.</p>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-right">
<a href="#">Back to top</a>
</p>
<p>
&copy; Copyright 2012-2022, Tom Rothamel.<br/>
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.6.<br/>
</p>
</div>
</footer>
</body>
</html>