Guide

Game localization and i18n explained

A narrative RPG launches in English only. Six months later the studio adds Japanese and Brazilian Portuguese in a rush patch. Cutscene subtitles overflow their boxes, a quest item still says “Sword” in English inside German UI, and Arabic players see mirrored HUD elements clip through the minimap. Revenue from non-English markets never materializes because the experience reads as an afterthought. Internationalization (i18n) and localization (L10n) are not a post-launch checkbox — they are production disciplines that start in pre-production and touch every system that displays text, audio, numbers, or images. This guide covers the i18n/L10n split, string externalization and ICU MessageFormat, RTL and CJK layout, font and voice-over pipelines, pseudo-localization and LQA, cultural adaptation versus literal translation, platform certification requirements, a Harbor Atlas multilingual launch worked example, a tooling decision table, common pitfalls, and a shipping checklist — building on dialogue systems, UI and HUD design, and narrative design foundations.

Internationalization vs localization

Internationalization (i18n) is engineering work that makes a game capable of running in any locale without code changes: externalized strings, locale-aware formatting, flexible UI layout, and asset pipelines that accept translated content. Localization (L10n) is the content work: translating strings, recording dubbed VO, adapting marketing screenshots, and validating cultural fit. You cannot localize well without i18n; i18n without L10n ships a technically ready but English-only product.

Locale identifiers

Use BCP 47 tags consistently: en-US, ja-JP, pt-BR, ar-SA. Store the player’s active locale in save data and platform profile; fall back through language-only tags (pt) before defaulting to source language. Never key content off country alone — Canadian French (fr-CA) differs from European French (fr-FR) in vocabulary and formatting.

What must be locale-aware

  • All player-visible strings — UI, tooltips, item names, error messages, achievements.
  • Numbers and units — decimal separators, thousand grouping, metric vs imperial where relevant.
  • Dates and times — 12h vs 24h clocks, calendar order, time zones for live events.
  • Currency display — symbol position, ISO codes for multi-currency stores.
  • Sorting and search — locale-sensitive collation for inventory and leaderboards.
  • Audio and video — dubbed lines, subtitle timing, censored variants per territory.

String externalization and ICU MessageFormat

Hard-coded English in source files is the most common i18n failure. Every string belongs in a resource table keyed by stable IDs (quest.tutorial.pickup_sword), never by English text. Translators work against keys; runtime code looks up the localized value for the active locale.

Concatenation traps

Never build sentences from fragments like "You found " + count + " coins". Word order varies: Japanese puts the count differently; Arabic plural rules have six forms. Use ICU MessageFormat (supported by Unity Localization, Unreal’s LOCTEXT with ICU, gettext, and most TMS exports):

