Element of a reusable, expandable AI interface

Element of a reusable, expandable AI interface

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

Post Reply
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Element of a reusable, expandable AI interface

Post by cain »

this is just a quick purposal, aimed to start a discussion to how should be make the interface freely expandable.

the changes purposed in there hare aimed to the 0.7x version, as to leave us some time to prepare beforehand (I can't access cvs, for example)

the quick and dirty bits:

adding a

Code: Select all

cons tvoid *extendedRequest(int request ID, const void *data);
in the IAIInterface and in the IAICallback,
to have a two way extensible model.

those functions can be used to extend the request adding new possibility without breaking code compatibility, and then addnig the function back into the interface at a major release (for example, at the 0.8x)

example:
ai extension for get a unit position (I know it's already there, it's just an example)

Code: Select all

#define REQ_UNITPOS

...
const void *extendedRequest(int request ID, const void *data) {
   switch(requestID) {

   case REQ_UNITPOS:
      int unitid=*((int *)data);      
      float3 pos=somefunctiontogetpos(unitid);
      return *pos;
      break; 


   default: return NULL;
   }

}




in the ai:

Code: Select all

 float3 pos=*extendedRequest(REQ_UNITPOS,&unitid);

it's not the cleanest implementation, but the easyest to build. at the next major release, you can just put the swich function in the interface and prune out unnecessaries one, restarting te process so you can put only stable code in the interface and keep a way to add on the fly functionality without breaking dll compatibility.
As for a major release, we could cope easily with the addition mapping the extended request on the functions itself.
or you can leave the request as extended request, or take an entire different direction applaing this metodology to all functions (undesiderable, also known as the big switch of death) or extend it furter to use a tree request structure, using a pair of id in the interface ex:

Code: Select all

float3 pos=*extendedRequest(DOMAIN_UNIT, REQ_POSITION, &unitid)
where domain is another #define
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Post by cain »

some considerations I left out:

us developer could easily and trasparently provide extensions for each others to use, with a generic interface. The switch mechanics provides nice fallback to unknown extension (a nice NULL poiunter, that is =) ).
Also the domain tag could be useful for this:
float3 pos=*extendedRequest(DOMAIN_ZCAIN, REQ_NEARESTMETALSPOT, *parameters);
where parameters is a struct explained in the documentation

the documentation of extensions is an important factor of this system

this is a more c like approach than c++, but cancallback be done also with class (requires more code and abstraction, I don't have time for a proper example, but the main idea is that the command request should provide a execute interface to take care of all and a constructor to import parameter, one used by the callback and the latter for the ai):
AI:
getunitposcommand : public command
blah

c=new getunitposcommand
execute c

interface:
c.execute

ai:
c.getresults

the ai knows the command tipe and the parameters it takes, the interface not, but uses the public command interface to call the execute method

still, i prefer the c approach, as for the GiveOrder callback (that does something like this, you send id and parameters and actions happens)

for people arguing the stability of passing pointer to spring:
if I've a malicious intent to crash the game, developing
a dll i can just do something like *NULL=1 and KABOOM!!.
normal bugs just happends, and all the ai out of there could
potentially crash the pc (jcai had a division by zero bug, ismbabel (i think) reports crashbug of ntai) using the standard, "secure", interface
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

Ok I see why this is needed. Here's what I will implement if you agree:

Code: Select all

new IAICallback functions:

#define AIVAL_UNITPOS        // float3*
.. AIVAL_UNITDEF             // const UnitDef*
AIVAL_UNITHEALTH           // float*

const void* GetUnitProperty(int unit, int property);
const void* GetValue(int id);

new IGlobalAI functions:

int HandleEvent(int msg, const void *data);
Im only going to use the HandleEvent for new types of messages, since we have the other functions now anyway.

This means there is going to be one last change for a long time, after that AIs stay binary compatible even if the messages are extended.
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Post by cain »

ok, that will do.

the getPoperty is a more standard and definite method.
maybe should be called only getproperty to be more extensible(extendible? expandable? boh. i'll go to study english a bit more)

also there should be a handle event for the callback
so you cand send generic message to the callback and
also to the ai dll.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Actually I have a better idea. I propose the LUA itnerface be bound to the AI interface so that we can call lua scripts from the AI interface, adn we can send lua commands as strings. That way I could say aicb->dofile("AI.lua"); or int threat = aicb->dostring("getthreat(%i)",unitid);

This would allow us to do the above much better, it would also allow us to itneract with missions, change other thigns, allow things such as mission scripts to itneract with the AI, allow mission scritps to use AI extensions, and could then even be used with the scripting for units.

Another benefit is that this makes writting config parsers so much easier, as you could just write a function int this = aicb->dostring("aigetthis()"); rather than writting a config parser that went through a file on the hd taking mroe tiem increasing filesize, and creating more lag at startup.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

And it would make the AI a hell of a lot slower, so I completely disagree.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Yeah but that depends on the script you're using, I could say the same thign abou adding code tot he AI but that doesnt stop you adding features.

Eitherway I would like those functions in the interface, they're useful, and it's not as if every call we make is going to use the Lua VM.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

You could say the same thing about adding features, but it wouldn't make a lot of sense saying it. Adding features doesn't slow down a program, as long as you do it well.

Calling LUA with the AI is not a real speed problem, as long as it will use the VM. Calling it like
aicb->dostring("getthreat(%i)",unitid);
is a problem, since then it will have to parse the code first.
In the future a LUA mission script to AI code seems very useful, but I think it's better to wait for the LUA script parts of spring maturing a bit.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Zaphod, ahve you ever seen a dostring() function defined? I've written them, it isnt that hard, it isnt that work intensive, your config parser or my original OTA parser are more cpu intensive than a dostring() function, a dostring function is about as cpu itnensive as your log print function at most, anymore overhead is from the script itself that you're calling.

I would say a dofile() function would be slower.
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Post by cain »

actually, i prefer the property system. this will free the dll of implementing lua, the interface of implementing lua and a lot of bloated code.

also the lua will hit as an hammer on chaching. it's a good system for interpreting a script, but will introduce unnecesasary complexity on a system. I love the occam's razor
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

The dll wouldnot need to implement lua unless it wanted to use its own modified version of lua, which is highly unlikely and too much work.

Implementing a LUA itnerface into the AI itnerface would require little work and would not require any additional code on the AI developers part.
Post Reply

Return to “AI”