Skip to content

Adding Translations

Person8880 edited this page Mar 24, 2018 · 9 revisions

Shine uses a set of JSON files in order to build messages. Each plugin has its own folder reserved for its own translations. These files live under locale/shine/extensions/pluginname. There is also a single file for the core translations under locale/shine/core/. You will need to provide files for all the plugins, and the core strings.

Adding a new language

To add a new language, first take the existing enGB.json file as a starting point. In this file will be all strings that require translation. Copy and rename the file to match the language code you want to translate to. For example, French would be frFR.json. If you're not sure what the name should be, look in NS2's installation folder under ns2/gamestrings, and match the file name (replacing .txt with .json).

Plural Rules

By default, languages are considered to have the same plural forms as English. That is:

  • A value of 1 is considered singular.
  • A value of 0 or more than 1 is considered plural.

If your language has more plural forms, or different rules, you can define this. Create a def-LANGCODE.json file under locale/shine, where LANGCODE should be the language code. For example, there is currently a definition file for Czech under def-csCS.json.

Now, add an entry named "GetPluralForm". The value should be a Lua expression that returns a single number. This number will tell the Pluralise transformer (see below) which variation it needs to use. Taking the Czech rule as an example:

( n == 1 and 1 ) or ( ( n >= 2 and n <= 4 ) and 2 ) or 3

Here n refers the the number that is being used to create a plural form. In the case of Czech, a value of 1 uses the first provided form (n == 1 and 1), a value between 2 and 4 inclusive uses the second form (n >= 2 and n <= 4 and 2), and otherwise the third form is used (or 3).

This means that in csCS.json files, the Pluralise transformer can have 3 variations, which will be picked based on the rule above. For example:

{Parameter:Pluralise:single|between 2 and 4|more than 4 or 0}

If Parameter is 1, the rule gives us that the plural form is 1, and thus the text becomes single. If Parameter is between 2 and 4 inclusive, the rule gives us that the plural form is 2 and thus the text becomes between 2 and 4. Finally, if Parameter is 0 or more than 4, then the rule gives us that the plural form is 3 and thus the text becomes more than 4 or 0.

Translation strings

You may notice that quite a few strings have placeholder values in them. These look like this: {PlaceholderName}. These values will be replaced with data from the plugin. Hopefully the name of the placeholder makes it obvious what it's for. If not, feel free to ask in an issue or in a pull request with your new translation.

Transformations

You may also notice some placeholders have more than just a name. These are transformations.

Transformation syntax

The basic syntax is a placeholder value (e.g. {Value), followed by a : (e.g. {Value:), then the name of the transformer you want to apply to it (e.g. {Value:Upper). Following that, you can optionally add an argument to pass to the transformer by adding another :, then your value. Finally, close the tag off with } (e.g. {Value:Upper}).

You can also chain together transformations. The expected format is {Value:Transformation1:Transformation1's arguments:Transformation2:Transformation 2's arguments...}.

If a transformation does not require arguments, just add another : immediately, like this: {Value:Transformation1::Transformation2}.

All available transformations

Here's a list of all the transformations available, and what they do to the input:

Transformation Action
{Value:Upper} Uppercases the value, including many non-ASCII characters.
{Value:Lower} Lowercases the value, including many non-ASCII characters.
{Value:Format:FormatString} Performs string.format( FormatString, Value ). For example, {Value:Format:%.2f} would format the value as a number with 2 decimal places.
{Value:Abs} Returns the absolute value of the given number.
{Value:BoolToPhrase:Text if true|Text if false} Takes a boolean, and outputs Text if true if the boolean is true, or Text if false if it is false.
{Value:TeamName:captials singular} Takes a team number, and outputs the canonical name associated with it. Adding capitals capitalises the first letter, and adding singular returns a non-plural version (e.g. marine team instead of marines). For example, a team number of 1 and {Value:TeamName:capitals} outputs Marines.
{Value:Pluralise:Text if value is 1|Text if value is not 1} See the above section on plural rules.
{Value:Duration:Text if duration is 0} Transforms the given value (taken to be a time in seconds) into a pretty string. If Text if duration is 0 is provided, then this will be output if the value is 0. For example, in enGB, Value = 60 would result in 1 minute.
{Value:NonZero:Text if value is not 0} Outputs Text if value is not 0 if the given value is not 0. Otherwise outputs nothing.
{Value:Sign:Text if negative|Text if non-negative} Outputs Text if negative if the value is less than 0, otherwise outputs Text if non-negative.
{Value:Translation:source} Outputs the translated value associated with the input translation key, and optionally from the given source. Source can either be a plugin's name (e.g. voterandom), or Core to be taken from the core strings.

Testing your translations

Once you've made the required json files, the next step is to test them. You'll want to clone the code from GitHub, either using your preferred Git client if you're familiar with Git, or otherwise, you can download a zip of the mod too. Place your translation files in this copy of the mod.

Once you've got the mod downloaded somewhere and your translation files are added to it, make a shortcut to NS2.exe in the Steam/steamapps/common/Natural Selection 2 folder with the parameter:

-game "path/to/where/you/downloaded/Shine"

Now run the game from this shortcut (make sure Steam is running). If your in-game language option is not already set, change it to your language. Then, load a map through the console (map ns2_derelict for example). You can then run through various actions to see how things look, such as opening the vote menu, admin menu, triggering votes etc.

If you want to check how many translation keys you are missing, run the sh_missingtranslations <langcode> command, passing in your language code.

Contributing to the mod

Once your translations are complete, it would benefit everyone for you to contribute them directly to the mod. To do so, fork the repository, commit your changes to a new branch, then open a pull-request here on GitHub to the develop branch. If you're not sure how to do that, have a look at GitHub's guide here.

Please ensure your translations have correct grammar, spelling and are formatted as close as possible to the original English. The clean and professional look that this gives is an important part of my design of the mod, and I do not want that compromised for non-English users.

Clone this wiki locally