Demo how to use localization (translate your game into multiple languages) with Castle Game Engine.
We use FPC GetText unit for this:
This translates all strings in
Place everything you may need to translate as a
resourcestringin Pascal. You can use English text in code, or you can use internal translation identifiers (never to be seen by normal users) -- both approaches are possible.
Note that this step is optional. If you want, you can work without any
game.potfile, and just create translations by manually creating files like
game.pl.pofor each language. The syntax of PO files is trivial, see
game.potcan serve a basis for translations. You can create it using strings from the source code:
Compile the game (
rstconv(distributed with FPC) like this:
rstconv -i castle-engine-output/compilation/x86_64-linux/game.rsj -o po_files/game.pot
Note that FPC will create one
xxx.rsjfile for each unit. But this should not limit you. It's normal to put all the strings from the complete application into a single
xxx.potfile. In general, the format of the
.potand .po` files (they are the same) is trivial, they are simple text files that can be concatenated together etc.
To translate to a new language:
For each new language, create a new file like
plfor a Polish translation,
enfor English etc.).
You can start by just copying
Or you can start by
msginit --locale=pl --input=game.pot --no-translator --output-file=game.pl.po. This creates
game.pl.po, with the initial translated strings having contents from
game.pot. This makes sense if
game.potcontains English text, and it's a good starting point for a new translation.
game.pl.pousing a normal text editor. Or use a specialized editor like https://poedit.net/
Generate .mo file:
msgfmt po_files/game.pl.po --output-file=data/locale/game.pl.mo. We have a trivial script here
update_translations.shdoing that. You need to rerun it after every modification to
Call in Pascal
TranslateResourceStrings(URIToFilenameSafe(ApplicationData('locale/game.pl.mo')));to use the Polish translation. This simply updates all
resourcestringcontents to the Polish versions.
Assign the resourcestrings to the approproate properties of appropriate objects, like
It's probably easiest to just call
TranslateResourceStrings once, at the very beginning of your application (at the beginning of
Application.OnInitialize handler). And then construct UI as usual (just use
resourcestrings). If the user wants to change the language, it's easiest to just say "Please restart the application in order for the language change to take effect.".
That said, if you put some more work, you can allow to dynamically switch the language during the game. Just reassign all captions from the corresponding
resourcestrings. The demo here shows how to do it: see the
TApplicationLogic.SwitchLanguage method. It's trivial to write, although it may be a pain to maintain in a larger project.
Note that we also adjust font in this application. The default font contains only basic ASCII (English) characters, so we load a font with additional German, Polish, Russian and Ukrainian characters. See https://castle-engine.io/manual_text.php about loading fonts in Castle Game Engine.
While we don't use Lazarus LCL code in CGE, but this mechanism is consistent with how Lazarus application can be localized. So a lot of Lazarus documentation apply also to us:
See also resources about gettext:
All the tools and editors for gettext files should work fine. There are even online services that take a ready PO file for translating.