{count, plural,
  =0 {You found no coins.}
  one {You found # coin.}
  other {You found # coins.}
}

MessageFormat also handles gender (select), ordinal ranks, and nested placeholders. Designers author templates; translators adjust grammar inside each branch without touching code.

Context and comments

Ambiguous keys destroy translation quality. The string Close might mean a door action or dismiss a window. Attach developer comments to every key in your TMS: “Button label — closes inventory panel, not physical door.” Use screenshots linked to string batches so translators see layout constraints.

Layout, fonts, and right-to-left languages

German and Russian expand text 20–40% versus English. Japanese and Chinese often shrink horizontally but need larger line height. UI built with fixed-width labels will clip in every non-English locale unless you design for text expansion from day one: auto-sizing labels, scrollable containers, and max-line policies in HUD layouts.

Right-to-left (RTL)

Arabic and Hebrew require mirrored layout: navigation flows right-to-left, progress bars fill from the right, and asymmetric padding flips. Do not mirror gameplay geometry (race tracks, map north) — only chrome. Test with ar pseudo-builds early; Unity’s RTL Text Mesh Pro and Unreal’s culture-aware widget mirroring help, but custom UI frameworks need explicit mirror flags per panel.

Font stacks and CJK

Latin fonts rarely cover CJK glyphs. Ship fallback font chains: primary brand font for Latin, Noto or platform system fonts for CJK, dedicated Arabic script faces with correct joining. Dynamic font atlases (SDF) must include codepoint ranges for target locales or load locale packs on demand to control build size. Missing glyphs render as tofu boxes — an instant review bomb in Asian markets.

Audio, subtitles, and cinematics

Full localization is not text-only. Tier your audio strategy per budget:

  • Subtitles only — cheapest; still requires timed SRT/VTT per locale and line-length checks.
  • Partial VO — dub main quest; subtitle side content. Common in AA titles.
  • Full dub — studio sessions per language; lip-sync may use phoneme retargeting or accept mismatch in cinematic games.

Pipeline discipline: export line ID spreadsheets from your dialogue system with character, emotion, duration estimate, and MAX character count. VO directors record against timing; LQA compares final audio to subtitle files frame by frame. Cinematics need safe-area subtitle placement per aspect ratio and platform (Switch handheld vs TV).

Pseudo-localization, TMS, and LQA

Pseudo-localization

Before paying translators, run pseudo-loc: replace strings with accented variants ([!!! Hélló !!!]), pad length by 30%, and inject RTL markers. Pseudo-loc instantly reveals hard-coded strings, clipped labels, and missing font coverage. Automate it in CI on every nightly build.

Translation management systems

A TMS (Crowdin, Lokalise, Phrase, memoQ) is the hub between engineers and translators. Typical workflow: export JSON/PO/XLIFF from game build → TMS assigns to vendors → in-context preview (Unity/Unreal plugins) → review pass → import back → lock keys for shipped content. Version keys when narrative changes mid-project; stale translations cause silent regressions.

Linguistic quality assurance (LQA)

Translation is not shipping. LQA testers play the localized build natively, logging: wrong context, gender mismatch, overflow, untranslated leftovers, cultural offense, and broken placeholders ({0} visible in UI). LQA runs per locale after integration, not on spreadsheets alone. Budget 10–20% of translation cost for LQA; skipping it costs more in day-one patches and store refunds.

Cultural adaptation and platform certification

Literal translation fails for humor, idioms, and taboo topics. Cultural adaptation may rename food items, swap holiday events, or replace gestures that offend (certain hand signs, skull imagery in specific markets). Separate SKU variants when law requires: loot box odds disclosure (China, Belgium history), gore filters (Japan CERO, Germany USK), or gambling mechanic renames. Document what changes per territory so live-ops does not accidentally push banned content globally.

Console manufacturers require localization completeness before cert: no English leftovers in UI, correct platform language list, and proper rating body text. Nintendo, Sony, and Microsoft each publish TRCs with i18n checklists — treat them as acceptance tests, not suggestions.

Worked example: Harbor Atlas multilingual launch

Harbor Atlas is a cozy exploration game shipping day-one in nine languages. Pre-production decisions:

  1. String policy — all UI and quest text in Lokalise; keys namespaced ui.*, quest.*, item.*. No string literals in C# beyond debug logs.
  2. UI kit — buttons use min-width + padding, not fixed text width; tooltip panels scroll after three lines.
  3. Pseudo-loc CI — nightly build with qps-ploc locale; Slack alert on any untranslated key in player-facing scenes.
  4. Wave 1 translation — French, German, Spanish, Brazilian Portuguese at content lock; Japanese and Korean two weeks later for VO sync.
  5. RTL pass — Arabic added in beta; mirror only menus and dialogue boxes; map orientation unchanged.
  6. LQA sprint — native speakers per locale play 20-hour checklist: tutorial, inventory, online co-op chat filters, store pages.
  7. Day-one patch buffer — hotfix branch reserved for overflow fixes discovered in review streams.

Result: store pages list accurate language support; review scores in DE/JP markets match English because no tofu or clipped tutorial text appeared at launch.

Tooling decision table

Approach Best for Tradeoffs
Unity Localization package + Addressables Cross-platform Unity titles with asset bundles per locale Learning curve; string and asset tables must stay in sync
Unreal LOCTEXT + GatherText UE5 projects with native ICU support and PO export Re-gather discipline; avoid duplicate keys across plugins
JSON/CSV + custom loader Small indie, web, or custom engines You build plural rules, TMS sync, and hot-reload yourself
gettext (.po) pipelines Linux/native, Godot, some middleware Mature tooling; less in-engine WYSIWYG than Unity/Unreal
Spreadsheet-only (early prototype) Jam games, single-language vertical slices Does not scale; migrate before first external translator

Common pitfalls

  • Hard-coded strings — any literal in code will ship untranslated; grep CI for quoted UI text.
  • Concatenated sentences — breaks plural, gender, and word order in inflected languages.
  • Fixed-size UI — German button labels clip; plan expansion and ellipsis rules.
  • Translating before content lock — narrative churn wastes vendor budget and introduces inconsistencies.
  • Skipping pseudo-loc — discover layout bugs after translation invoices are paid.
  • Spreadsheet LQA only — context errors appear only in running game (wrong gender, broken quest chain).
  • One global SKU for censored content — regulatory violations block entire territory launches.
  • Ignoring platform font licensing — CJK font embedding rights differ by foundry and storefront.

Production checklist

  • Define day-one locale list and tier (text-only vs partial vs full dub) in pre-production.
  • Externalize all player-facing strings to keyed resource tables with developer comments.
  • Adopt ICU MessageFormat (or engine equivalent) for plurals, gender, and variables.
  • Design UI for 40% text expansion and dynamic font sizing.
  • Implement RTL mirroring for chrome; test Arabic layout before beta.
  • Configure CJK and Arabic font fallbacks; verify glyph coverage in target locales.
  • Integrate TMS with in-engine preview; automate export/import on build.
  • Run pseudo-localization in CI on every nightly player build.
  • Export dialogue with line IDs, timing, and character limits for VO vendors.
  • Schedule LQA per locale on integrated builds, not translation spreadsheets alone.
  • Document territory-specific content variants and cert requirements per platform.
  • Reserve hotfix capacity for overflow and untranslated string patches at launch.

Key takeaways

  • i18n is engineering readiness; L10n is translated content — both are required for global launch.
  • Keyed strings and ICU MessageFormat prevent grammar bugs that concatenation guarantees.
  • Layout, fonts, and RTL must be designed early; retrofitting costs more than translation.
  • Pseudo-loc, TMS, and LQA form a pipeline that catches bugs before players and cert do.
  • Cultural adaptation and SKU variants are product decisions, not translator afterthoughts.

Related reading