Unreal Localization Support

Tim Sweeney
Epic MegaGames, Inc.
tim@epicgames.com
http://www.epicgames.com/

Audience: UnrealScript Programmers, C++ Programmers,  Translators.
Last Updated: 05/01/99

External Localization Links

Overview of Unreal localization support

The design goals for Unreal's translatability are:

The approach we chose is to place localized text in .ini style files which correspond to Unreal package files.  Translation capability is available in UnrealScript and C++ in three key areas:

Authoring UnrealScript code for translatability

Put all readable text into string instance variables, and use the "localized" keyword to designate them as localized, and use the "localized" keyword when declaring the class.  For example:

This code will be a bitch to translate because it will require messing with the code:

class OuchSayer expands Trigger;
function Trigger( Pawn A, Actor B )
{
	A.Message( "Ouch, you touched me!" );
}

This code will be easy to translate because it can be done in an .ini file by a non-programmer:

class OuchSayer expands Trigger localized;
var() localized string[64] Msg;
function Trigger( Pawn A, Actor B )
{
	A.Message( Msg );
}
defaultproperties
{
	Msg="Ouch, you touched me!"
}

The other advantage of this approach is that it makes it easy for a writer to go through and clean up the English text in a game.  This has been beneficial in Unreal development, because we have a lot of level designers and programmers writing game text which needed reworking due to stylistic inconsistencies.

Character set

Unreal is designed to use the 16-bit UNICODE character set.  The standard Unreal fonts include only the first page of UNICODE language characters, but our built-in TrueType font importer enbales you to import (with optional antialiasing) any Unicode TrueType font, i.e. for piecing together Unreal fonts that support the roman languages, Japanese, and Korean.

Localized file extensions

Each language has a characteristic file extension, which Unreal uses to try to find the localized text for a given package file.  For example, we define the following extensions:

When Unreal loads a package file (such as an .unr level file, or a .u class file), it searches for localized text in the following places. For example, when loading MyLevel.unr:

Preparing level text for translation

Lots of game text is stored within .unr level files, for example the text messages stored with Counters, Triggers, and TranslatorEvent actors.  The intent is that level designers will write the first-pass version of this text in English, and then the text will be localized (or the English version cleaned up) by a translator or writer, who edits the .ini files and never modifies the .unr level file itself.

Not modifying binary data files (such as .unr level files, and .u class files) is an important concept, because many aspects of Unreal, including network play, rely on the exact binary contents of these data files.  If translations were performed by having someone actually modify the .unr levels, or .uc scripts (thus affecting the .u binary files), it would be impossible for French or German people to play on American Unreal servers, etc.

UnrealEd supports a special console command analyze an Unreal binary file (such as an .unr or .u file) and generate an .ini style text file containing the international English version of the text.  For example, to process UnrealI.u, type on the console:

    dumpint UnrealI.u

And that generates the file UnrealI.int, the international text for the package.   That file can then be given to translators, who rename it to their appropriate language's extension (such as UnrealI.fr or UnrealI.de) and translate all of the text within.

Hardcoded C++ translation support

CORE_API const char* Localize( const char* Section, const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeError( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeProgress( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeQuery( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeGeneral( const char* Key, const char* Package=GPackage );

Hardcoded UnrealScript translation support

intrinsic function string[192] Localize( name KeyName, name SectionName, name PackageName );

Debugging translations

When a C++ or UnrealScript localization function is called for which no corresponding localized .ini file entry is found, the returned string is displayed as <?Package.Section.Key?>, and an entry is written out to the log to record the missing translation.  This is a non-critical error.  Because this is easy to screw up, I recommend coverage testing all lines of code which lookup localized text.

Non-technical information for translators

You can edit .int files with a text editor like Notepad.  A typical .int file will contain a lot of data that looks like this:

[Errors]
FileOpen=Error opening file
FileNotFound=Can't find file '%s'
FileClose=Error closing file

[Progress]
Saving=Saving file %s...
Closing=Closing

Bold text indicates the text to be translated.  For clarity, these .int files contain three kinds of data:

So, for example, the result, translated file above might look like:

[Errors]
FileOpen=Fehleröffnung Datei
FileNotFound=Kann nicht Datei %s finden
FileClose=Schließende Datei des Fehlers

[Progress]
Saving=Einsparungdatei %s...
Closing=Schließen

There are several important points to keep in mind:

Limitations

End