Anonymissimus' lua thread

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

Moderator: Forum Moderators

Post Reply
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Anonymissimus' lua thread

Post by Anonymissimus »

The wesnoth core macro MODIFY_UNIT does not allow changing more than one key per unit per call. This results in the need to repeatedly store and unstore the unit (performance ?!) to change more than one key, or to not use the macro at all.
First I wrote a wml version of this functionality using [split]:
Spoiler:
This sets hitpoints=30 and max_moves=20 for all units on side=1.

Then I wanted to know whether this would've been easier with the help of "silene's darling" lua; to solve the question whether lua is worth being learned I need to learn it. :roll: There is a function modify_unit in helper.lua, which indeed allows modifying more than one variable per unit, which is probably the reason why silene has written it.

For editing reasons, I want to keep lua code and wml code completely separated in different files:

file setup.lua:

Code: Select all

<<
	helper = wesnoth.require "lua/helper.lua"
	--proxy = helper.set_wml_action_metatable {}
	--_ = wesnoth.textdomain "my-campaign"

	-- Define your global constants here.
	-- ...

	--helper.set_wml_var_metatable(_G)

	-- Define your global functions here.
	-- ...
>>
file modify_unit.lua:

Code: Select all

<< 
	--	helper.modify_unit({side=1},{hitpoints=100,max_moves=2})
	local args = ...
	--Accessing the text below works:
	--wesnoth.message(tostring(args.text))
	local filter=helper.get_child(args.__parsed,"filter")
	local variables=helper.get_child(args.__parsed,"variables")
	helper.modify_unit(filter,variables)
>>

Code: Select all

#define LUA FILE ARGS
	[lua]
		code = {~add-ons/Testcampaign/utils/lua/{FILE}.lua}
		[args]
			{ARGS}
		[/args]
	[/lua]
#enddef

#define SETUP_LUA
	[event]
		name=preload
		first_time_only=no
		{LUA setup ()}
	[/event]
#enddef

{SETUP_LUA}

	[event]
...
		
		{LUA modify_unit (
		[filter]
			side=1
			id=Hamel
		[/filter]
		[variables]
			hitpoints=100
			max_moves=10
		[/variables]
		)}
		
	[/event]
Is there a way to make the transfer of the arguments to the lua code easier ?
What is a good development environment for this language ? (e.g. live syntax check ?)

I'd like to see "proxy" and "table" to be documented better on the wiki.

Although lua doesn't seem to be hard to learn if one has already programming experience, I doubt that there'll be many wml authors who'll try it. There are problems:
-It requires learning a new language for little benefit.
-Mixing 2 languages - although I've solved that in a bit complicated way, so that I can use the appropriate language settings in my editor for each of the files.
-What additional stuff does lua allow - other than calculating sin(x) more easily in wml via access to the C math library now ?
After all, the complexity of both solutions for modifying several unit variables seems equal, since the function modify_unit in helper.lua must be added to the lua approach.

How is lua handled by the engine ? Is it parsed in the same way like wml ? The preprocessor at least seems to make no difference.
How is lua in terms of performance compared to wml ?

There's of course a ton of other questions but I'm finished for now.
Last edited by Anonymissimus on July 19th, 2010, 1:51 pm, edited 1 time in total.
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
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: some first steps in lua, questions and discussion

Post by Sapient »

This may not be directly related to your question, but I just wanted to point out that there is a much cleaner way to create this macro in WML than the way you attempted. Since you obviously know how [set_variables] mode=merge works, I am surprised you aren't using that to merge a "diff" WML into each unit.

e.g. to make all the Spearmen turn to side 2 and go to 1 hitpoint:

{MODIFY_UNITS type=Spearman hitpoints,side=1,2}

or to poison them:

{MODIFY_UNITS type=Spearman (
[status]
posioned=yes
[/status]
)}

it's quite possible...

however, to answer your question, one of the main benefits of learning lua is you don't *need* a macro. Instead, you should register an action handler, and invoke it like [just_like_any_other_tag] ... then pass in arguments to the tag...


