Skip to content
TheFlash98 edited this page Jul 8, 2017 · 16 revisions

This tutorial talks about two things:

1. Internationalization (I18n)

2. Localisation (I10n)

Welcome to the TutorialI18n wiki!

A game should be available in languages other than English. We want everyone and anyone to be able to play the game. The game should not have a language constraint. Using I18n(Internationalization), this can be easily achieved. Adding new languages to the game or helping out with translating single strings is easy and helpful as it allows players from all over the world to enjoy the game, unhindered by language barriers!

Internationalization / I18n

Internationalization (I18n) is the process to design software for different languages, without changing the code for each language. Let's try and understand with an example. Let's say you have to display "Hello New Player!" when the game starts. You wouldn't want a Spanish player to see this, he/she would may be prefer seeing "Hola nuevo jugador". The code for the message is something like

@RegisterSystem
public class GreetInEnglish extends BaseComponentSystem {

    private static final Logger logger = LoggerFactory.getLogger(GreeterSystem.class);

    @ReceiveEvent
    public void onPlayerSpawn(OnPlayerSpawnedEvent event, EntityRef player) {
        logger.info("Hello, new player.");
    }
}

Now for a Spanish player, to have a different game with something like this

@RegisterSystem
public class GreetInSpanish extends BaseComponentSystem {

    private static final Logger logger = LoggerFactory.getLogger(GreeterSystem.class);

    @ReceiveEvent
    public void onPlayerSpawn(OnPlayerSpawnedEvent event, EntityRef player) {
        logger.info("Hola, nuevo jugador.");
    }
}

is tedious and highly inefficient, there too many languages in the world.

Instead of using hardcoded strings, the idea is to use a key for the string and lookup the actual content depending on the player’s language. This logic is contained in the TranslationSystem. Remove the hardcoded string and replace it with ${MyModule:greeter#greet}

@RegisterSystem
public class GreeterSystem extends BaseComponentSystem {

    private static final Logger logger = LoggerFactory.getLogger(GreeterSystem.class);

    @In
    private TranslationSystem translationSystem;

    @ReceiveEvent
    public void onPlayerSpawn(OnPlayerSpawnedEvent event, EntityRef player) {
        logger.info(translationSystem.translate("${MyModule:greeter#greet}"));
    }
}

The parameter ${MyModule:greeter#greet} tells the translation system to search for an translation entry in the module MyModule (use engine for the engine project). The entry is expected to be in a file named greeter.lang containing the key greet. So go ahead and create a file create the asset file located at assets/i18n/*.lang.

For our example, we need a file MyModule/assets/i18n/greeter.lang:

{
  "greet": "greet"
}

This file can contain a number of comma-separated entries with the key of the translation string. Values should be similar to the keys in this file.

Languages are than added in additional files with an *_xx.lang prefix, where xx should be an ISO 639-1 two-letter language code. Depending on the language select the appropriate value from these language specific files is then selected and used.

For our example, we need MyModule/assets/i18n/greeter_en.lang:

{
  "greet": "Hello, new player."
}

and similar to this one, MyModule/assets/i18n/greeter_es.lang:

{
  "greet": "Hola, nuevo jugador."
}

Let's say you want to add German. All you have to do is create a file MyModule/assets/i18n/greeter_de.lang.

{
  "greet": "Hallo neuer Spieler."
}

Again, in these files the keys map to the entries in the general file, with the values being the translated strings. It is not required to translate all these files by hand inside the json syntax. Instead, Terasology offers a weblate frontend, which is described in the next section.

Localization / l10n

Now that you know how to refer to the selected language's correct key, let's talk about how to store the correct value. Localization (l10n)is the actual translation of the extracted strings and requires no or less programming effort.

There are currently two ways of translating the game:

  1. (Recommended) Using our Weblate interface, available at http://translate.terasology.org/.

  2. Manually creating or editing text bundle files.

The former is the better option, as it allows us to easily review new translations or suggested changes.

Manual Translation

To keep things neat, clean and easily reviewable we advise you to work on the translation using a feature branch:

  • git checkout development
  • git branch feature/MyTranslation
  • git checkout feature/MyTranslation

To add a new language to the game, copy the contents of *.lang eg. menu.lang to the file where you will translate it eg. menu_**.lang in the assets/i18n directory. The ** will be the ISO 639-1 two-letter language code.

When your translation is finished, add a tiny flag to represent the language in the settings! To do this, download an appropriate 16x11 icon from the famfamfam.com icon pack (or create your own 16x11 icon) and place it inside engine/src/main/resources/assets/textures/ui/icons. Rename it to flag_xx.png, xx being the two-letter code you’ve used before.

To submit a new Translation we would want you to create a pull request which will be merged after some review. Here's how you can go about doing that:

Clone this wiki locally