游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

分享开发者执行本土化策略的技巧

发布时间:2014-03-14 15:00:52 Tags:,,,

作者:Jean-Claude Cottier

本土化:致胜策略

由于数字发行渠道的崛起,我们现在得以进入全球市场,我们有许多潜在用户并非英语用户。对你的应用进行本土化处理可以增加它们的全球覆盖率,为你的公司开创新机遇。你可能会去寻找对你的产品感兴趣的本地合作伙伴和经销商。只要你布置好一切并优化你的开发流程,多支持几种语言并非一项复杂的任务。Ovogame的多数应用支持多门语言(英语、法语、德语、西班牙语、意大利语、俄语、日语等),这会让我们从非英语市场多创造45%的收益。我将在本文分享关于本土化策略的技术方向和策略。我们在Ovogame团队是使用自己的多平台引擎(支持Android、iOS、Windows、OSX、BB10)。因为我们可以将这些技术运用于所有系统,所以会尽量保持平台兼容性。

代码没有文本

处理本土化的最佳方法就是在项目刚开工时就考虑这一点。你不应该将主要支持语言(英语)同其他支持语言区别对待。英语可以是默认设置选项,但除此之外,它不应该同其他语言存在区别设置。

这里的黄金法则就是永远不要在你的源代码中植入硬编码的文本,而要将其存储于一个外部文件中(像其他数据一样)。支持不同的语言意味着要为每种语言创造不同的文件夹,并载入正确的文件。

因为你无法在代码中植入任何文本,最佳方法就是用关键字来处理这个问题。例如,你想展示一个类似于“Hello World”的问候信息,你就可以使用关键字GREETING来代替。你的代码看起来如下所示:

String message = Translate(“GREETING”);
DisplayText(message);

Translate这个函数会返回正确的展示句子。如果应用语言设置为英语,它就会返回“Hello World”,但如果是法语,那就是“Salut monde”。Translate函数需要一个与其本土化句子相链接的简单关键字列表。它会扫描这个列表,并在找到正确的关键字时,返回相应的文本。实际上,最好是缓存这个字符串,没有必要每帧都调用Translate。

linklist(from gamasutra)

linklist(from gamasutra)

使用关键字是很好的做法,因为你在阅读代码时仍然能够理解它们的意思。因为它们是合适的字符串,你就可以动态地创造关键字来简化你的代码(尤其当它们索引为RATING_0, RATING_1 …的时候)。

使用Excel或Open Office

我们喜欢使用Excel文件来存储我们的本土化内容,因为它具有多种优势。人人都可以查看和编辑这些文件,所以本土化或校对文本的人就会对这种格式更为得心应手。你可以添加更多信息(额外栏目和行列),使用不同的颜色来区分。它还很便于提供图片的链接(这通常比长篇内牍的文字说明要好)。Excel整体上是一个创造和管理所有本土化内容的实用工具。

excel(from gamasutra)

excel(from gamasutra)

另一个极大的优势在于,它可以自动创建你的数据库。你的关键字及其本土化内容之间的关系一目了解:每一行包含一个关键字及其对应的翻译(存储在两个连接的格子中)。我们需要精简这一信息的方法,这样你可以将其运用到自己的应用中。Excel文件很复杂,并且编写一个函数来读取这种文件格式是非常费劲的工作。所幸我们并不需要这样做,因为我们很容易将其转化为基本的ASCII文本文件。如果你认真对待本土化策略,就应该令文本文件支持每字符两个字节的格式。如果你想本土化为日语或中文,你就必须支持这种格式。这并非强制性要求,只是说如果不支持该格式就很可异了。要将你的字符存储为16位而非8位。

在转换你的Excel文件之前,你可能想进行一些清理。你应该移除所有不需要的信息,仅保存前两个行列(关键字和本土化内容)。

excel_clean(from gamasutra)

excel_clean(from gamasutra)

如果你使用微软Excel来转化文本,只要将其保存为Unicode(*.txt)文本文件即可。这个新文件只包含以16位存储的ASCII字符。如下图所示,这是一个非常简单的格式。你可以直接运用于自己的应用。

format(from gamasutra)

format(from gamasutra)

