Light Style© by Fisana

Jump to content


Photo

AI API changes


  • Please log in to reply
48 replies to this topic

#1 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 20 December 2011 - 05:54 PM

Since the AI API is planned to be updated I thought that creating a thread to finalize the changes that will happen. This is marked to be done as part of the Pledgie work by Philip, I would be willing to help but I think some of the planned changes (e.g. running in a separate thread) would be best done by Philip.

I would like to have the changes below for qBot, it would be good to have feedback from other AI developers especially, feedback from everyone else is welcome of course. I have tried to mention how juBot behaves where relevant to the extent of my knowledge, I don't know enough about splitBot to comment though.

Core API

I am calling the current system the core api, these changes may break current AI scripts, depending on how they are done.

Running the AI scripts in their own threads. This should improve situations on multi core systems and also stop stuttering of the game when an AI does something expensive.

Storing entity objects persistently rather than constantly recreating them. This is fairly simple and should help the garbage collector mainly (plus a little less overhead creating the objects though this should be pretty cheap). I did a quick test by modifying the current api and have attached the code. It works with JuBot (qBot does some naughty stuff) and there seemed to be some performance improvement but it was fairly minor and my setup for measuring is rather crude, I measured about a 280ms to 230ms change at 10x speed but don't take this as an accurate figure.

Persistent entity collections
.
This is what I think will deliver the largest performance increase (qBot currently uses a crude version for this reason), but will require modifying AI scripts to take advantage of them. Based on my testing JuBot spends about 98% of the time filtering through entity collections. Here is my idea of how these should work:

You would create a new entity collection by filtering an existing entity collection (I think juBot does this exclusively). You would give the filter function as an argument (see filters.js in the attachment) and it would be stored as part of the entity collection. Then if you wanted to store the entity collection, you would use some sort of registerEntityCollection() function. From this point the entity collection would be maintained by the API. The filter functions of the parent would be inherited.

(more technical details, can be ignored)
The filter function may depend on a dynamic property, for efficiency I think it would be helpful for the API to be told which it depended on. So you could have player 2's idle units which would depend on the idle and owner properties. The combination of this with the Filter.js file leads to the question of how the dynamic properties would be passed to the entity collection. To keep things neat when using Filters.js putting the function and dynamic properties list into a simple object/array would keep things neat. This makes things more messy for someone making their own filter functions from scratch since they now need to wrap it in an object. I think this method is preferred though. e.g. {'func': filter_function, 'dynamic_properties': ['owner', 'idle']}

Filtering based on position presents a potential performance problem since there can be a lot of position updates every turn, I think for now it would be worth keeping thing simple and not doing anything special and see what happens, it should be able to offload it to a C++ component without any interface changes if it is a problem.

Another possible performance factor would be storing the entity collections in a hierarchy so you could avoid looking deeper in a tree for a lot of events. This should also be possible without any API changes so isn't important as a consideration currently.
(end of technical details)

Other Stuff
Here are other helpful functions that it would be nice to have an interface for in an AI. I have put them in what I think should be their priority.

Accessibility testing, can a unit reach another point on the map from where it is currently? QBot does this already but it is one of the factors causing lag at the start of games and is based on the coarse accessibility map which has caused some issues. Also qBot's version is not dynamic for performance reasons.

UnitAI state. It is nice to know whether a unit is walking, attacking, woodcutting...

Map manipulation functions see http://www.wildfireg...89 for details. Also see map.js in qBot.

Fairly low level pathfinding access or some terrain analysis functions. See terrain-analysis.js for a rough idea of what I want to be able to do. More fancy stuff would be good as well. On a basic level giving a pathfinder using a specified custom map to route over (basically adding some more inaccessible areas).

Edit 06-04-2012: Now the code is in svn
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#2 shnbwmn

shnbwmn

    Discens

  • Community Members
  • Pip
  • 10 posts

Posted 21 December 2011 - 10:54 AM

Nice, looking forward to these changes :cheers:
  • 0

#3 Echelon9

Echelon9

    Discens

  • Donator
  • 88 posts

Posted 24 December 2011 - 12:31 PM

On map manipulation functions, are you constraining your solution to just single fading spheres? Potential fields or threat hulls could offer additional benefits as one of the "types", or alternatively a blend of many influence fields.

Berkley Overmind -- the Starcraft AI -- used this approach.
  • 0

#4 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 08 January 2012 - 04:40 PM

On map manipulation functions, are you constraining your solution to just single fading spheres? Potential fields or threat hulls could offer additional benefits as one of the "types", or alternatively a blend of many influence fields.