A final note, as a WML author you really shouldn't be worrying about performance. If anything, you should be concerned with "WML bloat," which can be determined by the final line count of all your code after preprocessing (turn on uncompressed saves and save your game to get an idea). WML bloat has been shown to cause laggy responsiveness, especially during autosaves which occur at the beginning of every turn.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: some first steps in lua, questions and discussion

Post by silene »

Anonymissimus wrote:Then I wanted to know whether this would've been easier with the help of "silene's darling" lua; to solve the question whether lua is worth being learned I need to learn it. :roll: There is a function modify_unit in helper.lua, which indeed allows modifying more than one variable per unit, which is probably the reason why silene has written it.
Actually, it was more to test that the very first version of the Lua interface was usable. The fact that it handles several variables at once is just a side effect: the code for handling only one variable would be exactly the same (or worse, it would be more complicated if it had to error out in presence of several variables).
Anonymissimus wrote:For editing reasons, I want to keep lua code and wml code completely separated in different files:
That's a good decision, but one can do a bit better.

First, don't use strong quotes <<>> inside your Lua files. That way, the files will be pure Lua files, which means that you can ask you text editor to use syntactic coloration and you can directly send your Lua files to the Lua compiler/interpreter to test your files without having to launch Wesnoth. In other words, you get your "live syntax check".

Second, I wouldn't use several files, but one file with several functions:

Code: Select all

local helper = wesnoth.require "lua/helper.lua"
function modify_unit(args)
    args = args.__parsed
    local filter = helper.get_child(args, "filter")
    local variables = helper.get_child(args, "variables")
    helper.modify_unit(filter,variables)
end
-- other functions below
and then use it this way:

Code: Select all

[event]
    name=preload
    first_time_only=no
    [lua]
        code = "wesnoth.dofile 'Testcampaign/utils/lua/functions.lua'"
    [/lua]
[/event]
#define LUA FUNCTION ARGS
	[lua]
		code = "{FUNCTION}(...)"
		[args]
			{ARGS}
		[/args]
	[/lua]
#enddef
Anonymissimus wrote:Is there a way to make the transfer of the arguments to the lua code easier ?
As Sapient already mentioned, define new WML tags. The Lua code and the preload event are not modified; just add a registration point at the end of your Lua file:

Code: Select all

wesnoth.register_wml_action("modify_unit", modify_unit)
Then you don't need the LUA macro anymore, you can directly type:

Code: Select all

[modify_unit]
    [filter]
        side=1
        id=Hamel
    [/filter]
    [variables]
        hitpoints=100
        max_moves=10
    [/variables]
[/modify_unit]
Anonymissimus wrote:I'd like to see "proxy" and "table" to be documented better on the wiki.
Any particular thing you want me to explain better in wiki?
Anonymissimus wrote:Although lua doesn't seem to be hard to learn if one has already programming experience, I doubt that there'll be many wml authors who'll try it. There are problems:
-It requires learning a new language for little benefit.
It depends on your point of view. Lua is structured like a modern language, and anybody that knows Lua would have no difficulty to understand/switch to another programming language.
Anonymissimus wrote:-Mixing 2 languages - although I've solved that in a bit complicated way, so that I can use the appropriate language settings in my editor for each of the files.
That would not be the first time in Wesnoth' history. Think FormulaWML for instance.
Anonymissimus wrote:-What additional stuff does lua allow - other than calculating sin(x) more easily in wml via access to the C math library now ?
There isn't much more it can do; perhaps the only thing really lacking in plain WML with respect to Lua is access to the pathfinder. Anyway, the Lua interface wasn't written to give more control over the engine to scenarios, it was written to provide higher-level programming structures. You get floating-point arithmetic, string manipulation, array manipulation, dictionaries, generators, higher-order functions, and so on.

