Jump to content

Problem with the translation


Recommended Posts

I saw in the scripts/questral/util/loc.lua file information about formatting the translation using:

Quote

loc.format( ‘I choose you, {1:Pikachu|Squirtle}!’, 1 ) --> ‘I choose you, Pikachu!’

loc.format( ‘I ate {1*an|some} {1*apple|apples}’, 1 ) --> ‘I ate an apple’.

But I don't really understand how I can use this directly through the .po translation file. I tried to do something like this: {2:{name.megatreemon}}'s Sylvan Weave and Mother Treek|Test Treek and it didn't work, so I made changes to the code:

local function ReplaceNameInTable(string_table, fns)
    for k,v in pairs(string_table) do
        if loc.IsValidStringKey(k) then
            if type(v) == string then
                string_table[k] = loc.format(ReplaceNameInString(v, fns), 1, 2, 3, 4, 5) -- add this
            elseif type(v) == table then
                ReplaceNameInTable(v, fns)
            end
        end
    end
end

and it started working, but there was another problem. Strings that do not use the {1:{}} format are displayed in the game as Mother Treek|Test Treek. I think it's not very convenient when I have to add {1:{name.megatreemon}} to each variable if I want to get the first variant or {2:{name.megatreemon}} if I want to get the 2nd, 3rd, 4th variant of the translation. Is there any easier way to use this functionality without changing many lines in the translation or in the code.

ideally, I would like this behaviour in the po file:
{name.megatreemon}'s Sylvan Weave --> Mother Treek's Sylvan Weave
{2:{name.megatreemon}}'s Sylvan Weave --> ’Test Treek's Sylvan Weave’
And the original strings that can be displayed in the game: Mother Treek not Mother Treek|Test Treek
image.png.da3a3c08098b5664099ce3a8da0e072e.png

  • Developer

The comments in loc.lua aren't really intended for translators. They allow us to add random name selections or plurality to the game where we build the text UI in lua, but that logic must exist before the translation can use it.

Quote

ideally, I would like this behaviour in the po file:
{name.megatreemon}'s Sylvan Weave --> Mother Treek's Sylvan Weave
{2:{name.megatreemon}}'s Sylvan Weave --> ’Test Treek's Sylvan Weave’
And the original strings that can be displayed in the game: Mother Treek not Mother Treek|Test Treek

If you want to rename some of the items, you can ignore the {name} macro and set whatever msgstr you want:

#. STRINGS.ITEMS.BODY.megatreemon.name
msgctxt "STRINGS.ITEMS.BODY.megatreemon.name"
msgid "{name.megatreemon}'s Sylvan Weave"
msgstr "Test Treek's Sylvan Weave"

Or to replace mother treek's name everywhere (this first string is used for every {name.megatreemon} -- see comments in string_names.lua):

#. STRINGS.NAMES.megatreemon
msgctxt "STRINGS.NAMES.megatreemon"
msgid "Mother Treek"
msgstr "Test Treek"

#. STRINGS.NAMES_PLURAL.megatreemon
msgctxt "STRINGS.NAMES_PLURAL.megatreemon"
msgid "Mother Treeks"
msgstr "Test Treeks"

#. STRINGS.NAMES_PLURALITY.megatreemon
msgctxt "STRINGS.NAMES_PLURALITY.megatreemon"
msgid "Mother Treek|Mother Treeks"
msgstr "Test Treek|Test Treeks"

 

If you want the game to randomly select a different name for Mother Treek, then you can't do that solely through a translation -- it has to be supported everywhere we display the creature's name.

Hope that helps!

On 8/3/2024 at 12:45 AM, David_B said:

The comments in loc.lua aren't really intended for translators. They allow us to add random name selections or plurality to the game where we build the text UI in lua, but that logic must exist before the translation can use it.

If you want to rename some of the items, you can ignore the {name} macro and set whatever msgstr you want:

#. STRINGS.ITEMS.BODY.megatreemon.name
msgctxt "STRINGS.ITEMS.BODY.megatreemon.name"
msgid "{name.megatreemon}'s Sylvan Weave"
msgstr "Test Treek's Sylvan Weave"

Or to replace mother treek's name everywhere (this first string is used for every {name.megatreemon} -- see comments in string_names.lua):

#. STRINGS.NAMES.megatreemon
msgctxt "STRINGS.NAMES.megatreemon"
msgid "Mother Treek"
msgstr "Test Treek"

