[Feature suggestion] new translation system

Started by guga2112, Fri 07/02/2020 12:56:45

Previous topic - Next topic

guga2112

Hi all,
yesterday I stumbled against a small limitation of the current AGS translation system. Long story short, I had two strings which looked the same, but had different meanings. The word was "Music", but one was an options label - so it needed to be translated as "Musica" in Italian - while the other one was a speech string - which needed to be translated as "La musica".

I solved it by adding a whitespace in the GUI label, but that's a workaround. So, here's what I thought could be an easy modification to the current system, given that I assume everyone writes the whole game in a source language before thinking of translations.

NOTE: I never looked at the Engine source code, so what follows is a guess on what it currently does. If I'm wrong please correct me.

Before the first translation is created, the game is in its default language. When creating the first translation, the system scans all files looking for strings, but instead of adding them to the .trs files, it changes them to a placeholder, then compiles a .trs file with the placeholder AND the original as it were a translation.

So, suppose you have a game whose GlobalScript.asc looks like this:
Code: "Adventure game studio"

function game_start()
{
    cEgo.Say("Welcome to my game");
}
function invKey_OnLook()
{
    cEgo.Say("It's the key to my apartment");
}


Normally the editor creates an Italian.trs file that looks like this:
Code: ags

Welcome to the game

It's the key to my apartment



But what I envision is that the editor may change the whole game to this
Code: "Adventure game studio"

function game_start()
{
    cEgo.Say("globalscript.gamestart.1");
}
function invKey_OnLook()
{
    cEgo.Say("globalscript.invKey_OnLook.1");
}

and then automatically create an English.trs (or Default.trs) that looks like this:
Code: ags

globalscript.gamestart.1
Welcome to my game
globalscript.invKey_OnLook.1
It's the key to my apartment


Each new translation file would then get both placeholders (which sometimes help in understanding the context of each sentence) and the source language sentence. A translator would then overwrite the source sentence. Or, if you think having the source sentence visible at all times helps in having everything under control, it could look like this
Code: ags

globalscript.gamestart.1=Welcome to my game

globalscript.invKey_OnLook.1=It's the key to my aparment


so that if a translation is missing, it shows the default one.

In this case, equal strings would get different placeholders, which helps in solving ambiguities (does the "Ball" in your baseball-themed adventure game mean the object, or the pitch that's not a strike?).

I'd also add unprintable tags to specify which strings need not to be translated. Something like cEgo.Say("__NOTRANSL__AAAAAAAAAAAAAA"); would show only the "AAAAAAAAAAAAAA" avoiding the string to be changed at translation creation time (and leaving out of the .trs file).

What do you think?

It should't be that much of a modification, as the editor already scans looking for strings and writing them on a file. It's a matter of modifying those strings and putting the new and old value on the trs file.

"But what about the update function?". Well, placeholders may conform to a particular format - like being surrounded by double underscores - so newly added strings would stand out in the update.
Code: "Adventure game studio"

function game_start()
{
    cEgo.Say("__globalscript.gamestart.1__");
    cEgo.Say("It's not much but I hope you'll like it");
}

Updating the translation will create a new string in the .trs files with __globalscript.gamestart.2__=It's not much but I hope you'll like it.

What do you think?

Crimson Wizard

#1
I was actually considering something roughly similar in the past, and it is among recurring suggestions for localizations done in other engines (and regular applications) as well: to use unique "key names" instead of actual strings in the scripts or game data, and then have translation files map actual text to these keys.

All of this is doable, this way or another, but one serious concern I was having was user convenience, because I cannot imagine how AGS game developers will react to having "strange lines" instead of actual text in their game scripts.

But definitely a good idea to experiment with, IMO.

Note, that one alternate potential solution is to keep regular text in default language, but also allow special tags to separate identical texts, similar to how AGS uses voice tags now. For example, if you have cEgo.Say("Hello") and cEgo.Say("Hello"), and want, for some reason, to separate these in translation, you do something like cEgo.Say("@1 Hello") and cEgo.Say("@2 Hello"). That, one one hand, would allow to make a text unique, but also keep original text for the quick reference in script. Or even merge this with the voice-over tags.
The disadvantage of this would be that this number is non-descriptive, compared to the key such as "globalscript.gamestart.1".

PS. We also had a discussion about other localization problems in AGS recently, so this is just a part of what may be considered for a change.

Cassiebsg

#2
uhm, don't think changing the original that way would be helpful, for the dev anyway. I know I would hate not being able to read the Says and have to go look some other text somewhere.

But it would be nice to a) remove all the noise (strings that one shouldn't translate) and b) being able to identify where a piece of text fits in translation.

so while having the trs formatted this way:
Code: ags

globalscript.gamestart.1 Welcome to my game

globalscript.invKey_OnLook.1 It's the key to my apartment



or some other way to identify where the translation line goes in the game would be useful.

Code: ags

function game_start()
{
    cEgo.Say("__globalscript.gamestart.1__"); // not useful IMHO, nor intuitive 
    cEgo.Say("__globalscript.gamestart.2__ It's not much but I hope you'll like it"); // this would be readable

    cEgo.Say("¤3 A new hope?"); //  or maybe just create a character to identify the line like the speech like CW suggested...
}


Edit: about a) Maybe we could find a character one could add to strings that aren't translated? § This one is not likely to be used in a text, I think. If used at the start of the string it would make that string to not be index by the trs. Of course this would mean the dev would have to know and remember to add it when typing said string.
There are those who believe that life here began out there...

SMF spam blocked by CleanTalk