Author Topic: Internationalisation of text-games  (Read 3664 times)

Offline Sinzygy

  • Level 28
  • **
  • Posts: 420
  • Reputation: +11/-0
    • View Profile
Internationalisation of text-games
« on: August 15, 2007, 11:07:00 AM »
I'm in the process of rewriting one of my games and I want to add multiple-language support.
Currently I'm making one big file for each language with one big array for each piece of text that I want to display.

Is this a bad approach?
Should I split the array into many, smaller arrays (for each site one)?
Or should I do it via database?

Offline Zeggy

  • Global Moderator
  • Level 35
  • *****
  • Posts: 1,187
  • Reputation: +13/-4
    • View Profile
Re: Internationalisation of text-games
« Reply #1 on: August 15, 2007, 11:35:30 AM »
Erm, I'd do it with separate arrays for each language, then all you have to do is include the correct language file, then make sure all the array keys are the same for each language.
Sounds like a big project though, I'm guessing you speak more than 2 languages? :)

Offline Sinzygy

  • Level 28
  • **
  • Posts: 420
  • Reputation: +11/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #2 on: August 15, 2007, 12:15:12 PM »
yeah, I have one array which is the same for every language, just the values are different.

I speak fluently swiss-german (duh), german (again, duh!), english and french. I can speak some italian, but not as much as I'd like. Then I can speak PHP und JavaScrip 8)

To translate the game into more languages I thought about letting the users do it. I'll provide either the english (needs to be written) or the german (base) text and let the users work from there on.

Offline codestryke

  • Administrator
  • Level 33
  • *****
  • Posts: 588
  • Reputation: +22/-0
    • View Profile
    • eXtremeCast Games
Re: Internationalisation of text-games
« Reply #3 on: August 25, 2007, 07:38:18 AM »
Zeg is dead on...

If you look at any big forum / portal software that's the way they do it (ie SMF, phpBB, vBulletin)
Creating online addictions, one game at a time:

Offline JGadrow

  • Level 35
  • **
  • Posts: 1,133
  • Reputation: +23/-2
    • View Profile
Re: Internationalisation of text-games
« Reply #4 on: January 30, 2008, 03:06:20 PM »
Sorry for dragging out an old topic, but I did a search and this is the best place.

The method that I'm currently using is the data is input into a database with an added 'lang' column giving the 2 character language code (I'm not messing with accents at the moment, but easy enough to change if necessary).

It took me about a day to convert all of the existing data into utf-8 format and a few moments to install the mb_string extension but now all the data can be stored in a single location with quick indexing / searching.

My search was originally to see if forum users were offering to translate games into other languages but I figured I'd share another technique :)
Idiocy - Never underestimate the power of stupid people in large groups.


Offline thevtm

  • Level 4
  • *
  • Posts: 12
  • Reputation: +0/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #5 on: April 19, 2008, 03:04:07 PM »
I think the best way is to separate the sites...
like eng.chita.com(english) with all the text in HTML.
and esp.chita.com(spanish) like that u will use less of the computer.
is good for games that have aways 500+ online

Offline JGadrow

  • Level 35
  • **
  • Posts: 1,133
  • Reputation: +23/-2
    • View Profile
Re: Internationalisation of text-games
« Reply #6 on: April 20, 2008, 09:26:13 AM »
The question was how to store the data. I didn't know if anyone had a better method. I'm actually reading the http accept header which is supposed to indicate the user's preferred language choices. I default to english if none of the requested languages are supported.

And, yes, I sanitize the input because it is possible to modify the request headers.
Idiocy - Never underestimate the power of stupid people in large groups.


Offline mdshare

  • Game Owner
  • Level 14
  • *
  • Posts: 118
  • Reputation: +3/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #7 on: April 20, 2008, 09:49:08 PM »
Simple have all  text replaced by vars

eg $text[100]

If language is lets say 1 then fetch /languagepack/1.php

which includes only the variables

$text[1]="This is a test";
.....
$text[100]="This is a demo";

Offline ninto

  • Level 5
  • *
  • Posts: 16
  • Reputation: +0/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #8 on: June 15, 2008, 03:13:17 AM »
Now I'm really late answering this, but I thought I'd give it shot since it might be of help to others.

First of all, the one-file-per-lang-array approach sure works, but it's nothing but trouble.
The size isn't the problem, but the maintainability is. Take it from me, I've done it once and I'll never do it again.

