Anonymissimus' lua thread

Discussion of Lua and LuaWML support, development, and ideas.

Moderator: Forum Moderators

Post Reply
User avatar
pauxlo
Posts: 1047
Joined: September 19th, 2006, 8:54 pm

Re: Anonymissimus' lua thread

Post by pauxlo »

Anonymissimus wrote:a question for silene:
For C++ I've been told that in these code snippets it's better to use the first variant due to memory allocation (for the variable j, it needs some time to reserve the memory every time it is declared):
lua:

Code: Select all

		local j
		for i = 2, 5 do
			j = i
		end

		for i = 2, 5 do
			local j = i
		end
This would only the case for very stupid compilers (or interpreters, if such would exist for C++). The local variable is put on the stack, and needs no "allocation" work - it is allocated with all the stack space needed for a function call at once, if at all - most C++ compilers (or compilers for any other compiled language) would generate exactly the same code for both variants. (It might be different if there is a (superfluous) initialization of the variable, though. And it certainly would be different if you are constructing objects or really dynamically allocation memory instead of a simple int or pointer variable.)

For interpreted languages like Lua, I don't know which of both variants (if any) would be more efficient. I suppose any difference would be not really worth the hassle to move a declaration, so declare your variables as local as possible.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Translatable strings in lua code - awkward

Post by Anonymissimus »

Translatable strings in lua code - awkward
Here is what it looks like in a "real world" example in SOW:

Code: Select all

settings.message = string.format("%s%u%s%u%s%u%s%u%s%u%s", tostring(_"Select what trade type you want to engage in?\nYou currently have:\n\t"), resources.lumber, tostring(_" units of lumber;\n\t"), resources.grain, tostring(_" units of grain;\n\t"), resources.wool, tostring(_" units of wool;\n\t"), resources.brick, tostring(_" units of brick;\n\t"), resources.ore, tostring(_" units of ore."))
This is problematic since I guess the translator will only see the single strings then, "units of lumber" etc which is presumably difficult to translate since it is out-of-context. But I don't see another way here since according to silene the underscore function _ is only valid before "literal" strings, that is, strings given directly afterwards by "", while strings like _"units of %u, units ..." won't be corectly handled then, so I need to cluster the strings this way. in wml however one can just put _"units of $var, units...".
Any way out ?

Also, why is it neccessary to put both lines:
_ = wesnoth.textdomain("wesnoth-sow")
-- #textdomain wesnoth-sow
And since the same _ doesn't work with just another #textdomain wesnoth-something both carry the same information (it's needed to assign _ = wesnoth.textdomain("wesnoth-something") too).
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: Translatable strings in lua code - awkward

Post by silene »

Anonymissimus wrote:Translatable strings in lua code - awkward
Here is what it looks like in a "real world" example in SOW:

Code: Select all

settings.message = string.format("%s%u%s%u%s%u%s%u%s%u%s", tostring(_"Select what trade type you want to engage in?\nYou currently have:\n\t"), resources.lumber, tostring(_" units of lumber;\n\t"), resources.grain, tostring(_" units of grain;\n\t"), resources.wool, tostring(_" units of wool;\n\t"), resources.brick, tostring(_" units of brick;\n\t"), resources.ore, tostring(_" units of ore."))
This is problematic since I guess the translator will only see the single strings then, "units of lumber" etc which is presumably difficult to translate since it is out-of-context. But I don't see another way here since according to silene the underscore function _ is only valid before "literal" strings, that is, strings given directly afterwards by "", while strings like _"units of %u, units ..." won't be corectly handled then, so I need to cluster the strings this way. in wml however one can just put _"units of $var, units...".
Any way out ?
I'm quite impressed; that's some misusage of printf! Try this instead:

Code: Select all

settings.message = string.format(tostring(_"Select what trade type you want to engage in?\nYou currently have:\n\t%d units of lumber;\n\t%d units of grain;\n\t%d units of wool;\n\t%d units of brick;\n\t%d units of ore."), resources.lumber, resources.grain, resources.wool, resources.brick, resources.ore)
Anonymissimus wrote:Also, why is it neccessary to put both lines:
_ = wesnoth.textdomain("wesnoth-sow")
-- #textdomain wesnoth-sow
And since the same _ doesn't work with just another #textdomain wesnoth-something both carry the same information (it's needed to assign _ = wesnoth.textdomain("wesnoth-something") too).
The #textdomain comment tells wmlxgettext (the tool used to extract translatable strings and to push them to translators) what is the textdomain of the strings that are after it in the file. The _ line defines a real Lua function. I agree they are kind of redundant, but they target different tools. Note that you could easily devise some Lua code such that there are a lot less wesnoth.textdomain call than #textdomain; for instance, if you were using several domains constantly, you could cache the result of wesnoth.textdomain.
User avatar
pauxlo
Posts: 1047
Joined: September 19th, 2006, 8:54 pm