We chatted about this on irc a while back. Basically the outline above will create a potential field, non round threat hulls would be useful to have, and should be easy to add.

Also I have extended my prototype code, now I have updating entity collections working (I think, I didn't test thoroughly though). I am still a bit unsure about the interface, my function names could be improved and the grouping of filters and dynamic properties still feels a bit messy.

It almost maintains compatibility with juBot, changing line 65 of gamestate.js to
return this.ai._ownEntities;
makes it work. No performance benefit is achieved without changing lots of code though. Having ownEntities as a special case makes less sense with this new code, my new code just registers it as an updating EntityCollection and lets the standard code handle it from that point. I think it should be removed and left to individual AI's.

A usage example is:
	if (!this.allWorkers){
    	var filter = Filters.or(Filters.byMetadata("role", "worker"), Filters.byMetadata("role", "militia"));
    	this.allWorkers = gameState.getOwnEntities().filter(filter);
	}

Metadata updates instantly affect the entity collections. For efficiency, metadata filters use "metadata.{key}" as the dynamic property, using just "metadata" is supported and will catch all metadata changes.

Deleting metadata is unsupported currently, also saved games are broken.
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#5 lexa

lexa

    Discens

  • Community Members
  • Pip
  • 77 posts

Posted 02 February 2012 - 10:03 PM

So, if I understand well, the main change will be in the way one can filter and keep entities organized?

What I missed in SplitBot
- persistance for the EntityCollections
- ability to put metadata on a building when you start to build it (like you do it when you start to produce a unit)
- an easy way to detect if a place is buildable with a given unit at a given position and orientation
- an easy way to detect if there is water between a unit and a position

What would really have helped me is an event system. To be able to give a callback and arguments in these cases:
- when you start to build an entity or produce a unit: onBuildComplete and onBuildStoped
- when you send a unit somewhere: onUnitArrived, onUnitBlocked
- when you send a unit to harvest, onStart, onUnitBlocked, onResourceEmpty, onDropResource, onResourceIsFarAway...
- ...

Just in case it is useful to you : in SplitBot have filtered the entities in this arrays and used a kind of "cache" system to compute the array only one time per tour :



I think that the "Filters.byMetadata" thing would make my life easier, would it be fast if done with a C function?


And last thing : I do not think it is necessary to have the {'func': filter_function, 'dynamic_properties': ['owner', 'idle']} argument to keep a selection up to date. It can be done by hand easily if there are events.
  • 0

#6 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 03 February 2012 - 07:22 PM

So, if I understand well, the main change will be in the way one can filter and keep entities organized?

What I missed in SplitBot
- persistance for the EntityCollections
- ability to put metadata on a building when you start to build it (like you do it when you start to produce a unit)
- an easy way to detect if a place is buildable with a given unit at a given position and orientation
- an easy way to detect if there is water between a unit and a position

What would really have helped me is an event system. To be able to give a callback and arguments in these cases:
- when you start to build an entity or produce a unit: onBuildComplete and onBuildStoped
- when you send a unit somewhere: onUnitArrived, onUnitBlocked
- when you send a unit to harvest, onStart, onUnitBlocked, onResourceEmpty, onDropResource, onResourceIsFarAway...
- ...

Just in case it is useful to you : in SplitBot have filtered the entities in this arrays and used a kind of "cache" system to compute the array only one time per tour :

I think that the "Filters.byMetadata" thing would make my life easier, would it be fast if done with a C function?

And last thing : I do not think it is necessary to have the {'func': filter_function, 'dynamic_properties': ['owner', 'idle']} argument to keep a selection up to date. It can be done by hand easily if there are events.


The main thing is basically persistent entity collections, along with a group of preset filter functions which make it easy to use. This would be done in javascript initially, I think performance should be good enough. For performance though, the dynamic properties are important because without the automatic updating we are in exactly the same situation as now, and there are lots of position changes every turn so performance will be poor without filtering by dynamic property.

Metadata on buildings makes sense, I think we should do that.

The water information is linked to accessibility testing and pathfinding. It would be helpful to have, I think it would be best to leave this until Philip has finished the current pathfinding stuff and then come up with a decent AI interface for the whole section.

Buildability should be fairly easy to expose.

An event system would be a pretty big change. I currently can't see much use for it in qBot, but i haven't given it much thought. It should be possible to implement in the common-api code which would make it fairly straightforward to add, it would just run events at the start of your AI's turn.
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#7 lexa

lexa

    Discens

  • Community Members
  • Pip
  • 77 posts

Posted 03 February 2012 - 11:11 PM

I find it good to have persistent entity collections, clearly

but for the "automatic updating" of entity collections, I believe that it is better to have an event system which lets you update your model (keep the collections up to date), than to have this "binding"-like functionality
just because in javascript and web languages it is much more common / standard

and as far as I'm concerned, after a long time of practicing this languages for building complex web applications, I even prefer the callback version. the addEventListener version of an event system has a good point : you can add several listener, you will not prevent a callback to be called. but the problem is that at the end, it is much harder to debug. and also, callbacks force you to have a cleaner and simpler architecture.


finally the preset filter functions should be useful. in splitbot i used a helper class to access these collection with a "cache" mechanism

public static var myEntities:EntityCollection;
public static var myPeopleUnits:EntityCollection;
public static var myBuilderUnits:EntityCollection;
public static var myBuildingStructures:EntityCollection;
public function getMyEntities():EntityCollection
public function getBuilders(entities:EntityCollection):EntityCollection
public function getWorkers():EntityCollection
public function getFondations():EntityCollection
public function getBuildings(allowedTemplateNames:Array<String> = null):EntityCollection
public function getResources(entities:EntityCollection, type:ResourceSupplyType = null):EntityCollection

  • 0

#8 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 03 February 2012 - 11:29 PM

but for the "automatic updating" of entity collections, I believe that it is better to have an event system which lets you update your model (keep the collections up to date), than to have this "binding"-like functionality
just because in javascript and web languages it is much more common / standard

and as far as I'm concerned, after a long time of practicing this languages for building complex web applications, I even prefer the callback version. the addEventListener version of an event system has a good point : you can add several listener, you will not prevent a callback to be called. but the problem is that at the end, it is much harder to debug. and also, callbacks force you to have a cleaner and simpler architecture.


Sorry, I'm not quite sure what you mean by this. Could you elaborate a bit?
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#9 lexa

lexa

    Discens

  • Community Members
  • Pip
  • 77 posts

Posted 04 February 2012 - 12:44 PM

Sorry, I'm not quite sure what you mean by this. Could you elaborate a bit?


You mean the event thing to update the collections?


For example, let's say you have a collection of all of your workers. Each time you build a unit, you would provide a "onBuildSuccess" callback. And in this callback, you could get the unit as a parameter. Anyway you could maintain the collection of your workers up to date in the code of the "onBuildSuccess" callbacks..

I hope I was more clear this time... Posted Image Don't hesitate to challenge me and see if we can get something interesting before Ykkrosh starts his job :)
  • 0

#10 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 05 February 2012 - 12:05 AM

I think it will be much better to have this happen automatically, rather than each AI having to implement entity collection maintenance. Putting it into the API also allows the code to be easily changed for performance improvements without having to change everyones AI scripts. Of course it is possible to create entity collections the old way and manage everything yourself.

Adding some form of notification about changes would be useful. Currently there is the array of events for this, but it is fairly limited.

The game is built on a turn based system so I think the AI's will always be restricted to a turn based system like they are now. Callbacks are still workable though. There are some things which you would need to consider though. The main thing is that the games' state will have changed by the time the callback is called so this might cause issues with specifying parameters for the callback.
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#11 wraitii

wraitii

    Primus Pilus

  • WFG Programming Team
  • 1,666 posts

Posted 05 February 2012 - 08:16 AM

Not sure callbacks are actually needed for the AIs... There's updated often, and with a bit of tweaking, some "watcher" functions could be updated even more often.

I quite agree with the other changes though.
  • 0
Lancelot de Ferrière le Vayer [ aka Wraitii ]
Wildfire Games Programmer, AI developer, auxiliary map designer, dealing with anything water.
Contact me: wraitii@wildfiregames.com

Also the world's only three-dimensional poodle.

#12 lexa

lexa

    Discens

  • Community Members
  • Pip
  • 77 posts

Posted 05 February 2012 - 07:46 PM

The events would be called at the start of each turn. I was not thinking at something complicated like events called outside of the AI turn
The events are clearly a better way to go for me, because it is much more natural/standard and easy to use in javascript. And often I would use it without having a collection to update.


  • 0

#13 historic_bruno

historic_bruno

    Primus Pilus

  • WFG Programming Team
  • 2,491 posts

Posted 05 February 2012 - 11:13 PM

The events are clearly a better way to go for me, because it is much more natural/standard and easy to use in javascript. And often I would use it without having a collection to update.

I would leave "event" handling up to the AIs, and make sure all the most meaningful events are provided on the chance they need to be used. But I also think unlike some other JavaScript applications, AIs shouldn't be sitting around waiting for events, but always active processing things, since they have enough to do already :) We can even provide a decent interface to poll the events. But I think there should be higher level data structures for the really useful data, like entities owned by the player or tile obstructions.
  • 0
Ben Brian [ aka historic_bruno ]

Wildfire Games Programmer
Contact me: ben [at] wildfiregames [dot] com

#14 lexa

lexa

    Discens

  • Community Members
  • Pip
  • 77 posts

Posted 07 February 2012 - 09:26 PM

Also a way to get the chat messages typed by users would be nice (see what i mean?)
  • 0

#15 Pedro Falc„o

Pedro Falc„o

    Centurio

  • Community Members
  • PipPipPipPipPip
  • 651 posts

Posted 18 February 2012 - 02:39 PM

Also a way to get the chat messages typed by users would be nice (see what i mean?)


Indeed it would be good just as an extra option for the AI developers.

I'm interested in creating AIs, but i know little of the API and i'm not much familiar with Javascript (even though it's similar to Java). When you guys get these changes done, i'd like to see the new API and try to do anything, so please post a link on this topic to it.
  • 0
Pedro Falc„o
Latin: Petrus Falco; Literally means 'Stone Hawk'.
English equivalent: ' Peter ';


Undergraduate Computer Scientist by UFCG
Shotokan Karate Adept, 3rd Kyu (Green Belt) & Muay Thai initiate

#16 feneur

feneur

    Cartographer of imaginary worlds

  • 0 A.D. Project Leader
  • 7,986 posts

Posted 18 February 2012 - 04:16 PM

Indeed it would be good just as an extra option for the AI developers.

I'm interested in creating AIs, but i know little of the API and i'm not much familiar with Javascript (even though it's similar to Java). When you guys get these changes done, i'd like to see the new API and try to do anything, so please post a link on this topic to it.

There is some existing documentation here: http://trac.wildfire...com/wiki/TDD_AI , and some of the new changes are likely to be documented there. The main source will most likely be the code itself though, http://trac.wildfire...c/simulation/ai and then the individual folders for the main API/individual AIs. As far as I can tell from a quick look the code is pretty well documented, so if you have at least some JavaScript knowledge it's probably best to jump right in :) Of course, given that the API will change, it might be just as well to wait a while before starting, but if nothing else you can spend the time improving your general JavaScript knowledge ;)
  • 0

Erik Johansson [ aka feneur ]

Wildfire Games
Contact me: feneur@wildfiregames.com



Support Wildfire Games!


#17 wraitii

wraitii

    Primus Pilus

  • WFG Programming Team
  • 1,666 posts

Posted 19 February 2012 - 10:24 AM

Getting access to at least the "high level pathfinder" for a set of entities would be nice... Sending armies could be dealt with more easily, analyzing the map can likely be done easier with the current AI API.
(I'm thinking for example some sort of A* function that would return a path, possibly every x "cells" or at each turn.)

I forgot about the UnitAI stuff. It would really be useful, particularly to know which unit is attacking who.

Edited by wraitii, 19 February 2012 - 01:56 PM.

  • 0
Lancelot de Ferrière le Vayer [ aka Wraitii ]
Wildfire Games Programmer, AI developer, auxiliary map designer, dealing with anything water.
Contact me: wraitii@wildfiregames.com

Also the world's only three-dimensional poodle.

#18 fabio

fabio

    Centurio

  • WFG Programming Team
  • 657 posts

Posted 05 April 2012 - 08:47 AM

This was committed in r11429 by quantumstate.
  • 0

Graphics problems with 0 A.D. under Ubuntu and free drivers? Check out the Updated and Optimized Graphics Drivers Archive: includes updated drivers with fixes and improvements for games, including 0 A.D..


#19 quantumstate

quantumstate

    Primus Pilus

  • WFG Retired
  • 1,150 posts

Posted 05 April 2012 - 09:28 AM

Currently there are the "Core Api" changes and UnitAI is exposed to the AI's.
  • 0

Jonathan Waller [ aka quantumstate ]

Wildfire Games Programmer
Contact me: jonathanmarkwaller at gmail dot com


Support Wildfire Games!


#20 Almin

Almin

    Sesquiplicarius

  • Community Members
  • PipPip
  • 177 posts

Posted 05 April 2012 - 11:48 AM

But the first version of common-api will stay where it is now, won't it? Because I play around and try myself out on an own bot and probably need it as a school porject. So will the regular common-api stay the way it is, at least for the next half year?

Edited by Almin, 05 April 2012 - 11:48 AM.

  • 0
sry for my english