What you should look at is one of the following:
either you use gettext. (http://php.net/gettext) which is a nice standard that is used widely online. There's multiple GUI tools out there which makes it easier to edit/change existing collections. Although it might be a bit tricky to implement if you have done it before.

if you use XML with XSL(t) as templating then gettext doesn't do the the trick. Basically what you do is to save a xml-file for each language with a standard way to store a phrase/word/whatever. In PHP (if you using that) you simply load the language xml file, and append it to your XML document.

Yours,
ninto

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #9 on: July 03, 2009, 06:59:00 AM »
To sum it up.


We have two methods (source code side):
- simple language array: $lang['register']="Register";
- translation/output function: translate("bla bla, bla %s bla",$username);

Storage methods:
- txt file (language arrays method almost always use this storage)
- XML
- database
- hardcoded (I doubt anyone uses it, but in theory we could just run a parser and rewrite the very source code)

Have I missed something?

Offline Barrikor

  • Level 19
  • *
  • Posts: 197
  • Reputation: +3/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #10 on: July 03, 2009, 01:36:40 PM »
Nope, you summed it up pretty good.

The only thing I'd add is that INI files can often be better than .txt and XML, since XML is kinda bulky and .txt's force you to hardcode the array numbers everywhere.

if you do use txt's though, use something like this instead of opening it...
Code: [Select]
<?php
// + LineArray ( FileName : string ) : string array
public function LineArray$FileName )
{
return array_map'rtrim' file$FileName ) ) ;

?>


(All I did was copy that from my framework(ish) project, but it should be able to give you a line array with the least amount of overhead that will work in the way that Mdshare posted.
« Last Edit: July 03, 2009, 01:50:05 PM by Barrikor »
Projects: Pith PHP Framework, Also working on a small gui for pygame

Offline codestryke

  • Administrator
  • Level 33
  • *****
  • Posts: 588
  • Reputation: +22/-0
    • View Profile
    • eXtremeCast Games
Re: Internationalisation of text-games
« Reply #11 on: July 03, 2009, 03:48:11 PM »
I've never done a multi-lingual game so I can't say anything first hand but there is very heavily developed Exofusion / GamerFusion app that has the ability to support multiple languages.

Check out http://sourceforge.net/projects/vallheru/

Might give you some good ideas...


Now on to the very little I do know, I'm going to go with what Delifisek brought up in a couple threads. Keep the international versions of the game separate, no templates, no text replacements just convert the game to the language for the target audience. Not only will this produce the fastest code but will also create a better community. We've come a across problems with running and administering games that had users that could speak multiple languages. The community itself fragments based on the language barrier. Just some food for thought :)


Creating online addictions, one game at a time:

Offline Delifisek

  • Level 12
  • *
  • Posts: 79
  • Reputation: +1/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #12 on: July 03, 2009, 05:15:27 PM »
Nearly more than 5 years all of my new code has multilang capability.

This was my current implementation. I had extensions system in my code. Each extension has own language file per language.

Like

language_en.php
Code: [Select]
<?php
//--- Language: en
 
$_lang = array (
&
#160; '_extension_system_' => '_extension_system_',
&#160; '_plugin_system::checkin_' => '_plugin_system::checkin_',
&#160; '_plugin_system::extension_manager_' => '_plugin_system::extension_manager_',
&#160; '_plugin_system::index_' => '_plugin_system::index_',
&#160; '_plugin_system::user_manager_' => '_plugin_system::user_manager_',
&#160; '_user_email_' => '_user_email_',
&#160; '_user_login_' => '_user_login_',
&#160; '_user_logout_' => '_user_logout_',
&#160; '_user_name_' => '_user_name_',
&#160; '_user_password_' => '_user_password_',
);
?>



Usage was simple

Code: [Select]
<div>
<?=$GLOBALS['lang']['_plugin_system::checkin_']?>
</div>

I had some util functions to check all my php files and extract all $GLOBALS['lang']['_whatever_'] (or $this->lang['_whatever_']); ) data, also I include old language file and merge all keys. Then write array like native php file (example was auto generated file).

Plain dead simple. Plus opcode compatible. one include than everthing in memory.

One big array for every language leads too much memory usage. One common array for language needs and load only one language per request.

Regards


And also. Using XML or function based methods just increase your cpu load.


And also (sorry for that) :)

Load your language keys in GLOBAL space (with $GLOBALS or public static method) you have to access them easly. Load them when you need. And if they where too many language file. First concat them, then include one file.

And another common practice was using CONSTANTS. I did not go that way.
« Last Edit: July 03, 2009, 05:23:50 PM by Delifisek »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #13 on: July 04, 2009, 06:47:51 AM »
Nearly more than 5 years all of my new code has multilang capability.
If you have any tips/info not related to storage (like finding translators, managing multi language game, if this was worth it, etc) please post it there http://community.bbgamezone.net/index.php/topic,1890.0.html it would be useful as well.

Quote
Keep the international versions of the game separate, no templates, no text replacements just convert the game to the language for the target audience. Not only will this produce the fastest code but will also create a better community. We've come a across problems with running and administering games that had users that could speak multiple languages. The community itself fragments based on the language barrier.
Yes, I'm aware of this. I saw a few games with multiple languages on the same game world, and I'm definitely going to avoid it at all cost :D


