Guide
Locales
An app's texts live in one YAML file per language. They are compiled into the game, read with T("key"), and switch at runtime in a single frame.
The files
Put one file per language in the app's Locales folder, named by its code: en.yml, tr.yml, ar.yml. Nested keys become dotted names.
$name: English
menu:
play: Play
settings: Settings
hud:
gold: "{0} gold"
items:
one: "{0} item"
other: "{0} items"
$name: العربية
$direction: rtl
menu:
play: العب
- Texts may be plain, quoted, or blocks (
|and>); comments start with#. $nameis the language's own name,$direction: rtlmarks a right-to-left language.enis the fallback. A text missing in the current language comes from the fallback; a text missing there too is shown as its key.- A line the compiler cannot read gives a warning at that line; the rest of the file still compiles.
Using texts
<button>{T("menu.play")}</button>
<span>{T("hud.gold", gold)}</span>
<span>{T("items", count)}</span> <!-- picks "1 item" or "5 items" -->
In a component T needs no using. Texts are reactive: when the locale changes, every text on the page updates.
For a value that changes every frame, write the label and the value apart, {T("hud.goldLabel")}: {gold}. The label is read once and the number is written without making a string.
Switching the language
using DevCore.UiEngine.Localization;
Locale.Current = "tr"; // every text updates this frame
foreach (var locale in Locale.Available) // LocaleInfo: Code, Name, IsRightToLeft
Debug.Log(locale.Code + " " + locale.Name);
string play = Locale.T("menu.play"); // from game code
At start the engine picks the system's language if your app has it, unless you already chose one. The app view sets the page's lang and dir from the locale, so right-to-left languages mirror the layout and :lang() and :dir() rules apply.
Switching 1,000 texts takes one update of about 7 ms, most of it layout and paint, and allocates nothing once the page has warmed up.
Plural forms
A text has forms when the file has texts under its key named zero, one, two, few, many or other. T("items", count) picks the form by the language's rule: English has two forms, Polish four, Arabic six, Japanese one.
items:
one: "{0} przedmiot"
few: "{0} przedmioty"
many: "{0} przedmiotów"
other: "{0} przedmiotu"
The rules are CLDR's, for 216 languages, and match the browser's Intl.PluralRules. A missing form falls back to the language's other, then to the fallback language.
Numbers and dates
Formatted values in templates ({gold:N0}, {date:d}) follow the locale's culture: grouping and decimal separators, date order. From code, Locale.Format(value, "N1") does the same and Locale.Culture is the culture in use.
The locale editor
Tools → DevCore → Locales opens a table of every key against every language.
- Search, and filter by Missing, Unused, or keys the code uses that are in no file.
- Add keys and languages; rename and remove keys; edit multi-line texts; see which files use a key.
- Plural forms are shown as rows, with only the forms each language has.
- Show switches the previews and Play mode to a language; edits appear there at once.
Not included
Ordinal forms (1st, 2nd) and gender forms.