quest'n'click 4.5.0 · r1

Built for quest'n'click 4.5.0, revision r1. Whether it is published, and which one is current, is recorded at publication.json.

Translations

Français · Type: how-to + reference · Audience: author · Context: engine repository, created project · Status: ready · Applies from: 4.3.0

The content stays written in one language (lang in game.ts, en when absent). Translating is a table, not keys in the content: one JSON file per language, { "<path>": "<text>" }, made and kept up to date by the i18n tool. This page is the procedure, then the reference of the paths and of how the player picks a language.

What you get

locales/<lang>.json beside the game, every text of the game translated, a game that offers the language in its Settings and picks it from the browser, and i18n status at ✔ for every language.

Context and versions

The engine repository and a created project alike; only the command and the folder differ. True from 4.3.0: text switches kept by a translation and i18n.same are checked by status since then.

Prerequisites

Where to run the commands

ContextFolderCommandFiles
Engine repositoryits rootnpm run i18n -- <sub> (the game: GAME=<id>, else the one npm run game chose, else config.game)games/<id>/locales/
Created projectits rootnpx quest-n-click i18n <sub>game/locales/

Steps

  1. Write the reference file, every text of the game with its path, in the game's own language:

    npm run i18n -- extract              # games/<id>/locales/en.json: every text with its path (the reference)
    npm run i18n -- extract --lang fr    # locales/fr.json: keeps what is translated, follows moved texts, adds the missing ones
    npm run i18n -- status               # coverage of every language, stale paths, long lines
    

    These three run in the engine repository; in a created project they are npx quest-n-click i18n extract, npx quest-n-click i18n extract --lang fr and npx quest-n-click i18n status.

  1. Create or update the language file with extract --lang fr. The missing paths are added with the source text, to translate; the file's _ entry says so. It prints how many texts are to translate, followed a moved text, came back, or were parked as _stale.
  1. Translate the values, never the keys. Keep the text switches of the source ({form?m=him|f=her}): a translation must keep each choice its source makes, and may add its own (a French agreement English writes alike, Prêt{form?f=e|*=}). The syntax is on Heroes.
  1. Check with status. For each language: translated / total, missing, stale, long (more than 140 characters), with other text switches, and the texts identical to the source. It exits 1 while a language has a missing or stale path, a dropped switch, or an identical text that i18n.same does not list.
  1. Ship. The game's index.ts picks up every locales/*.json (the template's and the sample games' do); build as usual. Commit the reference file with the translations.

Paths, and what a refactor does to them

A path looks like room:house/look.pantry[1], item:key/name, char:grandma/refuse, ui/newGame, rules/fallbacks.look[2], start/intro[0].say, credits[3], map/places.house.name, objectives/key.title. A line with an id is keyed by it: room:house/look.pantry.<id>, rules/fallbacks.look.<id> (lists take { id, text } lines; see Upgrade notes v3). The file is { "<path>": "<text>" }.

Paths follow the structure, so a refactor moves them; extract --lang xx copes. It compares the game with the reference file (refreshed at the same time):

Rule of thumb: run extract --lang xx after every refactor, before translating anything new, and commit the reference file with the translations.

Guarantee · i18n-moved-texts · referenced · executed on aff6caab7514 · scope self-checked by the author (AI), not reviewed extract --lang keeps the translation of a text that moved, parks the one that disappeared under _stale:, and brings it back with its translation when its path returns.

How the player gets a language

The language is chosen when the page loads, the first that applies:

  1. ?lang=fr in the address;
  2. the player's choice in Settings (kept in the browser as <game id>.lang): with settings: true, the Settings menu shows a Language row (ui.language) when the game ships another language; each tap moves to the next language and reloads the page;
  3. the browser's language, when the game ships it (fr-CA picks fr);
  4. otherwise the game's own language.

A text a file lacks stays as written. The voices follow the language: Voices.

Limit · lang-not-shipped ?lang=xx for a language the game does not ship shows the texts as written, with no message.

i18n.same: identical on purpose

A text identical to the source is an untranslated line, and fails status, unless i18n.same in game.ts lists its path: a name, OK, ▲, a word French borrowed.

i18n: { same: ['char:hero/name', 'ui/ok'] },

status also lists the ui keys the game leaves to the engine's English defaults: a player sees those in English in every language.

Where else the coverage shows

npm run validate -- --report (npx quest-n-click validate --report) and the Studio's Check tab show the coverage per language. verify, build and release in a created project run i18n status and stop on its failure.

Expected result, and how to check it

status prints ✔ fr: <n>/<n> translated for every language and exits 0; ?lang=fr shows the game in French.

Common errors

SymptomCauseFix
… fr: 120/131 translated, 11 missingNew texts since the last extractextract --lang fr, translate
stale room:house/look.pantry[3]A text that no longer existsDelete it once sure, or let it come back
switch <path> (source: …; translation: …)The translation drops a choice of the source's switchesPut the switch back in the translation
same <path> (translate it, or list it in i18n.same)A text left as the sourceTranslate it, or list it in i18n.same
[<id>] no localesNo language file yetextract --lang <xx>
The page stays in English?lang= misspelt, a choice stored for another language, or the file not shippedCheck the address and Settings; rebuild

Files or data changed

locales/<base>.json (the reference) and locales/<lang>.json; nothing else. ids --write (a prerequisite) renames the keys of the locale files to id-based paths.

Recovery or going back

Both files are in Git: git checkout -- <file> undoes an extract. Nothing is lost by extract: a disappeared text goes to _stale:, never deleted.

References


Edit the source of this page · Report an error