Localizing your project

As the progress of technology marches on, the world seems to become a smaller place and your game may well end up being played on devices all across the globe. It's therefore well worth considering localizing your game so that players across the world can experience your game in their own language.

While supporting every language known to man would be impractical, many best-selling games now offer support for at least the EFIGS languages (English, French, Italian, German, and Spanish), and you can often add Portuguese, Russian, Polish, Japanese, Korean, and both Simplified and Traditional Chinese to the list as well.

Supporting other languages other than your own native tongue is well worth it, as players would much rather play a game they can read and understand than one they can't.

Whether or not you decide to support other languages, there is still a benefit in implementing your game's text in the manner I am about to describe, since it allows you to remove all the text from your source code and put it all in one place, which makes changing the text a much easier process.

Creating a text spreadsheet

The first step in localizing the text in your game is to use a program such as Microsoft Excel or OpenOffice Calc to create a spreadsheet containing all the text for your game. By using a spreadsheet it is very easy to add or insert new strings of text, and the columns of the spreadsheet can be used to provide translations of the strings for each language you want to support. The following screenshot shows an example of such a spreadsheet:

Creating a text spreadsheet

In this spreadsheet the first column is used as a text identifier field. This is just a string of text that we can use in our source code and datafiles to represent a particular string of text.

The first row is used to indicate which language each column of the spreadsheet represents. In the example, we have used the standard two letter ISO country codes to represent the supported languages, namely English (EN) and French (FR).

The rest of the spreadsheet is then just the actual text that we want to appear in the game.

Getting the text into the game

With the text for our game now in a spreadsheet, how do we access it from inside our game code? The answer is to process the spreadsheet into a format that is easy for us to load and use in game code.

Comma-separated values files

One option would be to export the text as a Comma-Separated Values (CSV) file from our spreadsheet program. This is a simple text-only format that outputs each row of the database as a separate line in the file, with the contents of each cell listed separated by commas.

The trouble with this approach is it can be error-prone. Having a comma in the text of one of your strings can play havoc with the output since the comma is already used to indicate the end of one string and the beginning of the next. This is often gotten around by enclosing each string in quote marks, but then this can cause further problems if a string needs to include a quote mark too!

Remember also that IwGxFont expects text to be supplied in UTF-8 format by default. If you are supporting languages such as Japanese or Korean, this becomes very important and some spreadsheet programs do not support exporting a CSV File in UTF-8 format.

Processing using a Python script

A much better method of getting the text out of a spreadsheet and into our game is to process the spreadsheet into a simple datafile, which can be easily loaded into our game. To demonstrate this, we'll be making use of the Python scripting language.

Python may have a rather strange approach to code layout (the scoping level of your code is indicated by how much it is indented, rather than using notation such as curly braces to indicate the start and end of a section of code), but there is no denying that it is extremely good at this kind of task.

You can get hold of an installer for Python from the following URL:

http://www.python.org/download/

The approach we will be using is to access the data from the text spreadsheet by accessing it directly. If we save the spreadsheet in Excel 97 format (file extension .xls, supported by most spreadsheet programs), there is an excellent Python library called xlrd that can be downloaded here:

http://pypi.python.org/pypi/xlrd/

Install Python first and then install the xlrd library. It's a good idea to ensure that the Python executable can be easily found by adding the Python install directory to your path environment variable. An easy way to check if the Python directory is already in your path variable is to open up a command prompt window and enter path to display the current list of directories that will be searched.

To illustrate just how simple accessing data from a spreadsheet file is, using Python and xlrd, the following script will open a spreadsheet file and output all the rows and columns it contains:

import xlrd

lXLS = xlrd.open_workbook("StringList.xls")
lSheet = lXLS.sheet_by_index(0)
for lRow in range(lSheet.nrows):
  lCells = lSheet.row_values(lRow, 0, lSheet.ncols)
  print lCells

Even if you've never set eyes on a Python script before, this should be fairly easy to follow, but here's a brief explanation.

The import xlrd line is equivalent to the #include directive in C/C++. It's just stating that we want to make use of the xlrd library.

Next we open the spreadsheet file by calling the xlrd.open_workbook method, passing in the filename of the spreadsheet we want to use. This returns an instance of a Python class defined by xlrd that represents the spreadsheet file. Note that Python is a loosely typed language and there is no need to declare what type the variable must be.

We call the sheet_by_index method on the spreadsheet object to retrieve the first worksheet from the spreadsheet. This yields another Python object representing the worksheet.

We then enter a for loop that causes the lRow variable to iterate between 0 and the number of populated rows in the spreadsheet. Within the loop we use the worksheet object to access the spreadsheet cells an entire row at a time using the row_values method.

Python has a built-in list type and this is what is being used to access all the cells on the row in one go. The lCells variable will contain a list whose elements are each cell in the row.

Finally we use the Python print command to display the entire list to standard output. You can use print in Python to display just about any type, including lists, in a human-readable form.

The UI example project that accompanies this chapter includes a Python script that will take a spreadsheet as input and convert it into a simple datafile for each language contained in the spreadsheet.

The datafiles list the number of strings in the file followed by a hash value generated from the text identifier field (the first column of the spreadsheet) and the string itself. It is fairly trivial to write C++ code to load this file into memory.

Note

The use of a hashing function here means it is possible for two strings to end up with the same hash value, causing a collision in the string table that means the wrong string may get returned. In practice a good hashing function will mean this hardly ever happens, but if you start getting the wrong string returned this might be the cause. The easiest way to rectify such a problem is just to rename one of the text identifiers in the collision!

To access a particular text string, we use the identifier field in our code. A hash value is generated from the identifier field and the list of string data is searched for that hash value. If a match is found, the corresponding text string is returned, otherwise an assert can be raised and a default string of text returned. The default text can be something like "Missing String!", which makes it easier to track down problems such as getting the identifier field wrong in code, or the string just not being present in the text datafile when it should be.

Selecting the correct language to use at runtime

We now have the ability to supply our game with strings of text in multiple languages, but how do we decide which of those languages to actually use? One method of course is to implement a language select screen during startup of our game and then load the relevant string table depending on the user's input. However, there is a much nicer way available to us.

The s3eDevice API allows us to find out which language is currently in use on the device we are running on. Simply insert the following line of code during the startup portion of your game code:

int32 lLanguage = s3eDeviceGetInt(S3E_DEVICE_LANGUAGE);

The return value will be a member of the s3eDeviceLanguage enumeration, for example S3E_DEVICE_LANGUAGE_ENGLISH or S3E_DEVICE_LANGUAGE_GERMAN. A full list of all possible language codes can be found in s3eDevice.h.

With the language type determined by this call, we can then load the correct table of strings and the user will magically get to see your game in their own language, assuming you've supported it of course!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.178.9