| 12345678910111213141516171819202122232425262728293031323334 |
- <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>Localizing jME 3 Games</title><link rel="stylesheet" href="./asciidoctor.css">
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
- <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/localization.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Localizing jME 3 Games</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#scope">Scope</a></li><li><a href="#preparing-the-localization">Preparing the Localization</a></li><li><a href="#translating-the-messages">Translating the Messages</a></li><li><a href="#which-strings-not-to-translate">Which Strings Not to Translate</a></li><li><a href="#common-localization-problems">Common Localization Problems</a></li><li><a href="#more-documentation">More Documentation</a></li></ul></div></div><div id="content"><div class="sect1"><h2 id="scope">Scope</h2><div class="sectionbody"><div class="paragraph"><p>Localizing an application can mean several things:</p></div>
- <div class="ulist"><ul><li><p>At minimum you translate all messages and dialogs in the user interface to your target languages.</p></li><li><p>You should also translate the “read me, help, and other documentation.</p></li><li><p>Also translating web content related to the application makes sure international users find out about your localized game.</p></li><li><p>If you go the whole way of internationalization, you also “translate metaphors in icons or symbols used.<br>
- E.g. For localizations to right-to-left languages, you must also adjust the whole flow of the UI (order of menus and buttons).</p></li></ul></div>
- <div class="paragraph"><p>There are tools that assist you with localizing Java Swing GUIs. jME3 applications do not typically have a Swing <abbr title="Graphical User Interface">GUI</abbr>, so those tools are not of much help. Just stick to the normal Java rules about using Bundle Properties:</p></div></div></div>
- <div class="sect1"><h2 id="preparing-the-localization">Preparing the Localization</h2><div class="sectionbody"><div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>The jMonkeyEngine SDK supports opening and editing Bundle.properties files. Also note the Tools > Localization menu.</p></div></td></tr></table></div>
- <div class="paragraph"><p>To prepare the application for localization, you have to first identify all hard-coded messages.</p></div>
- <div class="olist arabic"><ol class="arabic"><li><p>Find every line in your jME3 game where you hard-coded message strings, e.g.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">System</span>.out.print(<span class="string"><span class="delimiter">"</span><span class="content">Hello World!</span><span class="delimiter">"</span></span>);
- UiText.setText(<span class="string"><span class="delimiter">"</span><span class="content">Score: </span><span class="delimiter">"</span></span> + score);</code></pre></div></div></li><li><p>Create one file named <code>Bundle.properties</code> in each directory where there are Java file that contain messages.</p></li><li><p>For every hard-coded message, you add one line to the <code>Bundle.properties</code> file: First specify a unique key that identifies this string; then an equal sign; and the literal string itself.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code>greeting=Hello World!
- score.display=Score:</code></pre></div></div></li><li><p>In the source code, replace every occurence of a hard-coded message with the appropriate Resource Bundle call to its unique key:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">System</span>.out.print(<span class="predefined-type">ResourceBundle</span>.getBundle(<span class="string"><span class="delimiter">"</span><span class="content">Bundle</span><span class="delimiter">"</span></span>).getString(<span class="string"><span class="delimiter">"</span><span class="content">greeting</span><span class="delimiter">"</span></span>));
- UiText.setText(<span class="predefined-type">ResourceBundle</span>.getBundle(<span class="string"><span class="delimiter">"</span><span class="content">Bundle</span><span class="delimiter">"</span></span>).getString(<span class="string"><span class="delimiter">"</span><span class="content">score.display</span><span class="delimiter">"</span></span>) + score);</code></pre></div></div></li></ol></div>
- <div class="paragraph"><p>The language used in the Bundle.properties files will be the default language for your game.</p></div></div></div>
- <div class="sect1"><h2 id="translating-the-messages">Translating the Messages</h2><div class="sectionbody"><div class="paragraph"><p>Each additional language comes in a set of files that is marked with a (usually) two-letter suffix. Common locales are de for German, en for English, fr for French, ja for Japanese, pt for Portuguese, etc.</p></div>
- <div class="paragraph"><p>To translate the messages to another language, for example, German:</p></div>
- <div class="olist arabic"><ol class="arabic"><li><p>Make a copy of the <code>Bundle.properties</code> files.</p></li><li><p>Name the copy <code>Bundle_de.properties</code> for German. Note the added suffix _de.</p></li><li><p>Translate all strings (text on the right side of the equal sign) in the <code>Bundle_de.properties</code> to German.</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code>greeting=Hallo Welt!
- score.display=Spielstand:</code></pre></div></div>
- <div class="admonitionblock important"><table><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content"><div class="paragraph"><p>Do not modify any of the keys (text to the left of the equal sign)!</p></div></td></tr></table></div></li><li><p>To test the German localization, start the application from the command line with <code>-Duser.language=de</code>. Note the parameter <code>de</code>.</p><div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>In the jMonkeyEngine SDK, you set this VM Option in the Project properties under Run. Here you can also save individual run configuraions for each language you want to test.</p></div></td></tr></table></div></li></ol></div>
- <div class="paragraph"><p>To get the full list of language suffixes use</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">System</span>.out.println(<span class="predefined-type">Arrays</span>.toString(<span class="predefined-type">Locale</span>.getISOLanguages()));</code></pre></div></div></div></div>
- <div class="sect1"><h2 id="which-strings-not-to-translate">Which Strings Not to Translate</h2><div class="sectionbody"><div class="admonitionblock important"><table><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content"><div class="paragraph"><p>In the Bundle.properties file, do not include any strings that are asset paths, node or geometry names, input mappings, or material layers.</p></div></td></tr></table></div>
- <div class="ulist"><ul><li><p>Keep material layers:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">mat.setTexture(<span class="string"><span class="delimiter">"</span><span class="content">ColorMap</span><span class="delimiter">"</span></span>, tex);</code></pre></div></div></li><li><p>Keep paths:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">teapot = assetManager.loadModel(<span class="string"><span class="delimiter">"</span><span class="content">Models/Teapot/Teapot.obj</span><span class="delimiter">"</span></span>);</code></pre></div></div></li><li><p>Keep geometry and node names:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">Geometry thing=<span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">"</span><span class="content">A thing</span><span class="delimiter">"</span></span>, mesh);
- Node vehicle = <span class="keyword">new</span> Node(<span class="string"><span class="delimiter">"</span><span class="content">Vehicle</span><span class="delimiter">"</span></span>);</code></pre></div></div></li><li><p>Keep mappings:</p><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">inputManager.addMapping(<span class="string"><span class="delimiter">"</span><span class="content">Shoot</span><span class="delimiter">"</span></span>, trigger);
- inputManager.addListener(actionListener, <span class="string"><span class="delimiter">"</span><span class="content">Shoot</span><span class="delimiter">"</span></span>);</code></pre></div></div></li></ul></div>
- <div class="paragraph"><p>Only localize messages and UI text!</p></div></div></div>
- <div class="sect1"><h2 id="common-localization-problems">Common Localization Problems</h2><div class="sectionbody"><div class="paragraph"><p>Typical problems include:</p></div>
- <div class="ulist"><ul><li><p>Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization.</p></li><li><p>Strings with variable text or numbers don’t work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or use <a href="http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms">gettext</a> or <a href="http://userguide.icu-project.org/formatparse/messages">ICU4J</a>.</p></li><li><p>The localizer only sees the strings, without any context. E.g. does “Search History mean “display the history of searches, or “search through the history? ⇒ Use clear key labels. Work closely with the localizers if they require extra info, and add that info as comments to the translation file.</p></li><li><p>Broken international characters ⇒ Make sure the files are saved with the same character encoding as the font file(s) you’re using. Nowadays, that usually means UTF-8 since font files tend to come for Unicode.</p></li><li><p>Missing international characters ⇒ Make sure that there’s a glyph for every needed character in your font, either by using more complete font files or by having the translation changed.</p></li></ul></div></div></div>
- <div class="sect1"><h2 id="more-documentation">More Documentation</h2><div class="sectionbody"><div class="paragraph"><p><a href="http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/">http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/</a></p></div>
- <div class="paragraph"><p><a href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation</a></p></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
- apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
- indexName: 'jmonkeyengine',
- inputSelector: '#doc-search',
- debug: false // Set debug to true if you want to inspect the dropdown
- });</script></body></html>
|