Central Build AI as lua widget! - Page 2

Central Build AI as lua widget!

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua script?

Post by troycheek »

Well, I bypassed all the gl.whatever and Spring still crashes after a while. Where/how should I submit the infolog?

Edit: Commented out several sections and managed to narrow down the crash to the part of the code that assigns one builder to assist another. Possibly the problem lies with spGiveOrderToUnit(unitID, CMD_REPAIR, { busyX, busyY, busyZ }, { "" }) and I'm feeding it invalid map coordinates, or I'm assigning it to repair something that isn't there yet, etc. More testing on my next day off.
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Re: Central Build AI as lua widget!

Post by imbaczek »

best place would be manits (http://spring.clan-sy.com/mantis/), bonus points for providing a translated stacktrace.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Okay, I've stashed back a copy of the infolog.txt and a snapshot of the widget at the time of the crash and will attempt that translate thing again first chance I get.

Edit: Finally got a chance to report to Mantis.

I eventually decided the problem is that CMD.REPAIR expects either a unitID (1 parameter) or a map position plus a radius (x,y,z,r or 4 parameters). I'd misread the wiki and was only giving it a mappos (x,y,z or 3 parameters). Crazy thing is that it worked most of the time, only crashing occasionally. I'm pretty sure I've messed up parameters other times and gotten a simple Lua error message instead of a crash. Oh, well. It's in the hands of the developers now.

Edit: Now reported as resolved!
Last edited by troycheek on 16 Jul 2009, 08:51, edited 2 times in total.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

I've now managed to play three whole XTA games without my Central Build AI widget getting stuck or crashing. Now to download a few mods and see what happens.

For those playing at home, if issuing a CMD.REPAIR order to a unit, you should 1) make sure it has repair capability, 2) give it either a unit number OR a map position and a radius, and 3) check to see if there's something there to be repaired. I think it was #2 which was causing most of my crashes. I'd somehow gotten the idea that just the map position would work without a radius. Crazy thing is that it would work sometimes.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Things went a little quicker than I expected so here's my first more or less working attempt at a replacement for the old Central Build Group AI. I didn't hardcode any unit names so it should work with any mod/game that uses mobile builders (isBuilder and canMove). I've tested it quite a bit with XTA and a little with CA and BA.

Still to do (in no particular order):

1) Replace simple distance check between builder and build order with an actual path check. (Can anybody give me some hints about the Spring pathfinder? A simple "can't get there from here" function would be lovely.)

2) Add a way to specify a Central Build group other than 1 while within the game, rather than by changing a line in the lua file.

3) Add a way to specify multiple Central Build groups, each with their build queue.

4) Monitor Central Builder health and order idle Builders to repair damaged coworkers.

5) Come up with some way to recognize build orders intended for the Central Build queue without using the Wait command as a bookmark.

I'd really like to hear back from any more experienced coders who can point out the more obvious mistakes I've made, and also from anyone who remembers the Central Build Group AI general "look and feel" who can tell me how close I got to replicating it.

Edit: Changed the file description below. Realized that I'd labelled it v0.1 when I'd actually uploaded v0.3. No change in the file itself, so don't re-download if you already have it.

Edit again: Removed and replaced with a newer version. See first post for download.
Last edited by troycheek on 04 Jul 2009, 07:19, edited 3 times in total.
Super Mario
Posts: 823
Joined: 21 Oct 2008, 02:54

Re: Central Build AI as lua widget!

Post by Super Mario »

The AI works great with BA. Here are some of my requests.

I want to define an area for the builders to build in, so that it can automatically build a building without me putting the location of the building. It will helps me lots in BA intense micro battles. :)
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Central Build AI as lua widget!

Post by Niobium »