For instance, consider this file from LoW: replace_map.lua. It adds x= and y= attributes to the [replace_map] tag so that it no longer loads an entire new map but only a subset of it. I'm sure that the same loading functionality could be implemented in plain WML, but I'm also sure that I wouldn't be able to implement it in only 15 minutes and 30 lines.
Anonymissimus wrote:How is lua handled by the engine ? Is it parsed in the same way like wml ? The preprocessor at least seems to make no difference.
The embedded Lua code is preprocessed and parsed the same way than other WML (technically, it is just the value of an attribute from a tag). It is compiled on the fly, whenever the [lua] tag is executed. Lua files are compiled (they are never preprocessed nor parsed though since they are not embedded) whenever the "dofile" command is executed or the first time the "require" command is executed. So, to summarize, if you are using "dofile" and "register_wml_action" in a preload event, you will have no preprocessing nor parsing at all and a single compilation at scenario load time.
Anonymissimus wrote:How is lua in terms of performance compared to wml ?
It depends. The rule of thumb is that it is much faster. (As surprising as it may seems, there are even a few things for which a Lua script would be faster than even the corresponding C++ code added to Wesnoth, since it internalizes strings and hashes tables.) If you care about performance, just avoid accessing the __special fields (__cfg, __parsed, and so on) several times in the row; just do it once and for all, as in the modify_unit example above.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: some first steps in lua, questions and discussion

Post by Anonymissimus »

Sapient wrote:Since you obviously know how [set_variables] mode=merge works, I am surprised you aren't using that to merge a "diff" WML into each unit.

e.g. to make all the Spearmen turn to side 2 and go to 1 hitpoint:

{MODIFY_UNITS type=Spearman hitpoints,side=1,2}

or to poison them:

{MODIFY_UNITS type=Spearman (
[status]
posioned=yes
[/status]
)}
It was the first time for me using [set_variables] mode=merge, and I'm unsure whether I know how it works. ;) What would that part of the macro where a single unit variable (the container variable containing the unit) is modified about look like then ? I can't get a clear imagination of the code yet.
Sapient wrote:If anything, you should be concerned with "WML bloat," which can be determined by the final line count of all your code after preprocessing (turn on uncompressed saves and save your game to get an idea). WML bloat has been shown to cause laggy responsiveness, especially during autosaves which occur at the beginning of every turn.
I have one or two cases in my campaign with a serious slowdown...
So wml bloat, if I get it right, is caused by the way wml is made: The preprocessor inserts the code from macros at the positions where these macros are called, with parameters inserted (I used to think of this like an "inline" function in C++...), causing the code to get large. A way around this, while keeping the functionality, are true functions now provided by lua, which are kept separate: The same lua code is referenced from various positions where code from a macro would have been inserted all the time. But only if used in the way suggested by silene (loading the lua code with dofile or require) - doing it the way I wanted to do it the preprocessor inserts the lua code ?! 1:0 for lua...
silene wrote:Then you don't need the LUA macro anymore, you can directly type:

Code: Select all

[modify_unit]
    [filter]
        side=1
        id=Hamel
    [/filter]
    [variables]
        hitpoints=100
        max_moves=10
    [/variables]
[/modify_unit]
This features the problem that emacs+wesnoth mode (about the most "comfortable" editing environment for wml) won't know that new tag, disabling autocompletion and spamming "Tag not available in this context" messages on syntax check, making it hard to sort out that tags that really aren't available in their given context...
Any particular thing you want me to explain better in wiki?
Probably nothing particular. The way I understood it from about 2 days of reading and playing around is that in lua "table" is about the same like a container variable in wml / struct in C++, but it can also contain functions, since e.g. "helper" in my code seems to be a table, too.
It depends on your point of view. Lua is structured like a modern language, and anybody that knows Lua would have no difficulty to understand/switch to another programming language.
Lua features true functions, an implicit type system (I suppose) and variable/function modifiers (e.g. local). Stuff people who've only learned wml don't know about...
Eclipse+java is still the easiest way to learn programming I can think of. It features the live syntax check I mean (in case you misunderstood that) - display of errors as soon as one has just typed the code. Getting them after compiling without needing to launch wesnoth is still an improvement - 2:0 for lua...
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
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: some first steps in lua, questions and discussion

