Localization Guide - cabarius/ToyBox GitHub Wiki
Table of contents
Information for localizers
How to localize
Localization files consist of some MetaData and the Strings Dictionary. The Dictionary consists of a key (string in the original language) and a value (string in the translated language). At the beginning the values will be empty, you can contribute by adding the translated values or correcting existing ones.
IMPORTANT: Please don't change keys and keep the original formatting when translating
When the original key has a space at the beginning but not at the end, please do that for the translated string also. Some strings might contain color or other formatting (using HTML tags), please keep those too. Once you modified the files, create a PR on GitHub with the changes. You don't have to create a complete translation in one go. If values are missing, it will just use the original keys, which means that it's not a problem if localization is done step by step.
Getting the localization file
To contribute to an existing localization, just add/modify the relevant file in the repository.
To add a new localization, create the file (CTRL
+ F10
to open UMM, Toybox -> Settings
tab -> Pick the language -> Click Export current locale to file
).
Now there should be a new file in the ToyBox\Localization directory on your PC (e.g. '\Steam\steamapps\common\Pathfinder Second Adventure\Mods\ToyBox\Localization'). That file is called {languageCode}.json. The keys in it are based on the ones from en.json in the same directory.
The localization file
As mentioned earlier, the name of the localization file is {languageCode}.json.
There are 5 root elements, and typically the only 2 you'll edit are Contributers
(to add yourself), and Strings
LanguageCode
which saves the LanguageCodeVersion
which is the ToyBox version for which the most recent keys were addedContributers
which are the Contributers for that localizationHomePage
which is a link to this GitHubStrings
which is a Dictionary containing the actual localization
Information for developers
What to localize
Localization is nice, but some things should not be localized for various reasons. Here is a list:
- Errors, warnings, debug information or anything else that will be logged should not be localized.
- Labels that represent in-game data (Quests, Etudes, Items, ...) meaning their descriptions, names etc.. There are hundreds of thousands of blueprints in the game. If we did add localization, then that would mean hundreds of thousands of localization keys.
- When localizing string please take care that they are compile-time constant. A string like $"My String {SomeVal}" would get a new key created for every possible value of SomeVal. This is especially bad for variables that can assume arbitrary values (strings that display the page number for example), but even if it's only to display a character name, doing this is not a good idea for various reasons. Instead you should split those into several smaller strings. In cases where it you absolutely need to localize the whole string with variable, then you can use tricks like this:
var text = "Page % of %".localize().Split('%');
_paginationString = $"{text?[0]}{_currentPage + 1}{text?[1]}{GetMaxPages()}";
Though this does increase performance cost so be sure to only use this if absolutely necessary.
Edit: After writing this, I remembered formatted strings exist...
How to localize
Modifying code
Supporting localization is as simple as adding a .localize() invocation to the strings that need localization and adding key to the localized keys. This method is a string extension that uses the string content as a key for a (runtime loaded) dictionary of translations. If the key exists, it will return the translated string. If not, it will just return the key.
Adding the keys
Adding the keys can be done using the following ways:
- Manually adding the keys. This should be done to the en.json which is taken as the default locale file. Just add the string as both key and value to the file
- Rendering the key in-game. The localization framework will add unknown keys encountered during runtime to its dictionary. Saving or exporting the locale to the locale file will therefore produce a new file with the additional keys. The strings need to be rendered first, since it's only when the .localize() call happens that the key is actually added.
- (Not Implemented Yet) The plan is to add a Source Generator that, before a build step, goes through source code, checks for localize() invocations on constant strings and adds those strings as keys. Then it should automatically add those keys to en.json and update every other locale file to have all the keys that en.json has. This would add most (not all) keys for localization automatically
If you have questions, just reach out to an active contributor on GitHub or on the Owlcat Discord.