Questions? Want it tailored to your project? Ping me at xabk+loc.checklist at xabk.net

Keep all text accessible, editable – and separated from code

To make text localizable in Unreal, it has to be an FText variable or property. Unreal Engine has a system that gathers text for translation from FTexts in the project.

Use Unicode and be ready to look for new fonts

Use Unicode or UTF-8 if you plan to ever localize your game. And be ready that your beautiful English font won’t support characters from other languages – you’ll have to find a new font.

A nice tool to check what languages a font supports: https://www.alphabet-type.com/tools/charset-checker/. A good place to start looking for international fonts: https://fonts.google.com/.

Give each string a unique ID

Unique IDs help keep the devs and the translation/QA team on the same page. They help CAT tools with pretranslation/x-translation, which saves you time and money when it comes to localization of game updates. Also, make your IDs organized and descriptive: see descriptive IDs below.

Don’t reuse strings – or do it sparingly

Using the same strings in several spots in your game might work in your source language and some other languages but it also makes it impossible to translate naturally into other, more context-sensitive languages or languages with more complex grammar. Never reuse strings in dialogs and story texts, not even a simple ‘OK’. You might get away reusing strings in simple, standard UI elements but it’s better not to do it. A universal term might exist in your language but there might be no such term in other languages and your UI will look bad.

One clear exception is when you have a lot of items or other entities in your game and you have to include them into other phrases: feel free to reuse those but know that it might lead to unnatural or erroneous translations in other languages due to grammar differences. One way to avoid this is to use a system that allows for plurals and grammatical gender and case branching but those are too complex for most projects.

Don’t use localizable text in your logic

It’s better to never use user-facing localizable text in your in-game logic because it will fail when that text is localized and your comparison criteria are not. It’s best to avoid that altogether by using keys or indices for comparison, without relying on text values. If you can’t do that, make sure that your criteria are dynamic and localized, too, and that it’s localized identically to the UI text. One way to do it is a table or map of pairs of non-localizable keys and localizable values: use the values for UI but you always look up the key by value to later use that key in your logic.

Expect translations to be longer or shorter than the original

Many languages need more space than English to convey the same information naturally. Sometimes, translators can make things fit. Sometimes, it’s just impossible.

Here’s a quick guide on how the text length changes based on its original length:

Characters in English Avg. translation length
10 or less 200–300%
11-20 180–200%
21-30 160–180%
31-50 140–160%
51-70 130–140%
More than 70 70–150%

Short strings routinely get 2-3 times longer in other languages. Sometimes more. On the other hand, some languages are significantly shorter than English.

Create an adaptive UI and provide character limits when it’s impossible to stretch things too much. Be ready to work on issues where it’s simply impossible to fit things into the UI in one language or another.

Avoid concatenation, use moveable variables and full phrases

Use full phrases with descriptive variable names (e.g, “Hero {hero_name.string} is now level {level.number}”. This will help translators understand what the variable represents and also allow them to move things around and make the translation sound natural in their language.

Never concatenate lines from parts like “Hero” and “is now level”, mixing in the data in between: this is a recipe for disaster. Never use positional variables like “Get %s for %s”. Don’t be lazy with variable names.

Don’t use leading and trailing whitespace

It might get lost in translation and break whatever you’re using it for. It is often a sign of concatenation (“Part 1 ” + something + “ part 2”) and you shouldn’t do this for the reasons stated above. Sometimes it’s also used to format the UI by placing the label and the UI element it labels right next to each other and using a trailing or leading space in the label text to create some padding – you shouldn’t do it either, just use add a spacer in between or use padding to separate the label and the input element. If you’re displaying static text consider using rich text and a full phrase (“Your DPS is <color>{int_dps}</>”): this way translators can move the variable around and adapt the formatting to their language traditions, e.g. remove or add spaces.

Use descriptive IDs and variables

Use descriptive IDs and variables. Treat this like you would treat your code: it has to be readable and easy to understand.

An ID like “edit_account_window.caption” for the “Edit Account” string will help translators a lot: they’ll know it’s a window caption and not a call-to-action or button and choose the appropriate translation (yup, these things don’t sound the same in most languages). An ID like “button.lock_item” for a string like “Lock” saves you from the inevitable question: what’s this, a noun, a verb, is it an action or a call to action?

Do not overuse variables – or keep grammar differences in mind

Even though you should use variables and full phrases, please keep in mind that grammar differs a lot between languages. English tends to be very variable-friendly since words don’t change much and plurals are simple. Words in other languages change much more often and depend on many more things: gender, case, etc. Whole chains of words can change depending on the gender of a single word. Plurals and ordinals also work differently.

It’s better to use variables only for numbers, and even then have a system for plurals in place. If you absolutely have to use variables for items or names or other nouns, you can use a system that can be adjusted for different languages, like ICU syntax for complex things or POGettext-like plurals for simple ones – just don’t overdo this or it quickly becomes impossible to translate and maintain.

Add context to your strings

Same as before: treat your text as you treat your code. Make it readable and easy to understand for people who are not as familiar with the project as you are. Add comments and context to the strings, as much as you can. Explain jokes and references. Describe how this or that line is used. Always clarify what the variables mean. In a dialogue, always specify who’s speaking and, if possible, who they are talking to.

Context is king. Translators don’t have psychic powers to tell the exact meaning of a single out-of-context word and know how it’s used. No one will get all the references and jokes – that’s just too much to ask.

Be ready to answer questions and help the team

You’ll have far fewer questions if you prepare the text for localization by using proper naming conventions and adding comments. But there will always be things that are unclear or things that require your attention and knowledge. Things that only you can help with. Choices only you can make. Be ready for this.

Be ready to adapt things for the target culture and market

If you want to be successful in a new market you have to take cultural differences into account and adapt your game. Most likely, you’ll have to adapt the text. Sometimes you’ll have to adapt the visuals. The sooner you start working with a professional localization team, the easier and cheaper it will be to adapt things later.