Re: Translatable strings in lua code - awkward

Post by pauxlo »

Anonymissimus wrote:But I don't see another way here since according to silene the underscore function _ is only valid before "literal" strings, that is, strings given directly afterwards by "", while strings like _"units of %u, units ..." won't be corectly handled then,
Why do you assume this? I would understand literal string as only one pair of quotation marks, not as "may not contain any % signs".
a small printf-rant:
Anonymissimus wrote:so I need to cluster the strings this way. in wml however one can just put _"units of $var, units...".
Does this really work in WML with translated strings? Is the variable substitution done before or after translation? (I did not find the answer on the wiki by a quick look.)

Isn't there a way to access the WML variable substitution from Lua? Something like wesnoth.substitute_variables(string) would seem useful.
(It should substitute WML variables, not Lua ones.)
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: Translatable strings in lua code - awkward

Post by silene »

pauxlo wrote:One can use indexed arguments with printf, too: _ "units of %1$u, units ...", but I think most translators won't know this. (And I'm not sure this works in all printf-implementations.)
Yes, great feature, but not standard at all unfortunately.
pauxlo wrote:Does this really work in WML with translated strings? Is the variable substitution done before or after translation? (I did not find the answer on the wiki by a quick look.)
Variable substitution forces translation, so it works fine.
pauxlo wrote:Isn't there a way to access the WML variable substitution from Lua? Something like wesnoth.substitute_variables(string) would seem useful. (It should substitute WML variables, not Lua ones.)
No, there isn't such function. It can be written as:

Code: Select all

function substitute_variable(s)
  return wesnoth.tovconfig { value = s } .value
end
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Translatable strings in lua code - awkward

Post by Anonymissimus »

pauxlo wrote:I would understand literal string as only one pair of quotation marks, not as "may not contain any % signs".
It seems I understood "may not be inserted any variables". Since when not using string.format I'd need concatenation instead. Good I asked, but bit too late.

EDIT
Also, sometimes the variable to insert already is a translatable string while in the example from above the inserted variables are all numerical values which don't need to be translated.

Code: Select all

settings.message = string.format(tostring(_"\n%s's longest road is now %i units long."), sow_labels.player[player].name, victory.road)
sow_labels.player[player].name should be a translatable string such as _"Red".
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: Translatable strings in lua code - awkward

Post by silene »

Anonymissimus wrote:Also, sometimes the variable to insert already is a translatable string while in the example from above the inserted variables are all numerical values which don't need to be translated.

Code: Select all

settings.message = string.format(tostring(_"\n%s's longest road is now %i units long."), sow_labels.player[player].name, victory.road)
sow_labels.player[player].name should be a translatable string such as _"Red".
Then use tostring:

Code: Select all

settings.message = string.format(tostring(_"\n%s's longest road is now %i units long."), tostring(sow_labels.player[player].name), victory.road)
Note that if you often happen to substitute translatable strings, you may just as well define your own version of format to make the code lighter:

Code: Select all

funtion myformat(...)
  local args = { ... }
  for i = 1, #args do
    local v = args[i]
    if getmetatable(v) == "translatable string" then
      args[i] = tostring(v)
    end
  end
  return string.format(unpack(args))
end

settings.message = myformat(_"\n%s's longest road is now %i units long.", sow_labels.player[player].name, victory.road)
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: Anonymissimus' lua thread

Post by Anonymissimus »

Is there any way to
-(lua) display a call list (backtrace) but not throwing an error ? Just something to put into wesnoth.message().
-(wml or lua) detect which side is the current host ? Experiments with wesnoth.sides.controller seem futile.
-disable the "really end your turn ? You didn't yet move any unit" - confirmation dialog (preferences setting which I haven't found and/or (preferably) lua and/or wml). If not it becomes a feature request since it's disturbing for addons which turn BfW away from a fighting+unit moving game.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: Anonymissimus' lua thread

Post by silene »

Anonymissimus wrote:(lua) display a call list (backtrace) but not throwing an error ? Just something to put into wesnoth.message().
No. The debug.traceback would fit the bill (it's the one used by the engine in fact), but the debug namespace is disabled for user scripts. I don't think the traceback function is unsafe, so you can add it to the wesnoth namespace in lua.cpp if you feel like it. (Look at the first two lines of luaW_pcall for the way to recover the traceback function.)
Anonymissimus wrote:(wml or lua) detect which side is the current host ? Experiments with wesnoth.sides.controller seem futile.

No. I'm not even sure that the engine has this information; only the server cares about it.

Anonymissimus wrote:disable the "really end your turn ? You didn't yet move any unit" - confirmation dialog (preferences setting which I haven't found and/or (preferably) lua and/or wml). If not it becomes a feature request since it's disturbing for addons which turn BfW away from a fighting+unit moving game.

No. From a WML point of view, the less intrusive way might be to just select a unit and decrease its move points; that should be enough to confuse the engine.
Post Reply