记住该文件中每个ASCII字符都用两个字节存储(16位)。该文件从一个你可以跳过的幻数开始(1个字符:ASCII值65279)。用一个TAB字符(ASCII值9)来隔开关键字和本土化内容。用一个回车键(ASCII值13和10)来隔开不同的行列。如你所见,编写一个函数将这个文件载入内存,并创造一个链接列表或这些关键字/本土化配对的查找表格并不困难。

如果你使用的是Open Office,那就可以将文件存储为Text CSV(.csv) (*.csv),针对“字符集”使用UNICODE选项。该文件格式与之前并不相同,但你自己判断出其中的差别并非难事。

选择正确的语言

在这个阶段,你每种支持语言都有一个特定的文本文件。你只需要载入正确的文件即可。有个很好的小功能就是自动选择设备所使用的语言。所以,如果该设备设置为法语,你的应用就会自动从法语开始。在多数平台中,我们很容易找到你的设备所设置的语言。例如,在Android平台,你可以简单地从自己的Activity类中调用一个功能:

Configuration config=getApplicationContext().getResources().getConfiguration();
String lang = config.locale.getLanguage();

getLanguage函数返回了像en(English)、fr(French)、de(German)这类字符串。如果你并不支持该语言,就应该查查语言的值,将其设置回默认状态(在我们的项目中,英语是默认语言)。这个字符串将用于辩认你的应用生命周期中的当前语言,所以要确保它的安全性。你可以使用这些简称(游戏邦注:例如en、fr、de……)为文件设置一个简单的命名范例。

folder(from gamasutra)

folder(from gamasutra)

有了这个范例,我们就很容易知道该载入哪个文件了。此外,你还可以动态地发现自己的应用是否支持某种语言:只要检查对应的语言文件是否存在即可。这样,你就可以在无需更改一行代码的情况下添加新语言。

这是个尽量让你的代码保持通用性,并且自我处理资产(基于数据导向而非代码导向)的好方法。

如果你是面向不同的平台(iOS, OS X, Windows等)开发应用,你就会在所有系统中发现类似getLanguage的函数。

本土化其他资产

有时候,你所需要本土化的内容并不仅局限于文本。你可能有一些包含了编写内容的纹理。你应该使用与之前相同的命名惯例。

gameover(from gamasutra)

gameover(from gamasutra)

为了简化你的代码,你应该使用一个简单的函数创造你的本土化纹理名称:

String name = LocalizeName(“gameover”, “png”);

LocalizeName函数连接了当前语言和扩展名(例如.png)。所以,如果该语言是西班牙语(es),该返回名称就会是gameover_es.png。

你可能有一些资产需要转化成其他语言,但并非所有资产都要转化。例如,在法国,我们习惯使用英式英语的“Game Over”(如果翻译出来听起来就会很怪)。如果只是为了创造一个伪劣的本土化内容(gameover_fr.png)而直接复制默认资产,那就太糟糕了。LocalizeName函数可以检测文件是否存在(它需要完整的路径)。如果文件并不存在,该函数就要返回默认文件的名称。例如,在法语中,LocalizeName就会返回gameover_en.png。

找到合适的人

你应该与使用当地语言的人合作进行本土化操作。不要使用诸如谷歌翻译、Babel Fish等自动翻译工具(网络软件)。因为这些软件的翻译结果太糟糕了,还不如只保留英文设置。

你可以通过许多网络服务找到翻译人员,例如dystranslations.com和tethras.com,但我们从来没有使用过这个方法,只是听说许多游戏开发者推荐这类服务。

我们还发现了一个获得积极翻译者的替代方法。我们询问自己的游戏粉丝,看他们是否愿意代劳。他们喜欢我们的应用,也几乎像我们一样了解这些游戏。所以我们就同这些用户建立了更为密切的关系,这比通过网络服务聘请翻译人员更有效率。他们非常乐意执行最棒的本土化操作,我们向他们发送beta版本,这样他们就能测试自己的翻译是否完美。这就好像他们就是团队的一部分一样。

最后建议

尽量为你的翻译人员提供更多与应用相关的细节。如果他们(像我们的粉丝一样)能够测试合适的版本,那就更好了。他们对你的应用了解得越多,就能提供越地道的翻译。

