Localization
Doodle Engine uses a simple @key system for localization. All player-visible text should use localization keys so your game can be translated.
Locale Files
Section titled “Locale Files”Create flat key-value YAML files in content/locales/:
location.tavern.name: 'The Rusty Tankard'location.tavern.description: 'A cozy tavern with worn wooden tables.'character.bartender.name: 'Greta'bartender.greeting: 'Welcome! What can I do for you?'location.tavern.name: 'La Jarra Oxidada'location.tavern.description: 'Una taberna acogedora con mesas de madera gastadas.'character.bartender.name: 'Greta'bartender.greeting: '¡Bienvenido! ¿Qué puedo hacer por ti?'Locale files are loaded by filename: en.yaml becomes locale "en", es.yaml becomes "es".
Using @keys
Section titled “Using @keys”Reference locale strings with the @ prefix in YAML content:
id: tavernname: '@location.tavern.name'description: '@location.tavern.description'And in .dlg dialogue files:
NODE start BARTENDER: @bartender.greeting
CHOICE @bartender.choice.hello GOTO hello ENDHow Resolution Works
Section titled “How Resolution Works”At snapshot build time, the engine resolves all @key references:
- Looks up the key in the current locale’s data
- If found, returns the translated string
- If not found, returns the
@keyas-is (useful for spotting missing translations)
The resolution function:
import { resolveText } from '@doodle-engine/core';
const text = resolveText('@bartender.greeting', localeData);// → "Welcome! What can I do for you?"Changing Language at Runtime
Section titled “Changing Language at Runtime”Use the setLocale action:
const { actions } = useGame();actions.setLocale('es');Or from a dialogue effect. This isn’t built into the DSL, but can be done programmatically via the engine.
Naming Convention
Section titled “Naming Convention”Use a consistent key naming scheme:
# Locationslocation.<id>.namelocation.<id>.description
# Characterscharacter.<id>.namecharacter.<id>.bio
# Dialogue text<character_id>.<context><character_id>.choice.<choice_name>
# Itemsitem.<id>.nameitem.<id>.description
# Questsquest.<id>.namequest.<id>.descriptionquest.<id>.stage.<stage_id>
# Notificationsnotification.<event_name>
# Narratornarrator.<context>UI Strings
Section titled “UI Strings”The renderer’s interface labels (buttons, sidebar tabs, panel headers) are localized through the same locale files as all other text. Define ui.* keys in your locale YAML to override the English defaults.
If you don’t define a ui.* key, the English default is used automatically. You only need to add these keys for non-English locales or if you want to customize the wording.
| Key | Default |
|---|---|
ui.continue | Continue |
ui.inventory | Inventory |
ui.journal | Journal |
ui.notes | Notes |
ui.map | Map |
ui.save_load | Save/Load |
ui.settings | Settings |
ui.save | Save |
ui.load | Load |
ui.new_game | New Game |
ui.resume | Resume |
ui.no_companions | No companions |
ui.narrator | Narrator |
Example Spanish locale file:
ui.continue: Continuarui.inventory: Inventarioui.journal: Diarioui.notes: Notasui.map: Mapaui.save_load: Guardar/Cargarui.settings: Configuraciónui.save: Guardarui.load: Cargarui.new_game: Nuevo juegoui.resume: Continuar partidaui.no_companions: Sin compañerosui.narrator: NarradorNotification Strings
Section titled “Notification Strings”Notification effects use @key too:
NOTIFY @notification.quest_startednotification.quest_started: 'New Quest: Odd Jobs'