Skip to content

Localisation at runtime

How translated text reaches the player is a build choice with two modes. The mode is baked into the bundle, so your integration code constructs the engine the same way either way - what changes is what a step hands you. (The translation workflow - exporting for translators, importing back, staleness - is the project team’s side: Localisation.)

Embedded (default)IDs-only
What the .patterc carriesevery locale’s strings, inlineno strings
What the runtime returns for a linethe resolved text for the active localethe line’s ID
Character display nameresolved (localised)omitted, you get the character token
{@property} interpolationdone by the runtimeyou call flow.interpolate(text) yourself
Switch language at runtimeengine.setLocale("fr"), liveyour loc system’s job
Who owns translationsthe bundleyour game’s localisation system
Best forself-contained games, quick ship, the runtime does it allgames with an existing loc pipeline (Unity Localization, i18n, a CMS, …)
import { Engine } from "@patterkit/runtime";
const engine = new Engine(bundle, { locale: "fr" }); // or omit: the bundle's default
const flow = engine.openFlow("main", { scene: "intro" });
const step = flow.advance(); // step.text is resolved, interpolated French; characterName localised

Switch language live without losing the player’s place:

engine.setLocale("fr"); // subsequent beats render in French; flow state is untouched

A string missing in the active locale falls back to the source text flagged <Untranslated: {id}> …, so a half-finished translation is impossible to miss.

step.text is the beat ID and step.characterName is omitted (you still get step.character, the stable token). Look the text up yourself, then apply {@property} replacement with the flow:

const step = flow.advance(); // step.text === "L_greet" (an ID), step.character === "GUIDE"
const raw = myLocaliser.lookup(step.text, currentLanguage); // e.g. "Bonjour {@name}"
const shown = flow.interpolate(raw); // -> "Bonjour Alice" (your game's job to call)
const speaker = myLocaliser.lookup("cast:" + step.character, currentLanguage); // localise the name too

The ID → source tables your loc system needs come from the same export the translators use (JSON is the natural format here) - see the workflow page.

If the build was made with --source-debug, the engine resolves the embedded source strings (so the build is playable before your loc system exists) and exposes engine.isSourceDebug === true plus a one-time console warning: never ship that build.

All four runtimes handle both modes identically - JavaScript (@patterkit/runtime), Unity (C#), Unreal (C++), and Godot (GDScript) - each held to the same shared test suite. setLocale is live on every one of them.

MIT-licensed open source · Made by · patterkit.com