ResExsention's questions on the art of "Lua-ing"
Moderator: Forum Moderators
- ResExsention
- Posts: 97
- Joined: March 17th, 2018, 12:00 am
- Location: Alberta, Canada
ResExsention's questions on the art of "Lua-ing"
Hi!
Lua is a very interesting and powerful language; ever since starting with wesnoth UMC development, it has always intrigued me, and I've always wanted to participate in the discussion on the Lua Labs forum... And I don't believe it; I'm here!
So I went into the LuaWML page, learned some basic syntax, noted a few important functions and keywords, and now feel prepared to join the Lua Labs forum. I am familiar with C++ and Python, so I soon got a hang of the syntax, but what different keywords and functions did still eluded me; and too bad that there's no ReferenceLUA page, so I got stuck. That's why this topic is here. So that I can ask questions related to Lua so that myself and others can learn more. So here we go.
Lua is a very interesting and powerful language; ever since starting with wesnoth UMC development, it has always intrigued me, and I've always wanted to participate in the discussion on the Lua Labs forum... And I don't believe it; I'm here!
So I went into the LuaWML page, learned some basic syntax, noted a few important functions and keywords, and now feel prepared to join the Lua Labs forum. I am familiar with C++ and Python, so I soon got a hang of the syntax, but what different keywords and functions did still eluded me; and too bad that there's no ReferenceLUA page, so I got stuck. That's why this topic is here. So that I can ask questions related to Lua so that myself and others can learn more. So here we go.
I am a ranger and my WML knives will implant themselves in your back.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Re: ResExsention's questions on the art of "Lua-ing"
lua is not a wesnoth specific langauge, so ther is little point in adding wesnothwiki page that explains the lua language itself when there are other pages that do that already, for example on www.lua.org
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.
- ResExsention
- Posts: 97
- Joined: March 17th, 2018, 12:00 am
- Location: Alberta, Canada
Re: ResExsention's questions on the art of "Lua-ing"
So my first question pertaining to Lua relates to setting up a Lua AI which is basically the standard RCA AI but with this added in somewhere:
1 - Evaluate and move units to potential targets.
2 - Evaluate if any enemy units are in range.
3 - If so, make units form a defensive line, facing the enemy units. Make them advance forward one hex at a time cohesively, meaning if one unit encounters an enemy unit, stop the entire line until that enemy unit is killed. Adjacent units to the one being attacked by the enemy can also break out of line and attack the assailing enemy unit.
4 - If more enemies encounter the line, repeat the step 3 response to assailing units; fight back, adjacent units to the one being attacked break line and help out.
5 - Replace any holes in the line with any reserve units. If there are no reserve units, shorten the line so the gap is filled.
6 - Once there are no longer any enemies in range, or if there were never any enemy units, break line and start moving units toward target normally.
7 - Evaluate if there are any enemy units with in a ten hex radius from the side's leader.
8 - If not, send reinforcements to all advancing lines.
9 - If there are enemies, don't send reinforcements this turn and use those troops to destroy destroy destroy the intruders!
For evaluating the enemies' range from the advancing force, I was thinking of using the
If anyone could provide an entire lua AI script for this and walk me through it, that would be nice, and would be my most preferable answer, but just defining the right functions and their syntaxes is acceptable too.
Thank you all.
EDIT: Yes. I am informed that Lua is not Wesnoth only. Though the lua.org website doesn't seem to show Wesnoth-specific functions and such. Is there like a Lua library that's loaded that contains the stuff for Wesnoth? That's what I meant this topic to be about.
1 - Evaluate and move units to potential targets.
2 - Evaluate if any enemy units are in range.
3 - If so, make units form a defensive line, facing the enemy units. Make them advance forward one hex at a time cohesively, meaning if one unit encounters an enemy unit, stop the entire line until that enemy unit is killed. Adjacent units to the one being attacked by the enemy can also break out of line and attack the assailing enemy unit.
4 - If more enemies encounter the line, repeat the step 3 response to assailing units; fight back, adjacent units to the one being attacked break line and help out.
5 - Replace any holes in the line with any reserve units. If there are no reserve units, shorten the line so the gap is filled.
6 - Once there are no longer any enemies in range, or if there were never any enemy units, break line and start moving units toward target normally.
7 - Evaluate if there are any enemy units with in a ten hex radius from the side's leader.
8 - If not, send reinforcements to all advancing lines.
9 - If there are enemies, don't send reinforcements this turn and use those troops to destroy destroy destroy the intruders!
For evaluating the enemies' range from the advancing force, I was thinking of using the
ai.get_enemy_dst_src()
function, because to me it looked like ai.get_enemy_distance_from_a_certain_filter()
, but there was no documentation for it. And for the evaluation of whether there's an enemy near this side's leader, I was thinking using a conditional, but then, I would still need to evaluate ranges from the AI's leader to an enemy. Any ideas? And for filling in holes in a line, keeping the line in place, and making units fight back against enemies and also have adjacent units break line, well... Let's just say I have no idea how to do that. If anyone could provide an entire lua AI script for this and walk me through it, that would be nice, and would be my most preferable answer, but just defining the right functions and their syntaxes is acceptable too.
Thank you all.
EDIT: Yes. I am informed that Lua is not Wesnoth only. Though the lua.org website doesn't seem to show Wesnoth-specific functions and such. Is there like a Lua library that's loaded that contains the stuff for Wesnoth? That's what I meant this topic to be about.
I am a ranger and my WML knives will implant themselves in your back.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Re: ResExsention's questions on the art of "Lua-ing"
well, the luawml page lists all wesnoth functions except the ai functions afaik. I don't know whether there is a documentation reference for lua ai scripting, mattsc or celmin might know.
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.
- ResExsention
- Posts: 97
- Joined: March 17th, 2018, 12:00 am
- Location: Alberta, Canada
Re: ResExsention's questions on the art of "Lua-ing"
Yeah, that is kind of sad... I mean, there is a LuaAI page, but it doesn't define functions and stuff very well, and there also is a Creating a custom AI with Lua page, which was more helpful, but still didn't give me the functions and stuff I was looking for. So I haven't gone anywhere with that AI I'm trying to make.
I am a ranger and my WML knives will implant themselves in your back.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Re: ResExsention's questions on the art of "Lua-ing"
Hi ResExsention,
It's always good to have somebody else try to get their feet wet in the Wesnoth AI waters. However, what you are asking for there is a huge amount of rather complex work (we're probably talking hundreds of lines of code just for a first basic version). In particular something like "form a defensive line" is very difficult to do well for a computer. I think your chances of finding somebody to provide you with a complete Lua script, or even functions to do most of your numbered tasks, are very low.
Now, having said that, people here are generally very happy to help, but you need to come up with more specific questions. Your paragraph underneath the task list is a start in that direction, but the more specific the better. To get started, I'd say have a look at the mainline ai_helper.lua library. There's probably also some useful stuff in the lua directory of one of my add-ons, but quite honestly, that is currently such a mess that it is probably not worth your time trying to sift through. I might be able to point you to some functions on specific questions though.
Specifically on some of your questions, have a look at
Hope this helps to get started. AI is a pretty complex topic, it takes a while to get going on it, but hopefully that won't turn you away from it.
EDIT: I forgot, in that add-on I link to, there's a Lua AI Demo scenario that gives you a template for how to set up a functional (albeit not very useful) Lua AI.
It's always good to have somebody else try to get their feet wet in the Wesnoth AI waters. However, what you are asking for there is a huge amount of rather complex work (we're probably talking hundreds of lines of code just for a first basic version). In particular something like "form a defensive line" is very difficult to do well for a computer. I think your chances of finding somebody to provide you with a complete Lua script, or even functions to do most of your numbered tasks, are very low.
Now, having said that, people here are generally very happy to help, but you need to come up with more specific questions. Your paragraph underneath the task list is a start in that direction, but the more specific the better. To get started, I'd say have a look at the mainline ai_helper.lua library. There's probably also some useful stuff in the lua directory of one of my add-ons, but quite honestly, that is currently such a mess that it is probably not worth your time trying to sift through. I might be able to point you to some functions on specific questions though.
Specifically on some of your questions, have a look at
ai_helper.get_attackable_enemies()
, ai_helper.get_closest_enemy()
, ai_helper.can_reach()
or ai_helper.get_attacks()
. Those will not do exactly what you want done in the end, but you might be able to use them to accomplish some of your goals, and their code will tell you how (some of) this can be done.Hope this helps to get started. AI is a pretty complex topic, it takes a while to get going on it, but hopefully that won't turn you away from it.
EDIT: I forgot, in that add-on I link to, there's a Lua AI Demo scenario that gives you a template for how to set up a functional (albeit not very useful) Lua AI.
SP campaigns: Galuldur's First Journey (1.12 & 1.14) & Grnk the Mighty (1.10 & 1.12)
AI experiments: Micro AIs (wiki, forum thread, known/fixed bugs), Fred, AI-demos add-on
AI experiments: Micro AIs (wiki, forum thread, known/fixed bugs), Fred, AI-demos add-on
- Celtic_Minstrel
- Developer
- Posts: 2209
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: ResExsention's questions on the art of "Lua-ing"
The LuaAI page is the official reference for the AI-specific Lua functions in the engine. It could use some improvement, sure, but I think it's basically complete. The only thing really missing is any explanation of how to use those move map functions, but normally they'll be replaced with different, simpler functions to do the same thing, so what we really need to do is document those instead. It doesn't list every possible aspect only because those are listed separately in AiWML.
- ResExsention
- Posts: 97
- Joined: March 17th, 2018, 12:00 am
- Location: Alberta, Canada
Re: ResExsention's questions on the art of "Lua-ing"
Huh. Well, mattsc, thanks for pointing me in a direction that might help me out in my quest to make a complex AI, so thanks. I'll take a look at that file. Celtic_Minstrel, thanks for also pointing me also in another relatively correct direction. I'll certainly take a look at that, too.
EDIT: Well, mattsc, I checked out the ai helper file, and found that
The code looks right to me. Is this code correct? And if anybody has the code for grouping units tightly together, that would be nice to provide as well.... I was thinking of making the AI move the units in that force that's getting attacked towards a single nearby hex, but I can't really figure out how to filter out the specific units in that force. Maybe creating an array/table that holds the units in each individual force, and then making all those units in the table/array go to one nearby hex when they get attacked?
EDIT: Well, mattsc, I checked out the ai helper file, and found that
ai_helper.get_attackable_enemies()
worked nicely, but I was wondering what kind of data it returned. An array/table? So I went like this:Code: Select all
-- The Lance Defensive AI
-- Lances the units forward when there are no enemies in range, and then when the enemies come at the force, the ai groups them together defensively,
local ai_helper = wesnoth.require "ai/lua/ai_helper.lua"
local function get_unit(cfg)
local filter = cfg.filter or {id = cfg.id}
local unit = ai_helper.get_units_with_moves {
side=wesnoth.current.side, {"and", filter}
} [1]
return unit
end
local ca_return_unit = {}
function ca_return_unit:evaluation(ai, cfg)
local unit = get_unit(cfg)
if unit then
local attackable_enemies = ai_helper.get_attackable_enemies()
-- evaluate if there are any enemies
if attackable_enemies then
return 99900
else
return 100010
end
end
return 0
end
function ca_return_unit:execution(ai, cfg)
local unit = get_unit(cfg)
-- Uhhhhh. How do you make a line, or at least make the people group together defensively?
end
I am a ranger and my WML knives will implant themselves in your back.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Re: ResExsention's questions on the art of "Lua-ing"
Well ...
Whenever somebody writes something like that, I always think to myself: Why don't you try if it works? And I mean this completely non-cynical or anything. What you are trying to do here will require a lot of trial-and-error, and nobody will, in the end, be able to tell simply from looking at your code whether it does what you want. So you need to develop some way of testing and trouble-shooting your code piece by piece as you write it. Sorry for the "lecture", I am honestly just trying to be helpful, so here are some hopefully constructive pointers:ResExsention wrote:The code looks right to me. Is this code correct?
You don't actually need to have a working execution function to figure out whether the evaluation function works. Just put
print(99900)
or wesnoth.message(99900)
or whatever into the if/else blocks to see if they get triggered correctly. Or put a print message at the beginning of the execution function to see if it is called, or ...I very strongly suggest that you get the Wesnoth Lua Pack (WLP) from the add-ons server and use itsResExsention wrote:I was wondering what kind of data it returned. An array/table?
dbms
function whenever you need to know what a function returns. (Alternatively, you can get a slightly modified version from here -- I don't know if WLP is on the 1.14 add-ons server.) For what you want to do, I assume that this will be invaluable. I know that it is for me.Now, after all that, this is still simple enough that I can tell you that, no, it won't work like that. If you look here, you can see that the function returns an empty array when no enemies are found. So in that case, your conditional needs to look like this:
Code: Select all
if (#attackable_enemies > 0) then
attackable_enemies()
really returns what its name says, units that are attackable by what its arguments describe. In your code, there's no connection between unit
and the return value of the function. So it's either insufficient (if you want there to be a connection) or unnecessary (if you just want to know if there are enemies without "connection" to a specific AI unit.That's the part (one of them) that I meant when I said that it's not that simple to do well. I don't think there's any preexisting code, and it depends strongly on what you want. You'll likely have to work on this yourself and just try it out.ResExsention wrote:And if anybody has the code for grouping units tightly together, that would be nice to provide as well.... I was thinking of making the AI move the units in that force that's getting attacked towards a single nearby hex, but I can't really figure out how to filter out the specific units in that force. Maybe creating an array/table that holds the units in each individual force, and then making all those units in the table/array go to one nearby hex when they get attacked?
helper.adjacent_tiles()
might be useful function for this.SP campaigns: Galuldur's First Journey (1.12 & 1.14) & Grnk the Mighty (1.10 & 1.12)
AI experiments: Micro AIs (wiki, forum thread, known/fixed bugs), Fred, AI-demos add-on
AI experiments: Micro AIs (wiki, forum thread, known/fixed bugs), Fred, AI-demos add-on
- ResExsention
- Posts: 97
- Joined: March 17th, 2018, 12:00 am
- Location: Alberta, Canada
Re: ResExsention's questions on the art of "Lua-ing"
Oh. So
get_attackable_enemies
returns an array. I could probably utilize that. And the conditional you basically means if there are no enemies, then... And what of helper.adjacent_tiles()
? Can I look at it under ai_helper.lua
? Thx. I'll be getting the wesnoth lua pack in a few minutes; thanks for that. And thanks for pointing me towards using wesnoth.message()
. I'll check it out.I am a ranger and my WML knives will implant themselves in your back.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
Creator of the abandoned campaign Royalties Forgotten and the work in progress campaign Purger of Evil.
Maintainer of Fate of a Princess.
- Celtic_Minstrel
- Developer
- Posts: 2209
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: ResExsention's questions on the art of "Lua-ing"
helper.adjacent_tiles()
is part of the "helper" module, so you need to wesnoth.require "helper"
.