1) -
2) widget:TextCommand(command), this gets called when user types '/luaui <command>', this would be a nice way to change the group ingame (i.e. /luaui cbgroup 5), unless you want to make a button or some such (a lot of work for such a small thing)
3) Fairly easy isn't it? You would just need to loop for all groups marked as cb groups, running the same code you have now
4) widget:UnitDamaged(unitID, unitDefID, unitTeam, damage, paralyzer), then check what group the unit is in
5) widget:CommandNotify(cmdID, cmdParams, cmdOpts), follow with a getSelectedUnits call, loop through to see if any are central build and can execute order.

local bookmark = 99999 -- what is MAX_INT in Lua?
-- Use math.huge

I would also take a look at these callins:
widget:UnitIdle(unitID, unitDefID, teamID)
widget:UnitCmdDone(unitID, unitDefID, unitTeam, cmdID, cmdTag)
widget:UnitFinished(unitID, unitDefID, teamID)

(Look at http://springrts.com/wiki/LuaCallinReturn, and http://springrts.com/wiki/Lua_Scripting if you havn't)

Ideally you would have the entire widget 'event' based, i.e. no widget:Update() polling. I would also use internal groups, rather than springs groups, just make some simple things like meta+0-9 = adds to group (Label these units) and c+0-9 selects the group.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Super Mario wrote:I want to define an area for the builders to build in, so that it can automatically build a building without me putting the location of the building. It will helps me lots in BA intense micro battles. :)
You want to be able to say Here's my build area, now give me a T1 vehicle factory. That's heading away from Centralized Building and into the area of Automated Building. For the moment, I'm trying to mostly emulate the capabilities and behavior of the old Group AI. I'll put this down as a possibility in version 2.0. (Currently at version 0.3 and about to start again from scratch thanks to Niobium.)
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Niobium wrote:Ideally you would have the entire widget 'event' based, i.e. no widget:Update() polling.
Ideally, I'd understand Lua and the Spring API before I even started writing something this complex. It's been a learning experience all around.
Niobium wrote:I would also use internal groups, rather than springs groups, just make some simple things like meta+0-9 = adds to group (Label these units) and c+0-9 selects the group.
I used the existing Spring groups primarily because I assumed players were already familiar with them and I had noticed the GroupChanged() call-in in some other widget. I know the old Group AIs used group numbers 10 and up, but didn't know how to implement that. I'm not that familiar with the meta key concept, so I'll just have to download some widgets that use it. (This is my primary method of learning Lua.)

Thanks for the advice.
Last edited by troycheek on 03 Jul 2009, 02:50, edited 1 time in total.
Super Mario
Posts: 823
Joined: 21 Oct 2008, 02:54

Re: Central Build AI as lua widget!

Post by Super Mario »

I hope your learning experiences goes well.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Super Mario wrote:I hope your learning experiences goes well.
If nothing else, I've had some fun and have given the AI coders and Spring developers an idea or two.

I'm about halfway through v0.4 now. Using some of the information from Niobium, I've made it a lot more event-driven. It's a lot snapper and responsive now. Idle builders are now recognized and re-assigned almost immediately. I may go back in and add some kind of delay. There were fewer traffic jams when the builders were dispatched a second or so apart.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Central Build AI v0.5 is now available for download. See first post for the link.

What's new:
1) Almost everything is rewritten and most actions are event-driven (thanks to suggestions by Niobium). No more Wait commands. Much more responsive.
2) Added code to remove widget in Spectator mode. Not sure it would cause a problem in Spectator mode, but I had the code.
3) Idle units now Guard active units just like in the original, whereas before I was faking it by sending Repair orders.
4) Removed the console spam.

I think I've now pretty much replicated the behavior of the original Central Build Group AI, including an annoying habit of assigning a distant build to the slowest unit in the group, then assigning all the faster units to guard the slowest. :?