#. STRINGS.NAMES_PLURAL.megatreemon
msgctxt "STRINGS.NAMES_PLURAL.megatreemon"
msgid "Mother Treeks"
msgstr "Test Treeks"

#. STRINGS.NAMES_PLURALITY.megatreemon
msgctxt "STRINGS.NAMES_PLURALITY.megatreemon"
msgid "Mother Treek|Mother Treeks"
msgstr "Test Treek|Test Treeks"

 

If you want the game to randomly select a different name for Mother Treek, then you can't do that solely through a translation -- it has to be supported everywhere we display the creature's name.

Hope that helps!


I get your point, but then that breaks the whole logic of improving translation by variables. I made some changes to the code I wrote about above and it made the changes a lot better, I can change 1 name and it will change everywhere. I have several variants of the word and depending on which form of ending I need, I use that one.
image.png.9595f7b8937ce9f197f5b4e1f165f4c9.png

image.png.aaefb9e1b9e1671ac36bf1d7ef91a3cd.png

And I solved the problem with the names as follows:

local function ReplaceNameInString(str, fns, clear_names)
	if str:find("{", nil, true) and clear_names == false then -- TODO(PERF): Does skipping gsub for plain strings help load perf?
		-- Prefabs names are limited to lowercase letters, numbers, and
		-- underscore.
		
		str = str:gsub('([?:#.*%%]){name.([_a-z0-9]-)}', fns.singular) 	-- if have :#&...
		str = str:gsub('{name.([_a-z0-9]-)}', fns.singular)				-- else
		...
	elseif clear_names == true then    -- dell | in name
		local tokens = {}
		tokens = str:split_pattern("|")
		str = #tokens > 0 and tokens[1] or str
	end
	return str
end

fns.singular = function(operand, _key)  -- key supp
  local key = _key or operand
  local name = name_table_singular[key]
  kassert.assert_fmt(name, "Unknown name. Did you forget to add '%s' to STRINGS.NAMES?", key)
  if _key == nil then
    local tokens = {}
    tokens = name:split_pattern("|")
    return #tokens > 0 and tokens[1] or name_table_singular[key] or key
  else
    return operand..name_table_singular[key] or key
  end
end


 

  • Developer

So I understand: Are you saying that in Ukrainian, the ending for "Rots" varies depending on the context? Maybe depending on the number of rots (1, 2, 3+)?

So that means a single name_multiple.rot sometimes doesn't work because it depends on the quantity, which is known when translating the string but more convenient if using a variable?

 

On 8/30/2024 at 9:53 PM, David_B said:

So I understand: Are you saying that in Ukrainian, the ending for "Rots" varies depending on the context? Maybe depending on the number of rots (1, 2, 3+)?

So that means a single name_multiple.rot sometimes doesn't work because it depends on the quantity, which is known when translating the string but more convenient if using a variable?

 

Yes, in some languages, the ending of a word can change depending on the context. This is true not only for the plural but also for the singular. the number 2 is just a choice of which word I want to select from the available list of options, not a quantity. And using variables really makes translation more convenient. Because if I want to change the name somehow, or you change it, I don't need to go through all the lines where it should have changed. I update all possible variants of the word and that's it.

I'm also looking forward to the support of uploading custom fonts, because all attempts to upload them have failed and I have to replace the existing fonts in the game to make them work at least somehow. I saw that you are still in the process of adding this option, but I would be grateful if it will be available before the official support for modifications and translations

local Localization = require "questral.localization"
return Localization{
    id = "en",
    is_game_authored_language = true,
    name = "English",
    fonts =
    {
		-- TODO(L10n): We should use this to load fonts instead of
		-- fonts.lua since it allows custom fonts per language.
		blockhead = { font = "fonts/blockhead_sdf.zip", sdfthreshold = 0.4, sdfboldthreshold = 0.33 },
        title = { font = "fonts/blockhead_sdf.zip", sdfthreshold = 0.5, sdfboldthreshold = 0.33, scale = 0.6, line_height_scale = 0.85 },
        fixed = { font = "fonts/inconsolata_sdf.zip", sdfthreshold = 0.5, sdfboldthreshold = 0.33, scale = 0.6, line_height_scale = 0.85 },
    },
    can_display_italic = true,
    can_display_bold = true,
    default_languages =
    {
        "en",
        "en-GB",
        "en-US",
        "en-CA",
    },
}

 

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...