Multi-language support

Gondos

Well-known member
Joined
Apr 18, 2022
Messages
514
Reaction score
707
Points
108
Location
On my chair
There is now a draft PR on github for internationalisation support.
The solution is compatible with .pot/.po files and should work with the usual tools (tested with POEdit).
For now the main UI should be translatable, MFDs are next in line.
In an "eat your own dog food" spirit, I'm adding a French translation as I go along :
1771454092088.png
Sadly RTL languages are not supported by ImGui so we'll have to wait and see...
Let me know what you think.
PS : si ya des gens experts dans le jargon spatial en français, je suis preneur de vos remarques^^
 
PS : si ya des gens experts dans le jargon spatial en français, je suis preneur de vos remarques^^
there are a few of us, indeed. How can I help? So far only 2 typos seen in your screencopy:
  • top-right "Moment(s) gravitationnel" -> (1 or multiple values?)
  • same view -> "Jour sidéral" in seconds ?!
 
There is now a draft PR on github for internationalisation support.
The solution is compatible with .pot/.po files and should work with the usual tools (tested with POEdit).
For now the main UI should be translatable, MFDs are next in line.
In an "eat your own dog food" spirit, I'm adding a French translation as I go along :
View attachment 47563
Sadly RTL languages are not supported by ImGui so we'll have to wait and see...
Let me know what you think.
PS : si ya des gens experts dans le jargon spatial en français, je suis preneur de vos remarques^^
Vive la France!

It's an excellent step forward; I always dreamed of an Orbiter in Spanish.
When everything is ready, I offer to translate it into Spanish.
 
there are a few of us, indeed. How can I help? So far only 2 typos seen in your screencopy:
  • top-right "Moment(s) gravitationnel" -> (1 or multiple values?)
  • same view -> "Jour sidéral" in seconds ?!
Bien vu :)
Binaries are available here.
You need to add this line in the Orbiter.cfg file to switch the language :
Locale = fr_FR
 
That's excellent work - btw, the new UI looks good.

When appropriate I'll offer to translate Orbiter to Italian and German.
 
That's excellent work - btw, the new UI looks good.

When appropriate I'll offer to translate Orbiter to Italian and German.

I can assist in the German translation, the format is just a bit unfamiliar for me (sorry, I only did I13N in Java)
 
.po/.pot Files are not that complicated once you have tweaked some.
The only "not so easy to understand" thing might be the selection of different plurals depending on a number.
Some languages do not only have one singular and plural form (If I remember correct polish has a concept of "one", "two" and "many"...but I might confuse that with another language ;) ).
The correct selection of singular/plural has to be implemented in the C++ code as well, or it does not matter.

An example entry (from a project I did a decade ago):
de.po
Code:
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] "Ein Eintrag"
msgstr[1] "%1 Einträge"

pl.po
Code:
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] "1szy wpis"
msgstr[1] "%1 wpisów"

and if a (not yet completed) language file has empty translations it falls back to the ID - and if that's in english, it defaults to that
sv.po
Code:
"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] ""
msgstr[1] ""


PS: This was the comment I added for the polish translation - whether this statement is true has to be confirmed by someone else ;) :
"[...]in Polish there are three plural forms. There is a form for the singular,a form used when the number ends in 12, 13 or 14, and a form for all other cases.[...]"
 
Last edited:
.po/.pot Files are not that complicated once you have tweaked some.
The only "not so easy to understand" thing might be the selection of different plurals depending on a number.
Some languages do not only have one singular and plural form (If I remember correct polish has a concept of "one", "two" and "many"...but I might confuse that with another language ;) ).
The correct selection of singular/plural has to be implemented in the C++ code as well, or it does not matter.

An example entry (from a project I did a decade ago):
de.po
Code:
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] "Ein Eintrag"
msgstr[1] "%1 Einträge"

pl.po
Code:
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] "1szy wpis"
msgstr[1] "%1 wpisów"

and if a (not yet completed) language file has empty translations it falls back to the ID - and if that's in english, it defaults to that
sv.po
Code:
"Language: sv\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
...
msgid "1 entry"
msgid_plural "%1 entries"
msgstr[0] ""
msgstr[1] ""


PS: This was the comment I added for the polish translation - whether this statement is true has to be confirmed by someone else ;) :
"[...]in Polish there are three plural forms. There is a form for the singular,a form used when the number ends in 12, 13 or 14, and a form for all other cases.[...]"
Yes plurals can get quite messy. Even in French, it should not be the simple "nplurals=2; plural=(n > 1)" that poedit defaults to because French has a special handling for multiple of millions :
-0 orbite
-1 orbite
-2 orbites
-1000000 d'orbites
-1000001 orbites
For now the simplification should be enough though 😅
The little piece of code that handles plurals should do the trick but so far I did not have to use it so it's probably broken.
Translators should not have to mess with the low level file formats, tools exist that handle that under the hood :
1771598265410.png
 
