Back to Blog
localizationworkflowproductionui

Localization Debt: Keeping Your Game Translatable While You Still Have Time

Concatenated sentences, baked-in text and fixed-width buttons quietly make your game untranslatable. Here are the habits, the expansion budget and the pseudo-localization test that keep shipping in eight languages a business decision, not a rewrite.

GameDesignerX TeamSeptember 10, 20267 min read

Your shop UI says "Buy 3 Iron Ingots". Twenty-two characters, fits the button with room to spare. The German build says "3 Eisenbarren kaufen" — fine. The Russian build needs a different word ending depending on whether the number is 1, 3, or 5. The Finnish build overflows the button by a third. And somewhere in your codebase, that string is assembled as "Buy " + count + " " + item.pluralName, which means no translator can ever fix any of it.

That is localization debt. Like technical debt, it accrues quietly while you build, and the interest is paid in the last month before launch — the exact month when you have the least slack. The good news: almost all of it is avoidable with habits that cost nothing while you are still prototyping.

What localization debt actually looks like

You do not need to translate anything to start accumulating this debt. Five patterns cause most of it.

1. Sentences assembled from fragments

"You found " + n + " " + itemName + "!" is the classic. English tolerates it. Most languages do not, because word order, article, case, and adjective agreement all depend on the noun you are splicing in. German wants "Du hast 3 Eisenbarren gefunden!" — verb at the end. Any language with grammatical case needs the noun in a different form depending on its role in the sentence.

The fix is to make the whole sentence one translatable unit with named placeholders:

item_found = "You found {count, plural, one {# {item}} other {# {item}}}!"

That is ICU MessageFormat, the format Unicode's CLDR data is built around and the one most engines and middleware understand. The translator gets the full sentence and can restructure it however their language needs.

2. Plural rules that assume English

English has two plural forms. Arabic has six. Russian and Polish have three or four depending on the number's last digits. Japanese has one. If your code does if (n === 1) singular else plural, you have hard-coded English grammar into your logic layer, and no amount of translation fixes it. ICU plural categories (zero, one, two, few, many, other) exist precisely so translators can supply whatever set their language uses.

3. Text baked into art

Every sign, banner, tutorial poster, and animated title card with letters painted into the texture is a re-export per language. If your game has 40 such assets and you ship 8 languages, that is 320 exports and 320 chances to ship the wrong file. Decide early which signage is diegetic set dressing (fictional script, never translated — fine to bake) and which is information the player needs (must be a text layer over a blank texture).

4. Fixed-width UI

A button sized to fit its English label will break somewhere. Localization industry guidance has long used a sliding expansion allowance based on source length: the shorter the string, the more it can grow.

English source length Plan for growth of Example
1–10 chars up to 200% Buy, Save, HP
11–20 chars up to 100% New Game, Inventory
21–30 chars up to 60% Continue Campaign
31–50 chars up to 40% short tooltips
50+ chars 20–30% body text, item descriptions

Treat these as design constraints, not predictions. A three-letter button that must survive 200% growth needs a layout that grows or wraps — not a fixed 64px box.

5. Strings with no context

A translator working from a spreadsheet sees Fire and has no way to know whether it is the element, the verb for shooting, or the command to dismiss an NPC from your crew. They will guess, and roughly a third of the time they will guess wrong on exactly the strings that matter most. Every string needs a comment: where it appears, who says it, what the character limit is, whether {name} is a player or an item.

Set up the string table before you need it

The single highest-leverage habit is that no string is ever typed directly into a scene, prefab, or blueprint. Everything goes through a key. Even in a jam prototype it costs about ten seconds per string.

A workable key convention:

ui.shop.button.buy
ui.shop.error.insufficient_funds
dialogue.act1.mira.greeting_first_meeting
item.iron_ingot.name
item.iron_ingot.description

Namespaced, lowercase, no spaces, describing location and purpose rather than content. ui.shop.button.buy survives a rewrite of the button text; a key named buy_3_iron_ingots does not.

Alongside each key, store four fields your translators will need: source text, context note, maximum character count, and a "do not translate" flag for proper nouns and codenames. If you keep your dialogue in GameDesignerX's dialogue trees and your terminology in the lore bible, the localization module is where those two feed into a single export — the point being that character names, faction names, and item names get one canonical spelling across every line before a translator ever sees them. A glossary built after translation starts is a glossary built too late.

Pseudo-localization: the cheapest test you will ever run

Before you spend a cent on translation, run a fake one. Pseudo-localization transforms every string automatically:

Buy 3 Iron Ingots
→ [!!! Ḅŭẏ 3 Ïŕōń Ïńġōţś ~~~~~~~~ !!!]

Three things happen at once. Accented characters expose fonts missing glyphs and any code that assumes ASCII. The padding (roughly +40%) makes every layout overflow visible immediately. The bracket markers reveal concatenation — if you see [!!! You found !!!][!!! 3 !!!], you found a spliced sentence. Anything still rendering in plain English is a hard-coded string that never made it into the table.

Write the transform yourself in an afternoon, wire it to a debug key, and run the game in pseudo-loc once per milestone. It catches the structural problems while they are still cheap, in a build nobody has to pay a translator to produce.

Order of operations

Translation is expensive and re-translation is worse, so sequence it against your content lock:

  1. Prototype → vertical slice: keys and string table only. No translation. Pseudo-loc runs enabled.
  2. Production: UI and system strings are stable enough to translate first — they are short, high-visibility, and rarely rewritten. Build the glossary here.
  3. Content lock: narrative and dialogue go out only after the script stops changing. Dialogue is the largest word count and the most sensitive to rewrites.
  4. Post-translation: linguistic QA in-build. A translator reading a spreadsheet cannot see that a line is clipped, mistimed, or attributed to the wrong speaker. Budget real time for someone to play each language.

If budget forces you to pick, translate UI and store page copy before dialogue. A player can enjoy an English-voiced game with a localized interface; they cannot navigate a menu they cannot read.

Checklist

  • No literal strings in scenes, prefabs, or blueprints — everything through a key
  • Namespaced keys describing purpose, not content
  • Full sentences with named placeholders; no runtime concatenation
  • Plurals via ICU categories, not if (n === 1)
  • Context note + char limit on every UI string
  • Glossary of names and terms locked before translation starts
  • Do-not-translate list for proper nouns and codenames
  • Layouts that wrap or grow, sized against the expansion table
  • Fonts cover every target language's glyph set (CJK and Cyrillic are the usual gaps)
  • Pseudo-localization build runs at every milestone
  • Dates, numbers, and currency formatted by locale, not hard-coded
  • Linguistic QA scheduled in-build, not just in the spreadsheet

Start this week

You do not need a localization plan. You need three things: a string table with keys, a pseudo-loc toggle, and a rule that nobody types visible text into a scene. Do those while your game is 200 strings instead of 12,000, and the decision to ship in eight languages stays a business decision — not an engineering rewrite you cannot afford six weeks before launch.