Page 1 of 1

Generic internationalization issues

Posted: 06 January 2025, 08:05
by birbwatcher
Hi!

While contributing to translation of two games (Wingspan and Castles of Burgundy) into Lithuanian, I noticed that there are big internationalization issues with the current array-based translation mechanism:
  • often you get a word or two to translate without any meaningful context, which leaves you guessing whether your translation will be correct or not
  • strings often use concatenation or are made to include other strings, which does not always work well due to grammatical cases and such (e.g. I can't simply prefix or suffix nominative of "card" to build accusative in Lithuanian)
  • genders (somewhat addressed for a few languages in https://boardgamearena.com/forum/viewtopic.php?t=21387, but that's only a few languages, and even then I wonder how well it actually works. The post itself suggests that that logic is very basic
  • no support for plural forms. Not every language is as simple as "1 card; n cards", there are many that need more variants than these two
Localizability is so rudimentary here, it's just oof! So, I've filed a feature request to expand it here: https://boardgamearena.com/bug?id=151756. If you care about stuff like this, I would appreciate your vote there! :)

Re: Generic internationalization issues

Posted: 07 January 2025, 11:31
by fruktansvärt
Good luck getting anybody in the development team to care about translation. I don't think there's been any work done here since Een (one of the BGA founders) quit some time back.

Re: Generic internationalization issues

Posted: 07 January 2025, 13:58
by Blacktango
Note that date and internationalisation issues are some of the more complex things in computer development.

Even if the basic tools given to developers were very handy for dealing with them (which is never the case, in any programming language), the developers would still need to know about the possible peculiarities of the different languages.

For example, I have discovered some time ago that the Arabic has 3 plural/singular forms, whereas French or English (or any other language I learnt at school) has only one. If you don't know that, good or bad translation tool doesn't matter, you will just not handle one of the three cases.

Re: Generic internationalization issues

Posted: 09 January 2025, 23:12
by birbwatcher
Blacktango wrote: 07 January 2025, 13:58 Note that date and internationalisation issues are some of the more complex things in computer development.

Even if the basic tools given to developers were very handy for dealing with them (which is never the case, in any programming language), the developers would still need to know about the possible peculiarities of the different languages.

For example, I have discovered some time ago that the Arabic has 3 plural/singular forms, whereas French or English (or any other language I learnt at school) has only one. If you don't know that, good or bad translation tool doesn't matter, you will just not handle one of the three cases.
Nobody expects every developer to know how every language in the world works. There are libraries which handle plural forms as well as other things just fine. You just have to make use of these libraries.

Take gettext for example. It has had plural support for decades. All the developer using gettext has to do to make use of it is to make a call like this:

Code: Select all

printf(ngettext("%d translated message", "%d translated messages", n), n);
...and the ngettext() function provided by the library will make sure to select the correct plural form from those provided by the localizer.

This way the developer only needs to know English. But, naturally, they also have to invest some effort into using the library.

The method I mentioned in my feature request (a localization framework called Fluent) is even more powerful than that.

Re: Generic internationalization issues

Posted: 10 January 2025, 00:24
by Blacktango
What I mean is that, even with these libraries, you need to understand how to truncate your texts to make them translatable in any language.

For example, if you want to translate "n object(s)", you may use five different texts:

- 0 object
- 1 object
- 2 objects
- 3 objects
- x objects

In English, you need just two cases "object" and "objects", in Arab I think you need three.
What about the other languages? Maybe some objects have different gender too, then you need even more forms?
As a developer, how do you know how many different cases you need to use?

Re: Generic internationalization issues

Posted: 10 January 2025, 07:24
by birbwatcher
Blacktango wrote: 10 January 2025, 00:24 What I mean is that, even with these libraries, you need to understand how to truncate your texts to make them translatable in any language.

For example, if you want to translate "n object(s)", you may use five different texts:

- 0 object
- 1 object
- 2 objects
- 3 objects
- x objects

In English, you need just two cases "object" and "objects", in Arab I think you need three.
What about the other languages? Maybe some objects have different gender too, then you need even more forms?
As a developer, how do you know how many different cases you need to use?
I understand what you are talking about. This is exactly what gettext's ngettext() function is about. If a developer uses gettext, they always use only two forms in their source code, like this:

Code: Select all

printf(ngettext("%d object", "%d objects", n), n);
Here, the inner call to ngettext() takes three arguments: the two (always two!) plural forms for English singular and plural, and the number n, which is used to select one of as many as necessary plural forms according to target locale rules. Then, once ngettext() returns the appropriate translation, printf() (or sprintf() or whatever other replacement method the developer uses) replaces the placeholder in the translated string with the number (hence the second , n at the end), producing the final string.

From the localizer's side, each gettext translation file, if it supports plurals at all, has a "Plural-Forms" header, which specifies the number of plural forms and the logic of selecting the appropriate one. Here's an example for Lithuanian:

Code: Select all

"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
With that header in place, my translation for the above line would look like this:

Code: Select all

msgid "%d object"
msgid_plural "%d objects"
msgstr[0] "%d objektas"   # 1 objektas
msgstr[1] "%d objektai"   # 2 objektai
msgstr[2] "%d objektų"    # 10 objektų
The developer doesn't need to know or implement any language-dependent logic in their code (it would be a nightmare if everyone had to do that on their own). They only need to make use of the call itself.

Most popular gettext authoring tools (like Poedit) already have rules for most of the languages accounted for, so, once the localizer selects the language they're working on, the Plural-Forms header will be prefilled correctly. The localizer only need to concentrate on actual proper localization (and of course remember the correct order of plural forms) from there on. Some tools go even further and provide examples of translated string with the numbers in place on the fly.

If this is all new to you, I really suggest you to click on the two links in my previous comment. ;)

Re: Generic internationalization issues

Posted: 07 February 2025, 12:21
by SkeletonChief
Agree on those issues!

The one with the number of items I encounter a lot. Currently we either have to reword it so it reads more or less normal, or just translate it directly which just sound weird in many cases. People tend not to bother and go with the second option.

Translation context is a good point as well. Even translating a tutorial can be harder than it needs be: every tutorial window is broken in multiple separate strings - you have to follow along with actual tutorial in another window. With the general game text it's harder as you can't just emulate specific situations willy-nilly. Often translators just guess, occasionally totally missing the mark.

As for how hard it is to address. Well, our job is reporting the problems. And those are real problems. The BGA devs know the internals better, it's for them to decide how (and if) they want to address this. For us going "it's probably hard!" is unproductive and unnecessary.