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.

Locales/en.yml
$name: English

menu:
    play: Play
    settings: Settings
hud:
    gold: "{0} gold"
items:
    one: "{0} item"
    other: "{0} items"
Locales/ar.yml
$name: العربية
$direction: rtl

menu:
    play: العب

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.

Locales/pl.yml
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.

Not included

Ordinal forms (1st, 2nd) and gender forms.