Post by Anonymissimus »

Is it right that functionalities from the global table wesnoth aren't accessible without starting wesnoth ?
Most of the functionalities from the files in /data/lua/ also aren't usable since they're using that table themselves ?
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: some first steps in lua, questions and discussion

Post by silene »

Anonymissimus wrote:Is it right that functionalities from the global table wesnoth aren't accessible without starting wesnoth ?
Most of the functionalities from the files in /data/lua/ also aren't usable since they're using that table themselves ?
That is right. Is there a reason for wanting to use the wesnoth table outside Wesnoth? I have considered several times providing a dummy implementation that would allow people to run LuaWML scripts outside Wesnoth, but in the end it was never worth it. Perhaps you have a need for it?
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: some first steps in lua, questions and discussion

Post by Anonymissimus »

silene wrote:
Anonymissimus wrote:Is it right that functionalities from the global table wesnoth aren't accessible without starting wesnoth ?
Most of the functionalities from the files in /data/lua/ also aren't usable since they're using that table themselves ?
That is right. Is there a reason for wanting to use the wesnoth table outside Wesnoth? I have considered several times providing a dummy implementation that would allow people to run LuaWML scripts outside Wesnoth, but in the end it was never worth it. Perhaps you have a need for it?
One of my main motivations to cope with lua is the lacking need to launch the wesnoth engine to test the code since it's a lot faster. Writing functionalities for wesnoth in lua without using the table wesnoth seems rather pointless so that's currently the only reason for me.
How much work would that be and what's the benefit ? Would the functions return initialized values then, but not calculate or do anything ?
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: some first steps in lua, questions and discussion

Post by silene »

Anonymissimus wrote:One of my main motivations to cope with lua is the lacking need to launch the wesnoth engine to test the code since it's a lot faster. Writing functionalities for wesnoth in lua without using the table wesnoth seems rather pointless so that's currently the only reason for me.
Sorry, don't understand. The "wesnoth" table contains C++ function exported by the engine, and they are the only way for a LuaWML script to interact with the external world in general and with Wesnoth in particular. So a Lua script that wouldn't use them would indeed be pointless from a WML point of view. But on the other hand, there is no point in executing a LuaWML script outside Wesnoth, since there would be nothing for it to interact with.

So, I'm still not sure why you would execute scripts outside Wesnoth. However, what makes sense to me is not to execute them but just to compile them. That way, you can detect beforehand if there are syntax errors. In practice, you just try to execute the scripts, and if the error you get is "attempt to index global 'wesnoth' (a nil value)", then it means your script doesn't contain any syntax error (since lua tried to executed it).

By the way, when I write LuaWML scripts, I always have Wesnoth running. Contrarily to plain WML, you don't need to restart the game or even the scenario to test Lua scripts. For instance, let's assume you have written or modified a function "foo" in a file "bar.lua" and you want to know how the the function behaves. Then you can just type from inside the game:

Code: Select all

:lua wesnoth.dofile "bar.lua"
:lua foo(some, args)
Anonymissimus wrote:How much work would that be and what's the benefit ? Would the functions return initialized values then, but not calculate or do anything ?
The amount of work depends on the realism you expect from the functions. For instance, writing trivial functions that don't do anything is a few minutes job. For instance,

Code: Select all

wesnoth = {}
function wesnoth.register_wml_action(name, fun) print("Registering function for action " .. name) end
function wesnoth.fire(name, cfg) print("Executing WML action " .. name) end
-- and so on
But it can also be a huge work if you want to simulate the whole engine.
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: some first steps in lua, questions and discussion

Post by Anonymissimus »

I've just installed lua mode for emacs and a lua interpreter and I'm not yet sure about where the difference is at this thing between compiling and execution - other than e.g. VS C++.

But this
silene wrote:Contrarily to plain WML, you don't need to restart the game or even the scenario to test Lua scripts. For instance, let's assume you have written or modified a function "foo" in a file "bar.lua" and you want to know how the the function behaves. Then you can just type from inside the game:

