Dixie's Lua Thread
Moderator: Forum Moderators
Dixie's Lua Thread
Well, I said I was gonna put myself to Lua, which I have done. For the past few days/weeks, I have read a few tutorials, browsed our wiki, etc. So now at least I understand the basic syntax of the language, I've looked at a few example, and I'm able to understand most of them.
Faithful to my old habits, I have a somewhat ambitious project to go with that. I've been planning it for the past week(s) and now I'm more or less ready to start coding the main engine. I don't have a firmview of exactly all that I'll need, but I'll start with some basic functions nd work from there. I will try to not ask too much for your help and correct as much as I can by myself. Hope I won't be too much of a burden
So I have started doing some basic stuff, and I'd need something clarified already. I know in Lua you can build tables inside tables inside tables, etc. I wondered how this behaved in WML, though, as I read the global Lua state was flushed upon closing Wesnoth (and thus the global Lua state not being reliable to store variables, which should be handed over to WML). If, for example, I wanted to store a costum weapon variable containing the values "attack" "hit_chance" and "critical_chance" (which makes it a table) in a unit's variables. I suppose "wesnoth.set_variable" wouldn't be appropriate. I suppose since the keys inside my tables are words and not numbers, "wesnoth.set_variable_array" ain't the right option either (can my_unit.variables even contain arrays, btw?). The wiki also mentions "metatables" and "proxy arrays", but I'm not clear on the meaning of those. I'd naturally tend towards the metatable, but I'm not really sure how it'd behave in my_unit.variables. It mentions "WML objects", I suppose those are big containers such as a unit or a side. Can a unit hold a WML object in its variables?
Hmm... I think that's all for now. Thanks a lot!
Faithful to my old habits, I have a somewhat ambitious project to go with that. I've been planning it for the past week(s) and now I'm more or less ready to start coding the main engine. I don't have a firmview of exactly all that I'll need, but I'll start with some basic functions nd work from there. I will try to not ask too much for your help and correct as much as I can by myself. Hope I won't be too much of a burden
So I have started doing some basic stuff, and I'd need something clarified already. I know in Lua you can build tables inside tables inside tables, etc. I wondered how this behaved in WML, though, as I read the global Lua state was flushed upon closing Wesnoth (and thus the global Lua state not being reliable to store variables, which should be handed over to WML). If, for example, I wanted to store a costum weapon variable containing the values "attack" "hit_chance" and "critical_chance" (which makes it a table) in a unit's variables. I suppose "wesnoth.set_variable" wouldn't be appropriate. I suppose since the keys inside my tables are words and not numbers, "wesnoth.set_variable_array" ain't the right option either (can my_unit.variables even contain arrays, btw?). The wiki also mentions "metatables" and "proxy arrays", but I'm not clear on the meaning of those. I'd naturally tend towards the metatable, but I'm not really sure how it'd behave in my_unit.variables. It mentions "WML objects", I suppose those are big containers such as a unit or a side. Can a unit hold a WML object in its variables?
Hmm... I think that's all for now. Thanks a lot!
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: Dixie's Lua Thread
So, from one table-confused person to another...
Whenever the word "proxy" or "userdata" appears it means it's a reference to a C++ object in the engine, e.g. a unit from get_units. The difference to a wml object representing a unit is e.g. that you don't need to unstore_unit or put_unit your unit to let (some) changes have affect, e.g. you can do unit_var.side = 2 and it has affect instantly.
wml objects are the lua versions of wml code blocks, e.g.
corresponds to (untested ),
so a unit can take a wml object into its variables with e.g. wesnoth.fire("set_variable", ...).
EDIT
Upon rereading this critical "encoding wml objects into lua tables" section the xxxxth time, I see that a "wml object" is in silene's terminology the WML code block, while its lua version is the wml table.
@silene I think the section would be better understanable I you used consistent terminology if you mean the same thing, e.g. Scalar fields = Lua named fields.
yes, on the wml side at least (you can even store a unit to the variables of another one)Dixie wrote:(can my_unit.variables even contain arrays, btw?).
The meta-thing is only shortcut stuff afaik, that means you don't need to write so much in your lua code. Never used it so far.The wiki also mentions "metatables" and "proxy arrays", but I'm not clear on the meaning of those.
Whenever the word "proxy" or "userdata" appears it means it's a reference to a C++ object in the engine, e.g. a unit from get_units. The difference to a wml object representing a unit is e.g. that you don't need to unstore_unit or put_unit your unit to let (some) changes have affect, e.g. you can do unit_var.side = 2 and it has affect instantly.
I suggest to write yourself a global debug-message function that outputs not only the value but also the type of a variable (using wesnoth.message and type() which is a function in the "basic" library.)silene wrote:For instance, the following three scripts are strictly equivalent:Code: Select all
wesnoth.set_variable("counter", 1 + wesnoth.get_variable "counter") -- local V = helper.set_wml_var_metatable {} V.counter = 1 + V.counter -- helper.set_wml_var_metatable(_G) counter = 1 + counter
wml objects are the lua versions of wml code blocks, e.g.
Code: Select all
[tag]
key=value
[subtag]
subkey=subvalue
[subtag]
[/tag]
Code: Select all
wesnoth.fire("tag", {{key = "value", {"subtag", {subkey = "subvalue"}}}})
EDIT
Upon rereading this critical "encoding wml objects into lua tables" section the xxxxth time, I see that a "wml object" is in silene's terminology the WML code block, while its lua version is the wml table.
@silene I think the section would be better understanable I you used consistent terminology if you mean the same thing, e.g. Scalar fields = Lua named fields.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
Re: Dixie's Lua Thread
Hmmm... interesting. So if I understand correctly:
1) I can store whatever I like in a my_unit.variables, be it an array/table, a dictionnary-table, another unit, anything. That's nice and will definitely make my life easier
2) Metatable is useful when you have a big batch of Lua variables you want to transfer to wml all at once. In other words, it is merely a short cut to avoid spamming "wesnoth.set_variable" an infinite amont of times.
3) If I store a wml object (variable?) using the proxy thing, it will automatically be synced to the game, saving me the trouble of unstore or put_unit. For exemple:
would be the same as:
Right? Btw, I don't think I understood/used the function's arguments/return wrong?
Thanks for your fast answer!
1) I can store whatever I like in a my_unit.variables, be it an array/table, a dictionnary-table, another unit, anything. That's nice and will definitely make my life easier
2) Metatable is useful when you have a big batch of Lua variables you want to transfer to wml all at once. In other words, it is merely a short cut to avoid spamming "wesnoth.set_variable" an infinite amont of times.
3) If I store a wml object (variable?) using the proxy thing, it will automatically be synced to the game, saving me the trouble of unstore or put_unit. For exemple:
Code: Select all
function apply_damage(damage_var, unit_id)
wesnoth.fire("store_unit", { id=unit_id, variable = "unit_to_damage" })
local u = get_variable_proxy_array "unit_to_damage"
u.hitpoints = u.hitpoints - damage_var
return
end
Code: Select all
function apply_damage(damage_var, unit_id)
wesnoth.fire("store_unit", { id=unit_id, variable = "unit_to_damage" })
wesnoth.set_variable("unit_to_damage.hitpoints", unit_to_damage.hitpoints - damage_var)
wesnoth.fire("unstore_unit", { variable = "unit_to_damage" })
return
end
Thanks for your fast answer!
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
Re: Dixie's Lua Thread
It is appropriate:Dixie wrote:If, for example, I wanted to store a costum weapon variable containing the values "attack" "hit_chance" and "critical_chance" (which makes it a table) in a unit's variables. I suppose "wesnoth.set_variable" wouldn't be appropriate.
Code: Select all
wesnoth.set_variable("custom_weapon", { attack = 17, hit_chance = 42, ... })
Code: Select all
[custom_weapon]
attack="17"
hit_chance="42"
...
[/custom_weapon]
No it isn't. Here is example:Dixie wrote:I suppose since the keys inside my tables are words and not numbers, "wesnoth.set_variable_array" ain't the right option either (can my_unit.variables even contain arrays, btw?).
Code: Select all
helper.set_variable_array("custom_weapon", { { attack = 17, hit_chance = 42 }, { attack = 33 } })
Code: Select all
[custom_weapon]
attack="17"
hit_chance="42"
[/custom_weapon]
[custom_weapon]
attack="33"
[/custom_weapon]
A metatable is a Lua feature that modifies the behavior of an object; you won't need to define new ones for a while but the engine uses lot of them behind the scenes for proxy objects. A proxy is an object that doesn't get contain its own data; when it is read or written, the data transparently go through the object toward its original location, e.g. a wml variable or a unit on the map.[/quote]Dixie wrote:The wiki also mentions "metatables" and "proxy arrays", but I'm not clear on the meaning of those.
Yes, in the terminology I use, a "WML object" is the content of a WML tag: its attributes, its nested tags, and their contents. A "table" is a Lua base object. A "WML table" is a Lua "table" whose content can be converted to a "WML object" without error. And the other way, whenever you query the engine for a "WML object" (e.g. wesnoth.get_variable or the __cfg fields of proxy objects), you get a "table" which is in fact a "WML table".Anonymissimus wrote:Upon rereading this critical "encoding wml objects into lua tables" section the xxxxth time, I see that a "wml object" is in silene's terminology the WML code block, while its lua version is the wml table.
I didn't mean the same thing. A scalar field is a field that contains a scalar value, e.g. boolean, integer, string, translatable string. A named field is a field that has a name. For instance, the following Lua table has three named fields A, B, C:Anonymissimus wrote:@silene I think the section would be better understanable I you used consistent terminology if you mean the same thing, e.g. Scalar fields = Lua named fields.
Code: Select all
{ A = 1, B = { D = 2, E = 3 }, C = { 4, F = 5 } }
I'm assuming that "my_unit.variables" represents a WML variable; for instance, you set it by wesnoth.set_variable("my_unit.variables", something). In that case, you can indeed store anything into it, as long as it is a WML object. Note that most things can be encoded as WML objects, so it's not an issue, but the first times, you will probably try to store illformed things.Dixie wrote:1) I can store whatever I like in a my_unit.variables, be it an array/table, a dictionnary-table, another unit, anything. That's nice and will definitely make my life easier
Almost. Proxy objects are the shortcut. Metatables are just an implementation detail of them.Dixie wrote:2) Metatable is useful when you have a big batch of Lua variables you want to transfer to wml all at once. In other words, it is merely a short cut to avoid spamming "wesnoth.set_variable" an infinite amont of times.
No. While proxy objects automatically transmit data to something, this something is not magically guessed. So, considerDixie wrote:3) If I store a wml object (variable?) using the proxy thing, it will automatically be synced to the game, saving me the trouble of unstore or put_unit. For exemple:
would be the same as:Code: Select all
function apply_damage(damage_var, unit_id) wesnoth.fire("store_unit", { id=unit_id, variable = "unit_to_damage" }) local u = get_variable_proxy_array "unit_to_damage" u.hitpoints = u.hitpoints - damage_var return end
Code: Select all
function apply_damage(damage_var, unit_id) wesnoth.fire("store_unit", { id=unit_id, variable = "unit_to_damage" }) wesnoth.set_variable("unit_to_damage.hitpoints", unit_to_damage.hitpoints - damage_var) wesnoth.fire("unstore_unit", { variable = "unit_to_damage" }) return end
Code: Select all
local u = helper.get_variable_proxy_array "unit_to_damage"
u[1].hitpoints = u[1].hitpoints - damage_var
Second, u[1] is a proxy to the first WML container with name [unit_to_damage] in the [variables] zone of your scenario. So any access to the proxy will just read and write WML variables, nothing more. You still have to unstore the unit to put it back onto the map.
If you wanted a proxy to a real unit instead of WML variables, you should have used a different function.
Code: Select all
local u = wesnoth.get_units { id = unit_id }
u[1].hitpoints = u[1].hitpoints - damage_var
Code: Select all
local u = wesnoth.get_units { id = unit_id }
local u_wml = u[1].__cfg
u_wml.hitpoints = u_wml.hitpoints - damage_var
wesnoth.put_unit(u_wml)
Function arguments look fine. The return statement is fine too. It is just useless since it is the last statement of your function and it doesn't return any particular value.Dixie wrote:Btw, I don't think I understood/used the function's arguments/return wrong?
Re: Dixie's Lua Thread
Hm, very interesting. And informative. I guess I missed the wesnoth.get_units, it is indeed a great tool. And I'm definitely gonna do my thing for 1.9, since Lua seems to have many significant upgrades in it. Not gonna bother with 1.8
Continuing with variables, tables and dictionnaries, I think I'm able to get this one out by myself, but I'll I'd just like to be confirmed I'm understanding this correctly:
Am I right to assume that:
> string_var = "sub_table"
> table.sub_table.sub_sub_table.key == table["sub_table"].sub_sub_table.key == table[string_var].sub_sub_table.key == table[string_var".sub_sub_table"].key == table["sub_table"."sub_sub_table"].key == table["sub_table.sub_sub_table"].key == table["sub_table.sub_sub_table"."key"]
true
(well, I'm mostly testing the variables names, I'm not 100% convinced this would be a correct expression with that many ==s)
If not, what is wrong/which ones don't work? Are there other ways of doing this I haven't thought of?
Thanks a lot! I'm beginning to get a more global understanding of the thing, it looks promising
Continuing with variables, tables and dictionnaries, I think I'm able to get this one out by myself, but I'll I'd just like to be confirmed I'm understanding this correctly:
Am I right to assume that:
> string_var = "sub_table"
> table.sub_table.sub_sub_table.key == table["sub_table"].sub_sub_table.key == table[string_var].sub_sub_table.key == table[string_var".sub_sub_table"].key == table["sub_table"."sub_sub_table"].key == table["sub_table.sub_sub_table"].key == table["sub_table.sub_sub_table"."key"]
true
(well, I'm mostly testing the variables names, I'm not 100% convinced this would be a correct expression with that many ==s)
If not, what is wrong/which ones don't work? Are there other ways of doing this I haven't thought of?
Thanks a lot! I'm beginning to get a more global understanding of the thing, it looks promising
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: Dixie's Lua Thread
String concatenation is done with ..
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
Re: Dixie's Lua Thread
Yeah I know. What I'm trying to do, in fact, is variable substitution in order to call another variable. If I am not mistaken, it would have the following wml equivalent:
{VARIABLE string_var "sub_table"}
{IF_VAR table.sub_table.sub_sub_table.key equals table.$string_var|.sub_sub_table.key (
# etc.
And, in the mean time, I wondered how mixing the "table[sub_table]" notation with the "table.subtable" one behaved (I would think it follows the same rules in WML, but I'm not sure how it behaves in there either).
Sorry if it was not clear, I hope it is better this time, thanks anyway
EDIT: Sorry, I just realised what you probably meant with your string concatanation reply: my "table[string_var .. ".sub_sub_table"].key attempt, right?
{VARIABLE string_var "sub_table"}
{IF_VAR table.sub_table.sub_sub_table.key equals table.$string_var|.sub_sub_table.key (
# etc.
And, in the mean time, I wondered how mixing the "table[sub_table]" notation with the "table.subtable" one behaved (I would think it follows the same rules in WML, but I'm not sure how it behaves in there either).
Sorry if it was not clear, I hope it is better this time, thanks anyway
EDIT: Sorry, I just realised what you probably meant with your string concatanation reply: my "table[string_var .. ".sub_sub_table"].key attempt, right?
Last edited by Dixie on August 12th, 2010, 2:38 pm, edited 1 time in total.
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
Re: Dixie's Lua Thread
Yes. Note that you have nonscalar named fields, so, either table is a plain Lua table (not a WML table), or it is a proxy object to a WML variable.Dixie wrote:Am I right to assume that:
> string_var = "sub_table"
> table.sub_table.sub_sub_table.key == table["sub_table"].sub_sub_table.key == table[string_var].sub_sub_table.key
Syntax errors. (See below for the behavior of the fixed versions.)Dixie wrote: == table[string_var".sub_sub_table"].key == table["sub_table"."sub_sub_table"].key == table["sub_table.sub_sub_table"."key"]
No if it is a plain Lua table.Dixie wrote: == table["sub_table.sub_sub_table"].key
Yes if it is a proxy object to a WML variable.
Re: Dixie's Lua Thread
So I can't do this in Lua, unless I got it through wesnoth.get_variable_proxy_array, is that it?silene wrote:No if it is a plain Lua table.Dixie wrote: == table["sub_table.sub_sub_table"].key
Yes if it is a proxy object to a WML variable.
Either way, I guess this would give the same result? :
table["sub_table"["sub_sub_table"]].key
Would this version be true? :
table.sub_table.sub_sub_table.key == table["sub_table"]["sub_sub_table"].key
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
Re: Dixie's Lua Thread
Yes and no. The exact same mechanism is enabled by helper.set_wml_var_metatable:Dixie wrote:So I can't do this in Lua, unless I got it through wesnoth.get_variable_proxy_array, is that it?silene wrote: No if it is a plain Lua table.
Yes if it is a proxy object to a WML variable.
Code: Select all
-- In the code below, V can be used to transparently access any WML variable:
local V = helper.set_wml_var_metatable {}
assert(V.table["sub_table.sub_sub_table"].key == V.table.sub_table.sub_sub_table.key)
-- In the code below, you don't even need a prefix any longer.
helper.set_wml_var_metatable(_G)
assert(table["sub_table.sub_sub_table"].key == table.sub_table.sub_sub_table.key)
Syntax error, and I can't even imagine what it would actually mean.Dixie wrote:Either way, I guess this would give the same result? :
table["sub_table"["sub_sub_table"]].key
Yes for both plain Lua tables and proxies to WML variables.Dixie wrote:table.sub_table.sub_sub_table.key == table["sub_table"]["sub_sub_table"].key
Re: Dixie's Lua Thread
Thanks for your answers I'm still not 100% clear with metatables and proxies, but I'm trying to complete my understanding with the Lua 5.1 user guide. It isn't really a decisive concern right now, anyway, it's just for my personnal growth as a Lua user.
More importantly, I have run into the following two errors. I have narrowed down what seems to cause the problem, but I don't really understand why there is a problem.
Error 1: Is produced by the following code:
So I guess I am not understanding correctly how to call a function defined in a lua file. I thought it was so. I defined them with wesnoth.dofile, like this:
How should I call the function instead? Directly with generate_inventory()?
Error 2: Is caused by this code (which is in the generate_inventory() function) and apparently has something to do with one of the two dots, but I don't understand what I did wrong:
Writing this, I realise I haven't tried using eq[weight] instead of eq.weight but they are supposed to be equivalent, afaik
By the way, I think I've seen places where they use a semi colon (";") at the end of such statements, and others where there weren't. Is there a rule about that?
Thanks again!
More importantly, I have run into the following two errors. I have narrowed down what seems to cause the problem, but I don't really understand why there is a problem.
Error 1: Is produced by the following code:
Code: Select all
[event]
name=preload
first_time_only=no
[lua]
code=<<
wesnoth.dofile "~add-ons/The_Fall_of_Wesnoth/lua/fow_inventory.lua"
>>
[/lua]
[/event]
Code: Select all
[lua]
code=<< wesnoth.set_variable("inventory", fow_inventory.generate_inventory()) >>
[/lua]
Error 2: Is caused by this code (which is in the generate_inventory() function) and apparently has something to do with one of the two dots, but I don't understand what I did wrong:
Code: Select all
if eq.weight < 0
then
local eq.weight = 0
end
By the way, I think I've seen places where they use a semi colon (";") at the end of such statements, and others where there weren't. Is there a rule about that?
Thanks again!
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
Re: Dixie's Lua Thread
Note that you don't have to perform screen captures to get the error messages. You can just open the console or the stderr.txt file and copy-paste them.
Local variables are useful for giving shorter name to complex expressions and avoid to compute them again and again. In the case of the apply_damage function, the variable u is declared local, because once the function has ended, nobody no longer care that there was something called u in the function; the name was useful only for the duration of the function. The name shouldn't escape the function and pollute the namespace of other functions.
If that is the name you gave to your function, then yes.Dixie wrote:How should I call the function instead? Directly with generate_inventory()?Code: Select all
wesnoth.set_variable("inventory", fow_inventory.generate_inventory())
That's a serious misunderstanding of what a local variable is. A local variable defines a new temporary object whose name lives only for the time of the current block, that is, between "then" and "end" in your example. (The content of the temporary object may live for a longer time though, if it is transfered elsewhere.) You shouldn't be creating a new object there, you should be modifying the value of an existing one. So get rid of local.Dixie wrote:Code: Select all
if eq.weight < 0 then local eq.weight = 0 end
Local variables are useful for giving shorter name to complex expressions and avoid to compute them again and again. In the case of the apply_damage function, the variable u is declared local, because once the function has ended, nobody no longer care that there was something called u in the function; the name was useful only for the duration of the function. The name shouldn't escape the function and pollute the namespace of other functions.
Semi-colons are mandatory only when there is an ambiguity about the end of the previous statement and the start of the next one. I think the only such case in Lua is when a statement starts with a parenthesis. This hardly happens, so you usually never need to put semi-colons.Dixie wrote:By the way, I think I've seen places where they use a semi colon (";") at the end of such statements, and others where there weren't. Is there a rule about that?
Re: Dixie's Lua Thread
Hm, good catch about local. The variable eq is local to the function it's in. Would that if statement write eq.weight to _G, or would it still keep it local to the function? Would I need to specifically do eq.weight = nil at some later point? A truncated version of the function, for the sake of exemple:
Edit:
I think I understood something wrong with functions and the return part. I thought that if a function returned a table, it would be treated as a table when it is called, not a function returning a table. Or is that what the metatable thing is used for?
This line:
generates this error:
Would it work better if I had something like this?
Code: Select all
local get_eq_stats = function(get_mat, get_equip)
local eq = { weight = material[get_mat].weight + equipment[get_equip].weight }
if eq.weight < 0
then
eq.weight = 0
end
return eq
end
I think I understood something wrong with functions and the return part. I thought that if a function returned a table, it would be treated as a table when it is called, not a function returning a table. Or is that what the metatable thing is used for?
This line:
Code: Select all
wesnoth.set_variable("inventory", generate_inventory())
Here's the function it calls:error wrote:[string " wesnoth.set_variable("inventory", generate..."]:1: in main chunk
20100813 09:36:45 error scripting/lua: [string "wesnoth.set_variable("inventory", generate_..."]:1: bad argument #2 to 'set_variable' (WML table or scalar expected, got table)
Code: Select all
generate_inventory = function()
local inv_var = {}
for i,v in ipairs(item)
do
table.insert(inv_var, { amount=0, equip=0, stats=v })
end
for i,v in ipairs(inv_var, material)
do
pair_mat_eq(i)
end
for i,v in ipairs(relic)
do
table.insert(inv_var, { amount=0, equip=0, stats=v })
end
return inv_var
end
Code: Select all
default_inventory = generate_inventory()
wesnoth.set_variable("inventory", default_inventory)
default_inventory = nil
Last edited by Dixie on August 13th, 2010, 1:56 pm, edited 1 time in total.
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
-
- Inactive Developer
- Posts: 2461
- Joined: August 15th, 2008, 8:46 pm
- Location: Germany
Re: Dixie's Lua Thread
The scope of a variable declared local where it's valid is limited to the function or file where it appears first, until the end of that function or file. (It's the same principle in other languages.)
EDIT
In your case above, deducting from silene above, who said that it's limited to the "current block" which can also be an if then end statement, eq lives until the end of the function but its content may live further at that point where get_eq_stats is called if you catch the returned value in a variable.
EDIT2
Regarding your problem, you probably create subtables instead of named fields so I'd try leaving away the {} when inserting the fields. That's what I call table confusion, it's somehow hard to get a good debug message of inv_var (in your case) that shows the structure of the table.
not in lua (it can be very important in C++...)Would I need to specifically do eq.weight = nil at some later point?
EDIT
In your case above, deducting from silene above, who said that it's limited to the "current block" which can also be an if then end statement, eq lives until the end of the function but its content may live further at that point where get_eq_stats is called if you catch the returned value in a variable.
EDIT2
Regarding your problem, you probably create subtables instead of named fields so I'd try leaving away the {} when inserting the fields. That's what I call table confusion, it's somehow hard to get a good debug message of inv_var (in your case) that shows the structure of the table.
Last edited by Anonymissimus on August 13th, 2010, 2:14 pm, edited 2 times in total.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
A Simple Campaign: campaign draft for wml starters • Plan Your Advancements: mp mod
The Earth's Gut: sp campaign • Settlers of Wesnoth: mp scenario • Wesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
Re: Dixie's Lua Thread
More precisely, the name of the variable is local to the function. But the content of the variable stays alive as long as needed. Once the function has ended, you can no longer use the name to access the content, but if you have other ways to access it, it will stay around.Dixie wrote:Hm, good catch about local. The variable eq is local to the function it's in.
Nothing writes to _G in your function. "eq.weight" is just a field of the table "eq". As long as this table exists (under this name or another), its fields exist too.Dixie wrote:Would that if statement write eq.weight to _G, or would it still keep it local to the function?
It probably won't be called "eq.weight" since the name "eq" no longer exists, unless you have decided to give the value returned by the function the name "eq".Dixie wrote:Would I need to specifically do eq.weight = nil at some later point?
Anyway, while uncommon, there are situations where one wants to write nil to a field of a table or to a global variable (which is just a field of _G). As I said above, values will stay around as long as there is still a way to access them. Writing nil to all the names of a value ensures that the value can no longer be accessed, hence freeing memory earlier. For now, I doubt you have a use for this optimization. A better usage of nil is to make a field disappear from a table: once you have done "eq.weight = nil", all the users will see the table as empty (no "weight" field at all).