Localization of strings enumerated in a loop

Godot Version

v4.5.stable.mono.official [876b29033]

Question

This question is related both to C# and GDScript, since POT generator in Godot doesn’t support C#, so I need to rely on a helper gd file to generate the POT file.

I’m listing levels in UI dynamically, and giving them name in the loop. To simplify (real loop is much bigger, I just want to show you the idea):

foreach (var level in levels)
{
   nameLabel.Text = $"LEVEL {level.Id}"
}

In UI this will look like this: LEVEL 1, LEVEL 2, LEVEL 3, etc. Which is fine. But now I need to add localization to it.

My helper gd file looks like this:

func _ready() -> void:
	for n in 100:
		tr("LEVEL %s") % n

And it catches LEVEL %s, and I translate it to Level. And in game this is ignored, it still displays LEVEL.

The second issue I have is that I don’t know if this will even work for languages where number doesn’t go at the end. Afaik in Chinese it goes like “1 Level” instead of “Level 1”, and I don’t know if Godot will handle it properly.

Godot can’t translate parts of a string, if you give "LEVEL %s" as a parameter to tr it’s not going to do anything unless there is a translation key that is exactly "LEVEL %s"

So if you want to translate "LEVEL %s", then your translation should be "LEVEL %s""Level %s". Then for languages like apparently Chinese, just change the translated string to something like "%s Level"

(Not sure if that was clear this is what it would look like in a .csv translation file)
image

1 Like

As a rule of thumb, you don’t translate a part of the phrase, outside of its context. If there is a pattern, you can generate the translations, but still provide them to the code in a complete finished form. This allows to fix/change translations without messing with the code, which is the point of keeping the separate translation files in the first place.

1 Like

I get the concept, but I have no luck putting it to use.

I have replaced

nameLabel.Text = $"LEVEL {level.Id}"

with

nameLabel.Text = String.Format("LEVEL {0}", level.Id);

and changed the gd file to:

tr("LEVEL {0}") #adding loop here makes no sense since key is the same

This gives me key LEVEL {0} with translation Level {0}. Unfortunately output remains LEVEL 0, LEVEL 1, LEVEL 2, etc. In worst case scenario I will just manually translate from level 1 to level 10 (since I don’t expect more in my case) but this would be very stupid solution.

Ok this is a case of a brainfart, I forgot that you need to use Tr(string) too in C#. But @yesko reply was also useful so I will select it as solution.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.