这里要注意你的UI(按钮、信息框等)大小。多数英语文字相比其他语言都会显得比较小。通常情况下,德语文字更长,最好检查一下它们是否适合你的UI。此外还应该找个方法自动调整你的文本,这样你就可以确定它是否总能够处于特定区域内(例如按钮)。

可以在你的文本中添加格式化信息,例如“Chapter [NUM]”包括 [NUM]这个标签。我们就会在代码中用合适的索引来取代它(Chapter 1, Chapter 2…)。这一点非常管用,因为有些语言的格式化方式完全不同(在中文,这个标签是处于中间,第[NUM]章)。使用这个方法可以消除多数格式化问题。

在本土化操作时还要考虑其他许多方面的问题(字体、测试等),但这并非本文讨论的范围。希望本文内容能够在技术层面上为你的本土化操作提供有效建议。本土化是增加你的应用曝光度的一个简单方法,也是你应该考虑的措施之一。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

Localization: a Winning Solution

by Jean-Claude Cottier

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.

The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

Localization: a Winning Solution

Thanks to digital distribution, we now live in a global market and a lot of our potential customers simply don’t speak English. Having your applications localized will increase their global reach and will open new opportunities for your business. You’ll be more likely to find local partners and distributors interested in your products. Supporting more than one language isn’t a complex task once you’ve setup everything and streamlined your development process. Most of Ovogame’s applications are localized in many languages (English, French, German, Spanish, Italian, Russian, Japanese, etc.). It’s well worth it for us as we generate about 45% of our income from non-English-speaking territories. In this article, we’ll give you directions and tips about the technical side of localization. At Ovogame, we are using our own multiplatform engine (Android, iOS, Windows, OSX, BB10). As it is possible to use these techniques on all systems, we’ll stay as platform-neutral as possible.

No Text in Your Code

The best way to handle localization is to think about it from the start of your project. You shouldn’t treat your primary language (English) differently than the other languages supported by your apps. English may be set by default, but that should be the only difference with the other languages.

The golden rule is to NEVER have any text hard-coded inside your source code. Instead, it should all be stored in an external file (like any other data). Supporting different languages means creating different files per language and loading the correct one.

As you can’t have any actual text in your code, the best way is to handle them with keywords. For example, if you want to display a greeting message like, “Hello world,” you could use the keyword GREETING instead. Your code could look like this:

String message = Translate(“GREETING”);
DisplayText(message);

The function Translate returns the correct sentence to display. If the application language is set to English, it will return, “Hello world,” but if it’s in French, “Salut monde.” The function Translate needs a simple list of keywords linked to their localized sentence. It will scan this list and once the right keyword is reached, it returns the corresponding text. In practice, it’s wise to cache this string; there is no point to call Translate every frame.

Using keywords is very nice because you can still understand their meaning when reading your code. As they are proper strings, you can build some of them dynamically (mainly when they’re indexed: RATING_0, RATING_1 …) to simplify your code.

Using Excel or Open Office

We like to use Excel’s files to store all our localizations and there are many good reasons for this choice. Everyone can view and edit these files, so the persons localizing or proofreading your text will be comfortable with this format. You can add more information (extra columns and lines) and use different colors to help them. It’s also easy to provide links to images (often better than a long speech). Basically, Excel is a very practical tool for creating and managing all your localization.

The other great advantage is that your database is automatically created. The relationship between your keywords and their localizations is obvious: each line contains a keyword and its corresponding translation (stored in two consecutive cells). We need a way to extract this information so you can use it in your application. Excel’s files are complex and coding a function to read such a file format would be a lot of work. Thankfully, we don’t have to do this because it’s easy to convert them into a basic ASCII text file. If you are serious about localization, you should handle text files supporting two bytes per character. If you want to localize in Japanese or Chinese, you must support this anyway. It isn’t mandatory, but it would be a shame to not support it. Simply store your characters in 16 bits instead of 8 bits.

Before converting your Excel file, you might want to do a bit of cleaning first. You should remove all unwanted information and just keep the first two columns (keywords and localizations).

If you are using Microsoft Excel to convert your file, simply save it as a Unicode text (*.txt) file. This new file contains only ASCII characters stored on 16 bits. As the following picture shows, it’s a very simple format. You can use it directly in your application.

