I18n - e-ucm/ead GitHub Wiki

We use the common Java convention of having several .properties files that provide localized strings for each language, using the .properties format. These files are loaded and managed by the I18N class, which is part of the engine-core (and is therefore available in all engine and editor flavors).

messages[_xx[_YY]].properties

The default localization language is Spanish; therefore, assets/i18n/messages.properties contains lines such as

editor.title = Editor de eAdventure

The English localization is found in assets/i18n/messages_en.properties, and contains, among many others, this variant:

editor.title = eAdventure Editor

We provide 4 levels of localized strings:

  • Key level: the property key used is not in any known messsages**.properties, and the key itself is returned.
  • Default level: the property key is defined in messages.properties, and returns a default translation (in our case, Spanish).
  • Language level: the property key is defined in a file in the form messages_xx.properties, where xx is an iso 639-1 language identifier.
  • Country level: the property key is defined in a file in the form messages_xx_YY.properties, where, again, xx is a language identifier and YY is an iso 3166 alpha-2 country identifier.

These 4 levels allows to have the following i18n structure:

messages.properties // Default translations
messages_en.properties // English translations
messages_en_US.properties // particular translations in US English (say, "color" and "center")
messages_en_GB.properties // particular translations in GB English (say, "colour" and "centre")

General use

From the actual Java code, these are called as follows:

frame.setTitle(I18n.m("editor.title"));

Or, if you are feeling lazy,

// this static import makes m referer to I18N.m wherever it is used
import static es.eucm.ead.engine.I18N.m;

// and later on
frame.setTitle(m("editor.title"));

Advanced usage

Messages can be parametrized. For example, say that you want to describe the dimensions of a room. You would have, in the English .properties file,

room.dimensions = The {} room has a size of {}x{} paces.

And then, from the Java code, you would populate this via

showMessage(I18n.m("room.dimensions", "throne room", 10, 20));
// results in 'The throne room has a size of 10x20 paces'

That is, each successive instance of {} is replaced by the corresponding call-time parameters.

For the case when the messages differ depending on the cardinality of the input, a third version of I18N.m is available:

room.guards-singular = There is {} guard patrolling the {} exit.
room.guards-plural = There are {} guards patrolling the {} exit.
showMessage(m(room.guardNumber, "room.guards-singular", "room.guards-plural", room.guardNumber, "East"));
// results in 'There is 1 guard patrolling the exit' or 'There are 2 guards patrolling the exit' (for n != 1)

Adding new translations

Just drop a new .properties file in assets/i18n with the appropriate language-code; for example, for Swedish (sv), you would create a messages-sv.properties file, and add translations for all the strings found in the other properties files (the default Spanish and the English translations will always be the most up-to-date, as they are maintained directly by the development team).

Make sure that the new language is listed in assets/i18n/i18n.properties -- and if not, add it. This file is checked during application startup to populate language-selection menus. Having more languages listed than necessary has a minimal impact on application startup times, but is otherwise not a problem.