Code: Select all

:lua wesnoth.dofile "bar.lua"
:lua foo(some, args)
is probably even better than the benefit which I was exspecting from the dummy table+compiling lua with an external interpreter.
The rest of your post makes somehow sense to me, 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: some first steps in lua, questions and discussion

Post by silene »

Anonymissimus wrote:I've just installed lua mode for emacs and a lua interpreter and I'm not yet sure about where the difference is at this thing between compiling and execution - other than e.g. VS C++.
It isn't needed for using Lua, but I will try to clarify a few details.

Lua is not really an interpreted language. When you try to execute a Lua script, it is first compiled to a binary program containing elementary instructions. This first phase will fail if there are syntax errors in the script. This binary program is then executed by the Lua virtual machine. This second phase will fail if there are logic errors in the script.

The important point is that the compilation phase does not depend on the environment that will later run the script: there is only one Lua language. In particular, whether the global variable "wesnoth" contains a table does not matter at compile time. So you don't have to use Wesnoth to check that your file doesn't contain any syntax error, you can directly use Emacs.

I'm not a user of Emacs and I have never seen what the lua mode is like. But if it does behaves like other Emacs modes and if everything is properly installed, you should get a "lua" entry in your menubar when you load a lua file. Then you can select "send buffer" in this menu and your file will be sent to the Lua interpreter. For instance, you can try typing "print(2 + 2)" and hopefully a new buffer should open with the answer "4".

Obviously, you will get execution errors if you send a LuaWML script to the interpreter, since the "wesnoth" table doesn't exist in its environment. But if the interpreter actually complains about your trying to access wesnoth as nil, it means that the compilation was successful since it is trying to execute the script. Therefore the script didn't contain syntax error (e.g. parentheses and brackets are properly balanced, operators are properly used, and so on). So, before saving your file and trying to load it in Wesnoth, just try to send it to the interpreter from Emacs and it will detect a first batch of errors.
User avatar
melinath
Posts: 1298
Joined: May 20th, 2009, 7:42 am

Re: some first steps in lua, questions and discussion

Post by melinath »

Could someone clarify exactly how to reference files with wesnoth.dofile and wesnoth.require? The wiki says that they "Load the given filename (relative to the content directory)", but what exactly does that mean? What's the content directory?

It seems like the content directory would be equivalent to the ~ (or lack thereof) in preprocessor includes. This makes sense compared to silene's suggestion on how to include files. However, when I tried to follow silene's instructions to use an external lua file, it didn't work.
silene wrote:

Code: Select all

[event]
    name=preload
    first_time_only=no
    [lua]
        code = "wesnoth.dofile 'Testcampaign/utils/lua/functions.lua'"
    [/lua]
[/event]
Here's my code:

Code: Select all

	[event]
		name=preload
		first_time_only=no
		[lua]
			code = "wesnoth.dofile 'Brent/utils/brent_utils.lua'"
		[/lua]
	[/event]
Here's the error message:

Code: Select all

20091228 18:49:15 error scripting/lua: [string "wesnoth.dofile 'Brent/utils/brent_utils.lua..."]:1: bad argument #1 to 'dofile' (file not found)
stack traceback:
	[C]: in function 'dofile'
	[string "wesnoth.dofile 'Brent/utils/brent_utils.lua..."]:1: in main chunk
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: some first steps in lua, questions and discussion

Post by Anonymissimus »

melinath wrote:Could someone clarify exactly how to reference files with wesnoth.dofile and wesnoth.require? The wiki says that they "Load the given filename (relative to the content directory)", but what exactly does that mean? What's the content directory?
bad argument #1 to me, "content directory" is meaningless! :lol2:

Try about this, that works for me:

Code: Select all

code= <<
--...
	functions = wesnoth.require "~add-ons/Testcampaign/utils/lua/functions.lua"