Last edited:
Bien vu :)
Binaries are available here.
You need to add this line in the Orbiter.cfg file to switch the language :

what binaries? I'm not familiar with your fork (yet) nor with github's ci/cd: do I need to clone from the commit you linked to? @TheGondosTheGondos 12f4b32 multilang
... or can I check .po/.pot with an editor, but where are thes files located?
 
what binaries? I'm not familiar with your fork (yet) nor with github's ci/cd: do I need to clone from the commit you linked to? @TheGondosTheGondos 12f4b32 multilang
... or can I check .po/.pot with an editor, but where are thes files located?
No need to compile if you don't want to. Look at the bottom of the github link I provided :
1771614872279.png
Planetary textures are not included so you'll just get boring spheres for planets but it should not be a problem for checking the translations.
 
ok, i don't have the download button because I don't have an account on github (only gitlab). Can you upload somewhere -> here for instance, or can I check translations directly from .po/.pot? (maybe the latter is better to check everything)
 
Done! very few typos actually, but some suggestions here and there, up to you to accept/reject.

(and sorry for my shared repo, it seems there is an IT maintenance on it...)

EDIT: by the way, I think the provided .po is a good start for all other languages, and, @Matias Saibene @Fabri91 @dennis.krenz in my delivery here I added some clarifications on the English wording as well (see "comments" or the little dialog bubble on the beginning of a line with Poedit.exe editor)
 

Attachments

Last edited:
Done! very few typos actually, but some suggestions here and there, up to you to accept/reject.

(and sorry for my shared repo, it seems there is an IT maintenance on it...)

EDIT: by the way, I think the provided .po is a good start for all other languages, and, @Matias Saibene @Fabri91 @dennis.krenz in my delivery here I added some clarifications on the English wording as well (see "comments" or the little dialog bubble on the beginning of a line with Poedit.exe editor)
Thanks!

Pour les noms de mois en 3 lettres je suis parti de ce lien (https://vitrinelinguistique.oqlf.go...es-dabreviations/abreviation-des-noms-de-mois), meme si c'est peut etre specifique fr_CA, je fais plus confiance aux Quebecois qu'a mon intuition pour ce genre de choses^^
Pour le contexte de "Sol" c'est un nom plus ou moins fictif pour nommer notre systeme solaire en anglais. Pas trouve d'equivalent en francais donc j'ai laisse tel quel.
(et desole j'ai pas les accents sur ce clavier...)
 
Pour le contexte de "Sol" c'est un nom plus ou moins fictif pour nommer notre systeme solaire en anglais.
yes, I understand, but my question was about the context in Orbiter where this word appears.

By the way, in this Orbiter modification, as well as in O2024, is there/could there be an API to retrieve the language from the modules' code?
Then, the modules could implement translations.

Also encouraging to re-use .po format, would be nice to stimulate contributions for modules as well
 
Ah, AFAIK it's used on the spashscreen and the info dialog.
The plan is to expose the API in the Orbiter SDK (it's already used in the D3D9 client).
The issue is providing the tools to extract the strings for module creators. I think right now the more or less offcial way to do an addon is to use MSVC but the scripts for translating stuff are Lua programs called from cmake files. Maybe an SDK update is in order.
I'll add a TRANSLATION.md file to provide guidelines for people who want to contribute when I converge on a workflow.
Right now it looks like this :
  • add #include "I18NAPI.h"
  • mark your strings to localize (e.g. OutputLoadStatus(_("Building Shader Programs..."),0);)
  • update the CMakeLists.txt file :
include(cmake/i18n.cmake)
generate_pot(D3D9Client)
install_po_files()
- make a build :
[4/9] Extracting translations for D3D9Client
Writing .pot file to C:/github/openorbiter/OVP/D3D9Client/i18n/D3D9Client.pot
- open the .pot file with a translation tools and create your .po file from it, with a naming convention (e.g. D3D9Client.fr_FR.po)
That's it, the Orbiter core will load all the .po files for the selected locale (e.g. *.fr_FR.po) during startup and use the provided translations (or fallback to English).
 
The issue is providing the tools to extract the strings for module creators. I think right now the more or less offcial way to do an addon is to use MSVC but the scripts for translating stuff are Lua programs called from cmake files. Maybe an SDK update is in order.
wondering whether the use of MSVC (in O2024, I guess) is compatible with the portability to non-Windows? if not, would be too bad
Can the API be exposed to C++ code first, beside Lua?
 
wondering whether the use of MSVC (in O2024, I guess) is compatible with the portability to non-Windows? if not, would be too bad
Can the API be exposed to C++ code first, beside Lua?
I'm not sure, I checked a few addons but the ones that provide the source code don't provide a CMakeLists.txt file nor an MSVC project.
Orbiter is using cmake, and as much as it pains me to say it, addons should probably use it too.
The Lua interpreter is also a C++ module by itself.
 
Back
Top