Back to translation code & storage. We have only 2 options:
- variable (array/constant/define)
- function (gettext or home made solution)

The variable method is simple and fast. The function method is easier to maintain and allows for faster coding. Looking at open source projects almost all of them use the variable approach, the only one with function approach I found was Legend of the Green Dragon (check ScriptVault). In  theory, if you are determined and serious enough you would go for variable method, but... I tried it recently, for a limited part of code, and... I'm *really* not sure if I want to go this route :D It looks nasty for maintaining and it definitely gets in the way of coding, at least with my coding habits.

Questions:
- are there any tricks/tips for increasing the maintainability for variable approach?
- how exactly the function method works (especially how you identify which string it is and how you prepare the first translation file when some of the translate functions are not called every time you process the page, for example error messages)?
- which method you like the best (only if you tried both of the approaches)?

Offline Barrikor

  • Level 19
  • *
  • Posts: 197
  • Reputation: +3/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #14 on: July 04, 2009, 04:29:44 PM »
- are there any tricks/tips for increasing the maintainability for variable approach?

If you use INI's for storing the array, you have the array keys as strings instead of ints.



EN.ini
Username=Username
Password=Password
Help=Help

DE.ini
Username=Benutzername
Password=Paßwort
Help=Hilfe

Code: [Select]
<?php 
$text 
parse_ini_file'DE.ini' false );
?>


<?php echo $text['Username']; ?> <input type="text" ...
<?php echo $text['Password']; ?> <input type="text" ...


   

