My addon creator minions!
The next release of Tales of Maj'Eyal will include support for localization of the texts. And since this change can affect you I wanted to explain a bit what this entails. There are two things to consider: making your addon translatable and providing translations (either for your own addon or for a whole new language for the game itself).
Making your addon translatable
Let's start with the easy stuff: if you do not want to bother with it you have NOTHING to change. Your addon's texts will display in English as before and that's it :)
Now, if you want to support it here's how it works: The game now provides two new methods to handle text, these functions are _t and tformat. They are both extremely easy to use, a little example:
foo = "This text is visible by users" bar("This one is also visible!") test(("And this one is too but with formatting too! %d is a number and %s a string!"):format(7, "Yes I am a string!"))
Would now simply become:
foo = _t"This text is visible by users" bar(_t"This one is also visible!") test(("And this one is too but with formatting too! %d is a number and %s a string!"):tformat(7, _t"Yes I am a string!"))
That's it, if you do that your addon is now localizable!
Now to give some more details of the do & don't of the new system:
- Any string that IS an entity name, achievement name, talent name, effects name, ingredient name, birth descriptor name/display name/cosmetic, a call to a log function (game.log/logSeen/..., npc emotes, ..) and a few other minor things will NOT need to pass through the _t function as the framework will automatically understand those need to be translated.
- Any string that IS NOT an entity name, achievement name, talent name, effects name, ingredient name, birth descriptor name/display name/cosmetic, a call to a log function (game.log/logSeen/..., npc emotes, ..) and a few other minor things will need to be put through _t or :tformat is the user is ever going to see it
- If it is a plain string, simply prefix it with _t; like "Foorbar" becomes _t"Foobar", or [[Whatever this text is super long...]] to _t[[Whatever this text is super long...]]
- If it is a :format() call then simply change it to a :tformat call()
- Only do this for user-facing strings! identifiers, debug print() calls and such should not be translated.
- NEVER do manual concatenation of user-facing strings anymore, so turn code like that:
"There are "..nb.." foes around!"
into
("There are %d foes around!"):tformat(nb)
It is cleaner anyway.
- A few things have change for entities, Objects always had a getName, but now npcs also do, so never call npc.name but instead npc:getName()
- Try to not change strings around just for the sake of it, as it'll require translation of the new slightly different version again
Providing translations for your own addon
That one is very easy, basically you make a new folder named "locales" into your addon's data folder.
Inside of that you place one file per locale you wish to support. Say you want to provide translation into Simplified Chinese, you'd have a file names zh_hans.lua. For French you'd use fr_FR.lua and so on.
Each of those files should look like that:
locale "fr_FR" t("This is a plop!", "Ceci est un plop!") t("A string with %s formating %d code works the same.", "Une chaine avec %s du code de formatage %d marche exactement pareil.") ...
And important thing to note, the framework allows for re-ordering the parameters of formated strings. Imagine an example where you have a string that is formated like that:
local size = _t"giant" local what = _t"rabbit" game.log("You see a %s %s!", size, what)
Now in some languages, like French, this would need to become what, size. Handling that is actually very easy by passing some more infos into the locale file:
locale "fr_FR" t("You see a %s %s!", "Vous voyez un %s %s!", nil, {2, 1})
Notice the {2,1} table. It simply tells the game how to reorder the parameters before passing them to the formating code. That's it!
One last case is when the same english text would translate to two different texts based on context. You can handle that with "tags". Example:
foobar(_t("This text has a meaning!", "context1")) foobar(_t("This text has a meaning!", "context2"))
And the local file would do:
t("This text has a meaning!", "...first meaning here..", "context1") t("This text has a meaning!", "...second meaning here..", "context2")
Making a translation addon for a new language
That is also extremely easy (to implement, the actual translation will take you days, there is a LOT of text in ToME!) to do and is basically the same as the previous section.
Indeed you do provide the language file in the exact same way, but you also add a hook to tell the game of your new locale, basically:
class:bindHook("I18N:listLanguages", function(self, data) table.insert(data.list, {name = "Français (French)", locale="fr_FR"}) end)
If your language needs special characters not included in the game's default font you can also provide a special font package and force it on inside the locale file:
forceFontPackage("chinese")
Note that you'll need to provide translations for both the game's and engine's (and DLCs if you want) locale files! This is a lot of work!
I'll try to provide an example base translation addon upon which to build on sometime in the future.
Anyway, that's it for now, have fun!
- darkgod's blog
- Login or register to post comments
Third-party addon translation?
For reference, is it possible to write an addon that provides translations for someone else's addon? I ask because a Steam user asked a few months ago for permission to release a Chinese translated version of ZOmnibus. With any luck, I'll have localization support added to ZOmnibus and all its component addons by the 1.7 release, which I'm hoping will make their job easier.
That should work just fine
That should work just fine :)
And if it does not, I'll try to make it work anyway ;)