Remember that every ASCII character in that file is stored using two bytes (16 bits). The file starts with a magic number (one character: ASCII value 65279) that you can skip. A TAB character (ASCII value 9) is used to separate the keywords from their localization. A carriage return (ASCII value 13 and 10) is used to separate the different lines. As you can see, it isn’t difficult to code a little function to load this file into memory and create a linked list or lookup table of these keyword/localization pairs.

If you are using Open Office instead of Microsoft Excel, you can save your files as Text CSV (.csv) (*.csv) using UNICODE for the ‘character set’ option. The file format isn’t the same as the previous one, but you won’t have difficulties figuring out the differences by yourself.

Selecting the Correct Language

At this stage, you have a specific text file for each of your supported languages. You just need to load the correct one. A nice little feature is to automatically select the language used by the device. So, if the device is set to French, your application could automatically start in French. With most platforms, it’s very simple to find out the language set on your device. For example, with Android, you can simply call a function from your Activity class:

Configuration config=getApplicationContext().getResources().getConfiguration();
String lang = config.locale.getLanguage();

The function getLanguage returns strings like en (English), fr (French), de (German). You should check the value of lang and if you don’t support that language, set it back to your default one (en in our case as we want English to be default). This string will be used to identify the current language during your application life cycle, so keep it safe. You can use these abbreviations (en, fr, de…) to setup a simple naming convention for your files.

With this convention, it’s simple to know which file to load. Also, you can find out dynamically if a language is supported by your application: simply check if the corresponding language file exists. This way, you can add new languages without changing a line of your code. It’s always a good idea to make your code as generic as possible and let the assets handle themselves (data-driven instead of code-driven).

If you are developing your applications for different platforms (iOS, OS X, Windows, etc.), you’ll find similar functions as getLanguage on all systems.

Localizing Other Assets

Sometimes, you need to localize more than just text. You might have textures containing some writing. You should use the same naming convention as before.

To simplify your code, you can dynamically create the names of your localized textures using a simple function:

String name = LocalizeName(“gameover”, “png”);

The function LocalizeName concatenates the current language and the extension (.png in this example). So, if the language is Spanish (es), the name returned will be gameover_es.png.

You might have some assets that need to be localized in some languages but not for all of them. For example, in France, we are comfortable using the Anglicism ‘Game Over’ (translating it would actually sound weird). It would be a shame to duplicate the default asset just to create a fake localized one (gameover_fr.png). Instead, the function LocalizeName could test if the file exists (it’ll need the complete path for that). If the file doesn’t exist, the function should return the name of the default file. For our example, in French, LocalizeName would return gameover_en.png.

Finding the Right People

You should work with native speakers for all your localization. Don’t ever use automatic translation tools (online software) like Babel Fish or Google Translate. The result is so bad that you are better keeping your application in English.

There are many online services where you can hire translators, like dystranslations.com and tethras.com. We haven’t used them, but they were recommended by fellow game developers.

We did find an alternative way to get very motivated translators. We ask our fans if they can do it. These people enjoy our apps and know them almost as well as we do. We develop a much closer relationship with these users than we would ever get from hiring someone via an online service. They are very keen on making the best localization. We send them beta builds so they can test if their localization is perfect. It really feels like they are part of the team.

Final Tips

Give your translators as much detail about your application as possible. If they can test a proper version (like our fans do), it is even better. The more they know about your application, the better they’ll localize it.

Be careful with the size of your UI (buttons, message box, etc.). Most English words are small compared to other languages. Usually, German words are very long and it might be wise to check if they fit in your UI as early as possible. It’s also useful to have a way to auto-scale your text, so you can be certain it will always fit inside a specific area (like a button).

Don’t hesitate to add formatting information inside your text. For example, “Chapter [NUM]” contains the tag [NUM]. We will substitute the proper index in code (Chapter 1, Chapter 2…). It’s very useful because for some languages, the formatting is completely different (in Chinese, it’s in the middle 第[NUM]章). Using this solution will remove most of the formatting problems.

There are many other aspects to be considered when localizing (fonts, testing, etc.), but that would be too long for this article. Hopefully, this quick overview has convinced you that the technical side of localization is accessible to anyone. It’s a simple way to increase the visibility of your application; you should do it.(source:gamasutra


上一篇:

下一篇: