- Intro
- A short glossary
- Workflow overview
- Setting up environment for string extraction
- Extracting strings
- Creating new PO
- Updating existing PO
- Compiling PO into MO
- Adding MO file to the mod
- Miscellaneous notes
This document aims to give a brief explanation on how to set up and operate mod translation workflow for Cataclysm: Bright Nights.
For mod localization the game uses custom localization system that is similar to GNU gettext and is compatible with GNU gettext MO files.
While it's possible to use Transifex or any other platform or software that supports gettext, this document only gives examples on how to work with Poedit and command-line GNU gettext utilities.
If you desire an in-depth explanation on PO/POT/MO files or how to work with them using GNU gettext utilities, see GNU gettext manual.
To get some generic tips on translating strings for Cataclysm: Bright Nights and its mods, see TRANSLATING.md.
Portable Object Template file (.pot
).
This is a text file that contains original (English) strings extracted from mod's JSON files. The POT file is a template used for creating empty or updating existing PO files of any language.
Portable Object file (.po
).
This is a text file that contains translated strings for one language. The PO files are what translators work with, and what will be compiled into a MO file.
Machine Object file (.mo
).
This is a binary file that contains translated strings for one language. The MO files are what the game loads, and where it gets translated strings from.
The first translation workflow is as follows:
- Extract strings from mod JSON files into a POT file
- Create PO file for target language from this POT
- Fill the PO file with translated strings
- Compile PO into MO
- Put the MO into your mod files
As the mod changes with time, so may change its strings. Updating existing translations is done as follows:
- Extract strings from mod JSON files into a new POT file
- Update existing PO file from the new POT file
- Add new or edit existing translated strings in the PO file
- Compile PO into MO
- Replace old MO in the mod files with new version
Step 1 in both workflows requires you to set up environment for string extraction (see below).
Steps 2-4 can be done using translation software either by the mod author/maintainer, or by the translator.
You'll need Python 3 with polib
library installed (available via pip
).
Scripts for string extraction can be found in the lang
subdirectory of the repository:
extract_json_strings.py
- main string extraction routinesdedup_pot_file.py
- fixes errors in POT file produces by the 1st scriptextract_mod_strings.bat
(extract_mod_strings.sh
for Linux/MacOS) - to automate the other 2 scripts
Copy these 3 scripts into the mod's folder and:
- on Windows, double-click
extract_mod_strings.bat
- on Linux/MacOS, open terminal and run
./extract_mod_strings.sh
If the process completed without errors, you'll see a new lang
folder
with extracted_strings.pot
file inside.
Before creating PO file, you need to choose language id.
Open data/raw/languages.json
to see the list of languages supported by the game.
In this list, each entry has its own id in form of ln_LN
,
where ln
determines language and LN
- dialect.
You can either use full ln_LN
for exact language+dialect match,
or ln
if you want the game to use your MO regardless of dialect.
- Open the POT file with Poedit
- Press "Create new translation" button (should show up near the bottom)
- In language selection dialog, enter language id you chose
- Save the file as
path/to/mod/lang/LANG.po
whereLANG
is the same language id
msginit -i lang/index.pot -o lang/LANG.po -l LANG.UTF-8 --no-translator
Where LANG
is the language id you chose
- Open the PO file with Poedit
- Choose
Catalog->Update from POT file...
and select the new POT file - Save the file
msgmerge lang/LANG.po lang/index.pot
- Open the PO file with Poedit
- Make sure MO file will be encoded using UTF-8 (it should do so by default,
you can double check in
Catalog->Properties->"Translation properties" tab->Charset
). - By default, each time PO file is saved Poedit automatically compiles it into MO,
but the same can also be done explicitly via
File->Compile to MO...
msgfmt -o lang/LANG.mo lang/LANG.po
Create lang
directory in the mod files directory and put MOs there:
mods/
YourMod/
modinfo.json
lang/
es.mo
pt_BR.mo
zh_CN.mo
Note: Storing your POT/PO files
in the same lang
subdirectory may make it easier to keep track of them.
The game ignores these files, and your mod folder structure will look like this:
mods/
YourMod/
modinfo.json
lang/
extracted_strings.pot
es.po
es.mo
pt_BR.po
pt_BR.mo
zh_CN.po
zh_CN.mo
No. The game looks for MO files with specific names that are located in the
lang
subdirectory of the mod's path
directory specified in modinfo.json
(if not specified, path
matches the mod's directory).
However, any mod will automatically try to use any other mod's translation files to translate its strings. This makes it possible to create mods that are purely "translation packs" for other mods (or mod collections).
Open debug menu and select Info...->Reload translations
,
and the game will reload all MO files from disk.
This makes it easy to see how translated string looks in game, provided the translator has a way to compile MO files.
Example workflow with Poedit:
- Translate a string
- Hit Ctrl+S
- Alt+Tab into the game
- Reload translation files via debug menu
- The game now displays translated string
MO load order is as follows:
- First and always goes base game's MO file, which contains translation strings
for UI, hardcoded functionality, base "mod" (
data/json/
) and in-repo mods. - Then MO files of mods are loaded, in same order as the mod load order.
When loading MO files, the game first looks for the file with exact language and dialect match in its name. If such file is absent, then it looks for a file with no dialect.
For example, when using Español (España)
the selection order is
es_ES.mo
es.mo
And when using Español (Argentina)
the selection order is
es_AR.mo
es.mo
Thus, es.mo
would be loaded for either dialect of Spanish
if the exact translation files are not present.
Then the game selects which one to use according to this set of rules:
- If string A's translation has plural forms, but string B's translation does not, then translation A is used for both single and plural forms.
- If both translation A and B have (or both don't have) plural forms, then the first loaded translation is used (see MO load order).
If you want a different translation from the one in the base game, or don't want it to conflict with a string from some other mod, add a translation context to the string in the corresponding JSON object (see TRANSLATING.md for which fields support translation context).