Still to do:
a) Ability to assign a different unit group to Central Build, or create a custom group separate from Spring's normal groups.
b) Ability to create multiple Central Build groups. Low priority for me as I don't remember ever using more than one, anyway.
c) Add some intelligence to the job assignment. Currently, idle units are just assigned to the closest job they can do. I would like to factor in travel time, build speed, resource levels, and other stuff that a human player would do without thinking.
d) Add footprint outlines to the ghosted queued build orders. I keep stacking things on top of each other because I forget how far out a solar collector unfolds.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Central Build AI as lua widget!

Post by Niobium »

Looks good.

Replace widget:Update() with widget:GameFrame(n), where n is current gameframe.

Move UpdateOneGroupsDetails into GroupChanged and remove from update(). (There is only one place where groupHasChanged is modified, so I don't know why you are polling it in update)

widget:UnitCmdDone() and widget:UnitIdle() should cover all cases where a unit becomes idle, in which case you can move idle checking from update() into those callins. Though you'll have to test that. If this is the case then you no longer need Update().

You should also use widget:UnitDestroyed() and widget:UnitTaken() to remove builders as they die/are given to another team, can help solve some weird errors in advance (What would happen if you gave a central builder to a teammate? Your widget would detect it as alive, as well as being able to get its command queue, but all orders issued would not go through)

Also, you need to include spec checking as the game is running, i.e. you were a player and then you died and are now a spec. Most widgets just do a check every second / 30 gameframes, which is good enough. Nothing will go wrong if you try and issue orders as a spec, but it's good form to remove it.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Niobium wrote:Replace widget:Update() with widget:GameFrame(n), where n is current gameframe.
Another item I'd seen but had no idea what it meant. Is there a manual somewhere that I haven't found? All I can find in the wiki are lists which, if I'm lucky, tell me what parameters are used.

By the way, what's Update() supposed to be used for?
Niobium wrote:Move UpdateOneGroupsDetails into GroupChanged and remove from update(). (There is only one place where groupHasChanged is modified, so I don't know why you are polling it in update)
I did it that way originally because that's the way gunblob did it in his Unit Groups widget. My first inclination was also to move all the code into widget:GroupChanged(). However, when I did so, I found that Spring.GetGroupUnits() was returning an empty unit list or what appeared to be the unit list from before the change. Only by waiting a frame or two could I get an accurate current list of units in the group.
Niobium wrote:widget:UnitCmdDone() and widget:UnitIdle() should cover all cases where a unit becomes idle
It covers all the cases where a unit becomes idle, but if there's no work in the queue to assign it at that time, doesn't it stay idle? I'd still have to cycle through my units and look for idle ones at some point. Although I could put the idle check in widget:CommandNotify(), since that's the only time new orders would enter the queue. I'll look into that. But I'm still considering a delay to allow the idle units to stack up a bit so I can decide on new orders as a group instead of individually.
Niobium wrote:You should also use widget:UnitDestroyed() and widget:UnitTaken() to remove builders as they die/are given to another team, can help solve some weird errors in advance
I was hoping that widget:GroupChanged() would catch all those situations. A unit that's dead or captured or whatever shouldn't be in my unit group anymore, which would trigger GroupChanged, which would trigger UpdateOneGroupsDetails, which would update my list of central builders.

I did use those call-ins in my Metal Maker and Retreat widgets. I'd just hoped I could avoid some of the housekeeping by using widget:GroupChanged().

Thanks again for the help.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Central Build AI as lua widget!

Post by Niobium »

http://springrts.com/wiki/LuaCallinReturn

Which is linked to from http://springrts.com/wiki/Lua_Scripting

Update() just gets called constantly no matter what. GameFrame() gets called when a gameframe has passed, so its affected by game speed, paused/unpaused, game having started, etc. Update() will just fire all the time. Afaik anyway.
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

Those are the pages I've been checking. Usually, I have to wait for someone to point out a particular call-in or variable or command or whatever before I realize what it does. For example, I would have never guessed what CommandNotify() does if you hadn't suggested it for a specific purpose. Mostly, I'm just grabbing code from widgets that do something I think I need to do.

I'll switch to GameFrame() for the next version. I found a bug I want to squash in UnitCmdDone() anyway. It's stopping guard orders that it shouldn't, and I just realized why.
SeanHeron
Engines Of War Developer
Posts: 614
Joined: 09 Jun 2005, 23:39

Re: Central Build AI as lua widget!

Post by SeanHeron »

Seems you might not have seen this:

http://springrts.com/phpbb/download/file.php?id=773 ?!

Has been (rightly) referred to as the "Lua Bible" :).

Don't know if it's the most current version though.
Regards
Sean
User avatar
troycheek
Posts: 80
Joined: 22 May 2009, 19:13

Re: Central Build AI as lua widget!

Post by troycheek »

That's the same version I have. (I'll have to re-read it in depth now that I've got a little better understanding of the subject.) While it does list a lot of call-ins, very few are actually described, much like the wiki. If everyone else can read a list of call-ins and intuitively understand exactly when they're triggered and what they'd be useful for, then I apologize for being slow. But as I said, it took someone suggesting CommandNotify() for a specific purpose before I realized what it did, then pure luck stumbling upon a post in another thread to understand how to get it to do what I wanted.

widget:CommandNotify(cmdID, cmdParams, cmdOptions) where cmdID = id code of the command issued (negative numbers indicate a build order), cmdParams = parameters of the command (map location, unitID, or whatever appropriate for that command), and cmdOptions = (need help here). This function is triggered once after each command issued by the player to a unit, but before the unit actually receives the command. Useful if the programmer wishes to modify or redirect commands. When functions exits, the command will be passed on to the unit unless function returns TRUE indicating that it has already handled the command.

I'm not even sure that's all correct, but it's my best guess after messing around with the thing for a few days. Not that exploration and experimentation in and of themselves aren't fun and educational, it's just that it gets a little frustrating sometimes when you bang out revision after revision trying to get something tuned just right only to realize that there was a call-in that detected exactly what you were looking for, you just didn't know about it.

Oh, it looks like it's time to upload a new version of the Central Build AI widget. New to v0.6:
1) have replaced Update() with GameFrame().
2) moved spectator check out of Update/GameFrame loop and now have a check in Initialize() and another in PlayerChanged(). (Thanks to SeanHeron for reminding me to check the Lua Bible again.)
3) fixed a bug where Central Builders would get nonCB orders canceled.
4) hopefully CBAI is now a bit smarter job assignments. Now taking all idle builders into account before sending them out on jobs.
5) slightly more likely to choose construction aircraft and hovercraft (canFly and canHover) as primary builders under the assumption that they can reach a project site more quickly than a ground vehicle.