--...
>>
In file functions.lua needs to be a
return functions
at the end to make it work that way.
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
User avatar
melinath
Posts: 1298
Joined: May 20th, 2009, 7:42 am

Re: some first steps in lua, questions and discussion

Post by melinath »

Oh, so it just follows the same rules as the WML directory tools... thanks!

I'm experimenting with putting the lua file in _main.cfg, since that's how LOW does it. Seems more efficient.
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Re: some first steps in lua, questions and discussion

Post by silene »

melinath wrote:Oh, so it just follows the same rules as the WML directory tools... thanks!
Almost. The main difference is that you are not allowed to use relative locations "./something" since WML doesn't know about directories (only the preprocessor does).
melinath wrote:I'm experimenting with putting the lua file in _main.cfg, since that's how LOW does it. Seems more efficient.
It's equivalent to having a preload event. If you indeed use the same Lua code for all your scenarios (e.g. definition of new tags), the _main.cfg file (or any equivalent file) is indeed the best place to put a Lua script loader.
Anonymissimus wrote:

Code: Select all

code= <<
--...
	functions = wesnoth.require "~add-ons/Testcampaign/utils/lua/functions.lua"
--...
>>
In file functions.lua needs to be a
return functions
at the end to make it work that way.
From the point of view of locating files, "dofile" and "require" behave the same way; this path would have worked for both. Both of them also return the result of the script (that is, if last line of the script is "return something"). The main difference is that, "require" puts the result of the script in a cache and returns it for subsequent calls to the same script. (By the way, that means you can't use "require" to force Wesnoth to reload a file with ":lua".)

So, if your script is mainly registering WML actions and defining global functions, "dofile" is the way to go.

But, if your script is in fact a library, then "require" should be used. We could imagine that, at a point, someone ships a LuaTricks add-on that is meant to be used by several other add-ons. For instance, this is already the case with the "lua/helper.lua" script from mainline: it is used by several independent places so it would be hard to choose a single place where to put "dofile". For the same reason, "require" is also useful for an era with [unit_type] events, since you don't have control over a "preload" event. Each event will use "require" to load the needed functions, but the actual load will happen only once.

By the way, the structure of a file to be loaded by "require" is:

Code: Select all

local library = {} -- the actual name doesn't matter since it is local to the file
function library.do_something(a) ... end
function library.go_somewhere(x, y) ... end
return library
I will try to explain these points a bit better in the wiki.
User avatar
melinath
Posts: 1298
Joined: May 20th, 2009, 7:42 am

Re: some first steps in lua, questions and discussion

Post by melinath »

It might be useful to also include something on how to access the information in raw WML dumps like stored_unit.__cfg.

Comparison of a save file to a partial dump of a unit cfg (see script below) has shown that __cfg has a structure as follows:

Code: Select all

cfg = the [unit] tag. This is a table.
cfg[1] = the first child tag of the [unit] tag: say, the [portrait] tag. This is also a table. Let's call it v.
    v[1] = the first child tag's tag name. String. Say, "advancement".
    v[2] = the first child tag's contents. We'll call it q.
        q[1] = a table. There are as many qs as there are WML containers inside the tag that v represents. I suspect that if we call this table r, we would find that:
            r[1] = the first child container's name. Say, "effect"
            r[2] = the first child containter's contents.
etc.
This setup fits somewhat with how WML is supposed to be stored by Lua. But I can't seem to access actual values...


I haven't figured out yet how to access things like unit.id from the __cfg...
Script!:
P.S. Even after I get this reading thing done, I'd like to polish this script to be more useful, so if anyone has suggestions/corrections/tricks, it'd be great!

EDIT:: Found a better script on the internet using for...in, which I hadn't found yet. :P If anyone's interested, here's the modified version I'm using now:
Spoiler:
Still working on how this will help me actually access things...

EDIT EDIT::
Um. Okay, feel silly now. Just had to do team.__cfg.shroud_data to get the shroud data. Which now seems really obvious.
Last edited by melinath on December 29th, 2009, 10:17 am, edited 2 times in total.
Post Reply