enclave's Lua thread
Moderator: Forum Moderators
Re: enclave's Lua thread
I think it is still wrong, the original code did not contain a bracket too much, instead there was bracket missing.Elvish_Hunter wrote:In that case, I accidentally added one more bracket after the "show_if". That's the downside of handling WML tables directly: it's quite easy to do add, miss or misplace some brackets - even more when one isn't using an exitor with syntax highlighting (I typed it directly in the forum's editor...).
Anyway, I edited my code to remove the issue.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
Re: enclave's Lua thread
wow, thats a lot of text there Thank you! Very informative
I used lua because I was expecting to need synchronized.choice... so I thought that if i'm going to need it then I won't have to convert my code into anything and do double work glad to find that it didnt need synchronised choice.. happy happy
I dont really understand tables at the moment I guess, I will better use T. for some time
I'd like to learn lua for 3 reasons at the moment:
Back to my questions,
I have only 1 left at the moment.. If i had to enable right click option when not my turn, where do I start?
EoHS shows popup when moving mouse from one unit to another.. works when not player's turn.
Any ideas what lua code would look like if it had to be "on_mouse_move"... function() ... sort of thing.. any ideas?
EoHS is very hard to read for me.. I will be searching the right code there for another year probably
I used lua because I was expecting to need synchronized.choice... so I thought that if i'm going to need it then I won't have to convert my code into anything and do double work glad to find that it didnt need synchronised choice.. happy happy
I dont really understand tables at the moment I guess, I will better use T. for some time
I'd like to learn lua for 3 reasons at the moment:
Spoiler:
I have only 1 left at the moment.. If i had to enable right click option when not my turn, where do I start?
EoHS shows popup when moving mouse from one unit to another.. works when not player's turn.
Any ideas what lua code would look like if it had to be "on_mouse_move"... function() ... sort of thing.. any ideas?
EoHS is very hard to read for me.. I will be searching the right code there for another year probably
- Elvish_Hunter
- Posts: 1575
- Joined: September 4th, 2009, 2:39 pm
- Location: Lintanir Forest...
Re: enclave's Lua thread
Tested and fixed:gfgtdf wrote:I think it is still wrong, the original code did not contain a bracket too much, instead there was bracket missing.
Code: Select all
wesnoth.wml_actions.message {
image="units/human-loyalists/peasant.png",
speaker="narrator",
side_for="1",
caption="not a caption",
message="not a message at all",
{ "show_if",
{
{
"have_unit",
{
id="Elyssa"
}
}
}
}
}
That's not completely correct: WML has two preprocessor directives, calledenclave wrote:lua was the only way to find out what version of wesnoth every player has, there is no tag for synchronized choice, or wesnoth version in WML.
#ifver
and #ifnver
. By using them, you can implement code that is conditionally enabled depending on the player's Wesnoth version.Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
Re: enclave's Lua thread
The main benefits to use lua + wml rather than just wml in my opinion are these:
- lua has a proper grammar and a nice parser -- if you make a typo, it is more likely to be able to give you a useful explanation with pointers to line numbers than WML is. Full grammar is here: http://www.lua.org/manual/5.3/manual.html#9
- lua has a better type system than wml. You can assign tables in lua to their children just like they were strings or numbers. Assigning entries to arrays in WML by contrast requires a totally different syntax that is very verbose and painful. You generally have to use the [set_variables] tag, and if you don't get the variable names exactly right, it won't necessarily flag an error, it might just ignore your tag and pretend nothing bad happened. You don't often need to do manipulate arrays or complex data structures in scenario or campaign code but if you have to do it a lot, your code might be more readable and maintainable in lua.
- lua has some features that wml lacks. In wml you cannot define functions. You can define custom events and fire them, but this is not a complete substitute. In lua functions are first class data types -- you can pass a function to another function as an argument, and call a function which is stored in a variable. Sometimes code is much simpler if you can manipulate functions this way. In WML you can define macros which take other macros as arguments, but this approach has many drawbacks. lua also makes a lot of use of this feature to make iterators, which make it simpler to manipulate a data structure. If you have such a usecase, I would suggest to use lua rather than WML.
- lua has access to features like "wesnoth.synchronize_choice". If you need to do certain things in mp, you need to use this, and you can't use just WML. This partly stems from lack of ability to write functions in wml -- synchronize_choice most naturally takes as an argument the function that is supposed to be run in a synchronized way. I don't think there's a good way that we could extend WML to allow you to use synchronize_choice without using lua.
- lua has access to features like theme_items. If you ever played Bob's Galactic Empires add-on -- the "custom" ui displays, for instance that show HQ stats and nicer displays for transporters, were written by me in lua. They allow you to do comptuations and fancy things to adjust UI displays, without requiring an event to be fired or to get synchronization. They also don't block you from undoing a move. There's no way to make stuff like that in WML. Also you can look at gfgtdf's Scenario with robots for more sophisticated uses of this.
- lua can be used to *define new WML tags*. Indeed, about half of all of the WML tags are actually implemented in lua, not directly in C++. If you have a scenario or campaign with special custom mechanics, a good way to organize it is to define new WML tags in lua that implement the mechanics you want. Then write your scenario in pure WML, plus the custom WML you made. You can look at After the Storm, or Shadows of Deception, for examples of this style. IMO it can make complicated things a lot more readable once you get used to it.
- Two languages = more stuff = more complicated.
- Confusion about state, what is persistent. Variables just sitting in the lua environment are not synchronized across the network, and are not saved to savegame files or replays. For state that should be persistent this way, you have to write to a WML variable. There is a wesnoth "vars metatable" that makes this very succinct, but the reasons that you have to use this are ... well its not that complicated, I mean I just explained it to you. But it's still adding some complexity.
Re: enclave's Lua thread
to Elvish_Hunter:
didnt know about #ifver stupid me.. but well.. my code in lua looked like:
I was looking for right-click menu when not player's turn and came across lua help on compare versions.. so I thought "here it is! just what I also need!" and never read about #ifver I guess my approach is not the right one, - not reading full texts, but only what I'm looking for in particular cases.. And the result - missed #ifver... Anyway I'm happy with my lua results
To iceiceice:
wow, didnt know lua variables are not transferable in network thanks a lot.. you gave me some ideas on my right-click menu!
didnt know about #ifver stupid me.. but well.. my code in lua looked like:
Spoiler:
To iceiceice:
wow, didnt know lua variables are not transferable in network thanks a lot.. you gave me some ideas on my right-click menu!
Re: enclave's Lua thread
very nice idea in that era.. nice graphics.. strange nobody playing it..iceiceice wrote: If you ever played Bob's Galactic Empires add-on -- the "custom" ui displays, for instance that show HQ stats and nicer displays for transporters, were written by me in lua.
Re: enclave's Lua thread
This is actually giving OOSes wihout syncronized choice.. I dont think that reason of OOS is anything else.
I dont see problems to remake the code above into synchronized choice, BUT i see big problems and I hardly know where to start with the code below:
I guess i have to shorten it all into just 1 value.. I knew I would have to remake it all into sync choice!
Code: Select all
wesnoth.wml_actions.message {
image="portraits/humans/transparent/peasant.png",
speaker="narrator",
side_for="1",
caption="Choose Game Settings",
message="Would you like comparison of players progress to be OFF or ON?",
T.option {
message = "ON",
T.command {
T.set_variable { name = "input1", value="ON" }
}
},
T.option {
message = "OFF",
T.command {
T.set_variable { name = "input1", value="OFF" }
}
}
}
local lua_starting_top9=wesnoth.get_variable("input1")
wesnoth.set_variable("showtop9",wesnoth.get_variable("input1"))
Code: Select all
wesnoth.wml_actions.message {
image="portraits/humans/transparent/peasant.png",
speaker="narrator",
side_for="1",
caption="Choose Game Settings",
message="How much resources would you like each player to start with?",
T.option {
message = "15 (Recommended)",
T.command {
T.set_variable { name = "input1", value="15" },
T.set_variable { name = "input2", value="15" },
T.set_variable { name = "input3", value="15" },
T.set_variable { name = "input4", value="15" },
T.set_variable { name = "input5", value="false" }
}
},
T.option {
message = "45",
T.command {
T.set_variable { name = "input1", value="45" },
T.set_variable { name = "input2", value="45" },
T.set_variable { name = "input3", value="45" },
T.set_variable { name = "input4", value="45" },
T.set_variable { name = "input5", value="false" }
}
},
T.option {
message = "90",
T.command {
T.set_variable { name = "input1", value="90" },
T.set_variable { name = "input2", value="90" },
T.set_variable { name = "input3", value="90" },
T.set_variable { name = "input4", value="90" },
T.set_variable { name = "input5", value="false" }
}
},
T.option {
message = "TEST MODE (Not Recommended)",
T.command {
T.set_variable { name = "input5", value="true" }
}
}
}
local lua_starting_resources=wesnoth.get_variable("input1")
wesnoth.set_variable("starting_food",wesnoth.get_variable("input1"))
wesnoth.set_variable("starting_wood",wesnoth.get_variable("input2"))
wesnoth.set_variable("starting_stone",wesnoth.get_variable("input3"))
wesnoth.set_variable("starting_gold",wesnoth.get_variable("input4"))
wesnoth.set_variable("testing_mode",wesnoth.get_variable("input5"))
Re: enclave's Lua thread
changed into synchronized choice, still causing OOS on start..
can this cause OOS?
or its somewhere there:
Please Help
can this cause OOS?
Code: Select all
wesnoth.wml_actions.print {
text="Starting resources: " .. tostring(lua_starting_resources) .. "\n" .. "First turn Help: " .. tostring(lua_starting_help) ..
"\n" .. "Player Comparison: " .. tostring(lua_starting_top9),
size="40",
duration="250",
red="0",
green="100",
blue="255"
}
Code: Select all
local result = wesnoth.synchronize_choice(
function()
wesnoth.wml_actions.message {
image="portraits/humans/transparent/peasant.png",
speaker="narrator",
side_for="1",
caption="Choose Game Settings",
message="How much resources would you like each player to start with?",
T.option {
message = "15 (Recommended)",
T.command {
T.set_variable { name = "input1", value="15" },
}
},
T.option {
message = "45",
T.command {
T.set_variable { name = "input1", value="45" },
}
},
T.option {
message = "90",
T.command {
T.set_variable { name = "input1", value="90" },
}
},
T.option {
message = "TEST MODE (Not Recommended)",
T.command {
T.set_variable { name = "input1", value="test" }
}
}
}
return { value = wesnoth.get_variable("input1") }
end,
function()
return { value = "15" }
end)
local lua_starting_resources=result.value
if not (lua_starting_resources=="test") then
wesnoth.set_variable("starting_food",result.value)
wesnoth.set_variable("starting_wood",result.value)
wesnoth.set_variable("starting_stone",result.value)
wesnoth.set_variable("starting_gold",result.value)
else
wesnoth.set_variable("testing_mode","true")
end
Re: enclave's Lua thread
Simple way to check is to use :inspect dialog on both clients. If your wml variables aren't matching then you definitely got OOS.
I don't think print can cause an OOS, can't say for sure with the other one because it depends when it is fired. You are better off to post the whole scenario than code snippets.
I don't think print can cause an OOS, can't say for sure with the other one because it depends when it is fired. You are better off to post the whole scenario than code snippets.
Re: enclave's Lua thread
print on its own didnt cause oos.. so it all is down into message options..
The full code is here:
below is event..
Only LUA_PRELOAD_OPTIONS1 is causing oos.. removing some parts of it making things back to normal..
with only this
every player will report out of sync as soon as game begins (same without sync choice)
Otherwise in local game with only my computer (local player) no problems whatsoever..
Or maybe I need to move message options to more later event? (I mean message options not allowed for start/prestart/preload.. maybe turn 1 also not good?)
The full code is here:
Spoiler:
Spoiler:
with only this
Spoiler:
Otherwise in local game with only my computer (local player) no problems whatsoever..
Or maybe I need to move message options to more later event? (I mean message options not allowed for start/prestart/preload.. maybe turn 1 also not good?)
Re: enclave's Lua thread
So I would suggest you to try it at turn 2 and see if it is still OOS.
I don't remember exactly how stuff worked in 1.10, but I thought that in 1.10 both start and prestart are not really safe, so most add-ons would delay such menus until the time that P1 moves their first unit. I think that "start" is actually the same as "turn 1".
In 1.12 I think that this should work fine. I don't see anything wrong with your lua.
I don't remember exactly how stuff worked in 1.10, but I thought that in 1.10 both start and prestart are not really safe, so most add-ons would delay such menus until the time that P1 moves their first unit. I think that "start" is actually the same as "turn 1".
In 1.12 I think that this should work fine. I don't see anything wrong with your lua.
- Elvish_Hunter
- Posts: 1575
- Joined: September 4th, 2009, 2:39 pm
- Location: Lintanir Forest...
Re: enclave's Lua thread
This is unrelated to your problem, but I noticed these lines in your code:
I assume that what you're attempting here is to set a boolean variable and check its value, right? In this case, there are a few useful tips to know:
Code: Select all
wesnoth.set_variable("testing_mode","true")
end
------------------------------
if not (tostring(wesnoth.get_variable("testing_mode")) == "true") then
- When setting a boolean variable, Lua has two special values available: true and false (nil also counts as false, everything else in Lua counts as true). Both of them must be used without quotes, otherwise "false" between quotes counts as a string value and is cast as true:
Code: Select all
Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio > if "false" then print("Value is true") end Value is true > if false then print("Value is true") end >
- In WML, both "yes" and "true" count as true boolean values, and both "no" and "false" count as false boolean values. WML and Lua automatically take care of the appropriate castings. This code:
gives this output:
Code: Select all
[set_variable] name=test_0 value=true [/set_variable] [set_variable] name=test_1 value=yes [/set_variable] [set_variable] name=test_2 value=false [/set_variable] [set_variable] name=test_3 value=no [/set_variable] [lua] code=<< local print = std_print if wesnoth.get_variable("test_0") then print("Variable test_0 is true") end if wesnoth.get_variable("test_1") then print("Variable test_1 is true") end if not wesnoth.get_variable("test_2") then print("Variable test_2 is false") end if not wesnoth.get_variable("test_3") then print("Variable test_3 is false") end >> [/lua]
Don't mind the fact that I'm using aCode: Select all
Variable test_0 is true Variable test_1 is true Variable test_2 is false Variable test_3 is false
std_print
command, as it is a 1.13 function. Up to 1.12, the normalprint
is used. - You can directly test variables for truth without first converting them as strings:As expected, the output is
Code: Select all
wesnoth.set_variable("test_6",false) if not wesnoth.get_variable("test_6") then print(tostring(wesnoth.get_variable("test_6"))) end
false
. If test_6 was true, print() would have been skipped. - Given these facts, your code can be improved in this way:
Code: Select all
wesnoth.set_variable("testing_mode",true) end ------------------------------ if not wesnoth.get_variable("testing_mode") then
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
Re: enclave's Lua thread
thx iceiceice, I will try turn 2, will be easy change of code..
thx Elvish_Hunter, i didnt know that string "false" equals to boolean true..
I was always trying to avoid "true" "false" without quotes to make sure that they are treated like strings..
I dont like the fact that true is same as yes and false is same as no.. because I was never sure if my code failed to work because machine expects "Yes" and my code expects "yes" or that machine expects "True" and my code expects "true" or my code expects "True" and machine converts my "True" into "yes" so my code doesnt work... How WML and Lua treating the code was always very confusing so I used quotes wherever I could.. now will just replace with "ON" "OFF"... will 100% remove all possible confusion...... I guess.. thx for a hint very much couldnt even nearly imagine that "false" could give true.. a lot easier to just get rid of booleans..
thx Elvish_Hunter, i didnt know that string "false" equals to boolean true..
I was always trying to avoid "true" "false" without quotes to make sure that they are treated like strings..
I dont like the fact that true is same as yes and false is same as no.. because I was never sure if my code failed to work because machine expects "Yes" and my code expects "yes" or that machine expects "True" and my code expects "true" or my code expects "True" and machine converts my "True" into "yes" so my code doesnt work... How WML and Lua treating the code was always very confusing so I used quotes wherever I could.. now will just replace with "ON" "OFF"... will 100% remove all possible confusion...... I guess.. thx for a hint very much couldnt even nearly imagine that "false" could give true.. a lot easier to just get rid of booleans..
Re: enclave's Lua thread
Yes, WML and lua have different philosophies about some things. For instance, lua numbers arrays starting from one, because they think its easier for non-programmers. WML does almost everything to be as easy for nonprogrammers as possible, but did not do that one :p
WML isn't really focused on types. When we need to think of a value as a boolean, the strings "true" and "false" and "yes" and "no" will become boolean values. Other values... will get some default value which may depend on the exact context. It doesn't really make sense to say that a variable in wml is "boolean type" as opposed to a string -- its going to get written to the save file ultimately as "true" or "false" string most likely, or "yes" or "no" if you input it that way.
In lua, every expression has a precise type, which is from the list nil, boolean, number, string, userdata, function, thread, and table. You can query e.g. the type of "X" by calling the built-in function that tells you the type: "type(X)" (if I recall correctly).
Even though lua has a proper boolean type, for convenience most boolean operations also work with non-boolean objects and they won't call it an error. When interpretting objects as booleans, they take the convention that the false boolean type, and nil, are interpretted false, and everything else is true. So this one rule explains how lua "if" and also "or", "and", will behave. This idea is unique to lua, so you might have to get used to it. There are several idioms in lua that use this behavior to write certain things succinctly. http://lua-users.org/wiki/LuaStyleGuide
WML isn't really focused on types. When we need to think of a value as a boolean, the strings "true" and "false" and "yes" and "no" will become boolean values. Other values... will get some default value which may depend on the exact context. It doesn't really make sense to say that a variable in wml is "boolean type" as opposed to a string -- its going to get written to the save file ultimately as "true" or "false" string most likely, or "yes" or "no" if you input it that way.
In lua, every expression has a precise type, which is from the list nil, boolean, number, string, userdata, function, thread, and table. You can query e.g. the type of "X" by calling the built-in function that tells you the type: "type(X)" (if I recall correctly).
Even though lua has a proper boolean type, for convenience most boolean operations also work with non-boolean objects and they won't call it an error. When interpretting objects as booleans, they take the convention that the false boolean type, and nil, are interpretted false, and everything else is true. So this one rule explains how lua "if" and also "or", "and", will behave. This idea is unique to lua, so you might have to get used to it. There are several idioms in lua that use this behavior to write certain things succinctly. http://lua-users.org/wiki/LuaStyleGuide
Re: enclave's Lua thread
thx iceiceice I always considered arrays starting with 0 pain in the a.. I dont remember a single case when array[0] would be more useful than array[1], rather was always problematic and required some extra code to make it work the way you want.. adding to the code i-1 , i+1 etc.. wml is very nice regarding that you dont need to declare variables, array lengths and a lot of other things are really making life a lot easier. but I guess the largest tradeoff is speed of how fast it all works.. making optimisations harder.. but i never felt any differences yet in real wesnoth world everything is normaly working real quick.