(however, if it's a huge project the array might get too bulky)
« Last Edit: July 04, 2009, 04:52:40 PM by Barrikor »
Projects: Pith PHP Framework, Also working on a small gui for pygame

Offline travo

  • Level 18
  • *
  • Posts: 186
  • Reputation: +2/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #15 on: July 04, 2009, 05:29:32 PM »
I use strings in my arrays anyway. Might be a little bit slower, but 100 times quicker to code... If I need to, Ill just replace all of the keys with numbers when Im finished.

Load them when you need. And if they where too many language file. First concat them, then include one file.

Why not just add to the array as you need it?

Code: [Select]
<?php
if (empty($GLOBALS['lang']) || !is_array($GLOBALS['lang'])) {
$GLOBALS['lang'] = array();
}

$GLOBALS['lang'] = array_merge($GLOBALS['lang'], array(
//New data here
)
);

Offline Delifisek

  • Level 12
  • *
  • Posts: 79
  • Reputation: +1/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #16 on: July 05, 2009, 03:05:35 AM »
Damn language barrier.

As you know, I'm very over zealous about performance.  ;D

Problem is when your code starts to include too many files, performance starts to drop. And of course using an opcode cache (APC, Xcache etc) will solve problem.

And also, my current programming model has extensions/plugins model. On front page I may load 20 different plugins from 6 different extensions. that means 6 different language file include (per extension). Concatting those files into one file and include one language file, help performance (of course under heavy load).

This approach reduces my I/O overload. After moving to MVC model (no not something like CI or Cake, mine just seperated files for plugin). Each plugin loads 4 files for programming + 1 one for views. And you know 20 * 4 = 80 was too much (of course in my twisted mind).

Also, My game plans always on one big server.


One of my current implementation.

Code: [Select]
<?php
/**
* k5_get_language_file#
* gets Requested language file
*
* Variables: $o['mbase']:&#160; modlue base
* $o['lang_key']: current language key (en, tr, de etc)
*
* @author Sancar Saran <saran@delifisek.net>
* @version 1.0
*/
function k5_get_language_file($o) {
$file $o['mbase'].'language/language_'.$o['lang_key'].'.php';
if(is_file($file)) : require_once($file); endif;
if(isset($_lang) and is_array($_lang)) : $GLOBALS['k5']['lang'] = array_merge($GLOBALS['k5']['lang'],$_lang); endif;
}
?>


and

Re: Barrikor

And you have to pay parse_ini_file for each request.

Regards
« Last Edit: July 05, 2009, 03:15:11 AM by Delifisek »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #17 on: July 11, 2009, 05:14:14 AM »
Does anyone know how exactly the function approach (translate("bla bla, bla %s bla",$username);) or gettext works?

- How do you identify which string it is? Do you make a string comparison each time the function is called? Or maybe use some identifiers?
- How to prepare the first language file? I assume you run the script with a special "write" mode and all text from translate function is written to file/database. But how to handle error messages that are not called at all?

Anyone did the function/gettext translation and want to share experience?

Offline Greyth

  • Level 6
  • *
  • Posts: 22
  • Reputation: +0/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #18 on: July 12, 2009, 10:39:46 AM »
Just a thought... Awhile back I spent a LOT of time and energy into getting one of my sites multi-language. In the end I realized a couple of things.

First that for the size of my game it was a stupid move because the number of players from other countries didn't make a large percentage, and even after there were 5 languages available in our post popular non-us audiences, there was only a little growth from those places. In the end the game would have been healthier had I just worked on other features instead.

Second, note that it does add a layer of complication across the board for all of your future coding. You will be paying for it in small amounts forever. Not that it's a problem if you have enough users to support it, but if nobody ends up using it, it can be a permanent slowdown for your development, albiet small.

Third, after the fact someone pointed out to me that there were already a number of translation libraries out there and that although I had some good coding experience in the making of ours, it would have saved a lot of time not to re-invent the wheel.

http://pear.php.net/package/Translation2

Just my three cents...

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #19 on: July 13, 2009, 05:15:38 AM »
Second, note that it does add a layer of complication across the board for all of your future coding. You will be paying for it in small amounts forever. Not that it's a problem if you have enough users to support it, but if nobody ends up using it, it can be a permanent slowdown for your development, albiet small.
Which approach you used? Variable or function?

From perspective, can you think of any library/solution/approach that would reduce the code maintenance cost (not the initial cost of first implementation but the ongoing long term added cost associated with translation)?

Offline Greyth

  • Level 6
  • *
  • Posts: 22
  • Reputation: +0/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #20 on: July 13, 2009, 08:45:37 AM »
Not sure what you mean by library or function, a bit if both I guess. Basically I went with the approach Zeggy first mentioned. I went with arrays for each page.

Basically the setup that I ended up with stored the language mappings in an associative array. The array was then serialized and stored in a flat file under a subdirectory for each language. A function was then called to load the language array on the page, first loading the english version in case the translation was incomplete, then overwriting it with the other language.

So each page had something like:

$langArr = loadLang($thisPage);

After that each string to be output to the page has to come from the array, so to echo hello would be something like this:

echo $langArr['hello'];

Note that the 'hello' value could be anything, probably a paragraph or even a basic HTML segment.

I also built a control panel to allow language admins to edit the mappings. Once that was done the upkeep is just in dealing with the extra variables on the page and keeping the language files up to date. It's not much, but when you are a single developer only working part time on the game, it is a level of headache. I didn't mean to make it sound like a complete nightmare once it is setup, just personally I wish I had spent the time developing either a new game or adding something that would have been of value to the majority of my players instead.

As for whether I can think of a better approach, nope not really. Using something that is already tested and proven will put you a leg forward for sure, but it is something you will always have to maintain.
« Last Edit: July 13, 2009, 08:52:45 AM by Greyth »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #21 on: July 13, 2009, 09:48:06 AM »
Not sure what you mean by library or function, a bit if both I guess. Basically I went with the approach Zeggy first mentioned. I went with arrays for each page.
You went with the most difficult to maintain approach then. But you still say it is only a minor headache. Ninto who went the same route said "I've done it once and I'll never do it again". Hmmm...

I wonder about the function apprach then. It should be easier to maintain.

General overview how function/gettext works:
- you don't make any arrays nor variables, just a function with text (English)
- then you run the script in "gather data" mode and all strings are stored into database
- then you send the database to person who make translation to make it translated to another language
- once it is ready you run the script normally and depending on language setup it changes the text displayed (probably by comparing the original hardcoded string in English with the translation in the database)

The best thing about this approach is that it moves the effort from coder's side to translator's side (in theory, we still lack someone who went that route and could confirm how it works in practice...)

Offline ninto

  • Level 5
  • *
  • Posts: 16
  • Reputation: +0/-0
    • View Profile
Re: Internationalisation of text-games
« Reply #22 on: July 22, 2009, 03:44:16 AM »
(in theory, we still lack someone who went that route and could confirm how it works in practice...)

I'd like to mention that I have both used and implemented gettext.
My main point about this approach is that there's lots of GUI tools out there making i18n less stressful on me, as the coder.

I'm a bit short on time, but when I get home I could perhaps make a small guide if you want to?

Yours,
ninto

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #23 on: July 22, 2009, 05:33:48 AM »
I'm a bit short on time, but when I get home I could perhaps make a small guide if you want to?
It would be great. Also please include the basic usage of these GUI tools and everything else that is required to make it work effectively (standard online manuals are one sided, a complete description of a whole process provided by someone who already did it is much more helpful)

To clarify, you tested both approaches in PHP application? Was is BBG or something else?

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,128
  • Reputation: +26/-1
    • View Profile
Re: Internationalisation of text-games
« Reply #24 on: December 05, 2009, 02:59:03 PM »
I recently tried doing both array based translation and gettext. If I had to I could live with arrays method, but when it comes to ease of use gettext wins without one second of doubt :D Not sure about performance through.

 


SimplePortal 2.3.3 © 2008-2010, SimplePortal