There are still problems when the assigned builder can't reach the build location, but that will have to wait until I understand pathfinding better (possibly never). This was also a problem with the original Group AI.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Central Build AI as lua widget!

Post by Niobium »

Everything you said about CommandNotify is correct.

cmdOptions is alt/shift/control/meta modifiers. (i.e. cmdOptions.shift). There is also cmdOptions.coded for the functions which require options in that form.
SeanHeron
Engines Of War Developer
Posts: 614
Joined: 09 Jun 2005, 23:39

Re: Central Build AI as lua widget!

Post by SeanHeron »

Well, sorry if it wasn't that much help - but I must say I'm quite impressed with what you've put together, seeing you've started from scratch! (I tried my hand at a Lua AI, and god, was progress slow...).

I was under the assumption you didn't know the "bible", cause you hadn't used the "GameFrame" call in, and that is one of the ones that is described - though to be honest I wouldn't know why to choose that over "Update" either :P. And same as you, after working for a bit I appreciated looking through the big daunting document again more than first time round!

I know SpliFF has the Coding Guide on his SVN, I'll have to ask/ check if anythings changed - and of course, we should probably look for a way that the stuff that you found out can be added in the relevant section! (After all that's the way SpliFF put it together)

Sean
Post Reply

Return to “Lua Scripts”