Localisation
A Patter project is ready to translate from the start: every line, narration, choice prompt, and character name has a stable ID that its translations hang off. Running the translation side of a project is one small loop, and one rule keeps it sane: writers only ever see and edit the source language. Translations live in their own files, never on the writing surface - which is also what makes staleness computable (below).
Declare your languages
Section titled “Declare your languages”In Project Settings ▸ Language, list the languages you’ll ship and mark the default (the one writers author in). That’s the whole setup.
The loop: export, translate, import
Section titled “The loop: export, translate, import”Production ▸ Export / Import Localisation… (also reachable from the Language tab) runs both halves:
- Export writes the source text - and, for a chosen language, its current translations - in the translator’s preferred format (below). Hand the file over.
- The translator fills in the Translation column/fields and sends it back.
- Import reads the language from the file (or you set it) and reports how many lines landed. Translations go into that language’s own file; the source is untouched, and the writing surface still shows only the source language.
Run the loop as often as you like - it’s incremental, not a one-shot. Which brings us to:
What changed since last time: the Status column
Section titled “What changed since last time: the Status column”Writers keep writing while translation happens, so the export tracks staleness per line. The Excel export shows it as a Status column:
- (blank) - not translated yet.
- translated - has a translation, and the source line hasn’t changed since.
- stale - has a translation, but the source line was edited after it was translated: it needs re-checking against the new wording.
On import, unflagged rows are accepted as fresh. A row still marked stale has its text
imported but stays flagged: the translator confirms a re-check by clearing the “stale”
cell, not by re-sending the file - so an old spreadsheet can never silently bless an
outdated translation. (PO files carry the same signal as the standard #, fuzzy flag.)
The formats
Section titled “The formats”All three carry the same IDs and the same staleness signal; pick by who’s receiving the file:
- Excel (.xlsx) - for human translators working by hand: one sheet per scene, columns ID / Source / Translation / Comments / Status. The friendliest to non-technical folk.
- PO / POT - for agencies and gettext-based tooling (Poedit, Weblate, Crowdin, …).
Exporting with no language gives a blank POT template; staleness is
#, fuzzy. - JSON - for pipelines and engines: plain ID → string tables, easy to transform or feed into your game’s own localisation system.
Translator-facing comments come from your documentation notes routed to the loc
channel - see Reviewing & feedback.
How the strings ship: two approaches
Section titled “How the strings ship: two approaches”At publish time (Project Settings ▸ Publish ▸ Localisation) you pick how the built bundle carries text:
- Embedded (default): every translated language ships inside the bundle. The runtime resolves the right text and can switch language live, mid-game, with no rebuild. Right for self-contained games - nothing else to set up.
- IDs-only: the bundle ships no text at all; the runtime hands your game each line’s
ID and your game’s own localisation system supplies the string. Right when the game
already has a loc pipeline (Unity Localization, i18n, a CMS…).
- Embed source language for debug (sub-option): adds the source text to an IDs-only build just so it’s playable before your loc system is wired up. It warns it’s not for release; leave it off for a real build.
Crucially, the choice doesn’t change the translation loop above: either mode exports and imports the same files. Going IDs-only never cuts you off from Patter’s round-trip - you still hand translators the same spreadsheets and feed the results into whichever pipeline ships them.
Previewing translations
Section titled “Previewing translations”The Play window always previews fully translated, whatever the build mode: switch
language from its menu and read the script in any locale, even on an IDs-only project. A
string missing in a locale plays as the source text flagged <Untranslated: …>, so a
half-finished translation is impossible to miss.
From the terminal
Section titled “From the terminal”The same loop, scriptable (see the CLI):
patter loc-export -o strings.json --format json # a blank template (all source, empty translations)patter loc-export -o fr.xlsx --format xlsx --locale fr # the fr table as a spreadsheetpatter loc-import fr.xlsx # bring a translated file back--format is json | xlsx | po; omitting --locale produces a blank template / POT. The
build mode is picked per export too: patter export --ids / --source-debug.
For the game team
Section titled “For the game team”How the two modes look from inside the game - setLocale, interpolate, the
untranslated fallback, all four runtimes - lives with the rest of the integration docs:
Localisation at runtime.
MIT-licensed open source · Made by Ian Thomas · patterkit.com