View topic - Global AI Interface



All times are UTC + 1 hour


Post new topic Reply to topic  [ 214 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  Next
Author Message
 Post subject:
PostPosted: 12 May 2005, 11:39 

Joined: 10 Mar 2005, 07:32
Location: Amsterdam
PauloMorfeo wrote:
I just hope that the development of TA::Spring never gets dependent on closed development.


It won't.
I am now completely dedicated to an open process, where anyone can learn from the code and send the maintainers code improvements.
I think Jounin feels (sort of) the same about..
If someone has usefull code to contribute, i'm sure the maintainers (whomever that may become) will take a look at it.

I will help, and certainly understand the code for an "unbeatable AI" in all it's detail, but I simply do not know how much time i'll have to actually write code that's good enough to end up in the public releases.

I'd like to add something about alfa males, and how it affects societies.
But I'll keep it short; there should be no throne to be had in this project, there should only be (a) round table(s).

Alantai, I think it's time you kicked me off your team. I've had some time to think it over, and your way is not mine, sorry.

I realize that those AI teams with simpler design are gonna release sooner probably than the 'unbeatable' AI teams.

Good hunting, and may the best AI win ;-)


Top
 Offline Profile  
 
 Post subject:
PostPosted: 12 May 2005, 12:09 
AI Coder
User avatar

Joined: 14 Sep 2004, 10:32
Location: Cookieland
In which case I bid you farewell from darkstars Renev, may your path be filled with promise and innovation.

As for competition, I look forward to seeing you all tremble infront of the AI's we release.


And simple AI, people, do us all good, the eyes and ears of the community will be watchign you if we at darkstars dotn beat you to it, or people with previous experience writting RTS AI's & lots of spare time take up the challenge


Top
 Offline Profile  
 
 Post subject:
PostPosted: 12 May 2005, 12:47 
User avatar

Joined: 29 Aug 2004, 21:24
Besides, we can probably steal something useful from the Simple AI's that get out before us.


Top
 Offline Profile  
 
 Post subject: request
PostPosted: 14 May 2005, 07:04 
User avatar

Joined: 09 Jan 2005, 04:52
I have one more request that i would like to have in
the interface from start: std::string QueryMapPath().
So it is possible to have per-map settings for the AI
The goal, in the long run, would be to not need that,
but it would be nice to have for starters...


Top
 Offline Profile  
 
 Post subject:
PostPosted: 14 May 2005, 22:27 
User avatar

Joined: 08 Sep 2004, 21:59
Location: Qc, Canada
PauloMorfeo wrote:
I just hope that the development of TA::Spring never gets dependent on closed development.


I wonder... with the GPL, don't you have to distribute the source code even of the modules you design for the game? Only the LGPL allows you to distribute closed-source modules. So you can do "closed development" as long as it is for your own private use, but if you want to release anything, the AI module has to be released under the GPL.


Top
 Offline Profile  
 
 Post subject:
PostPosted: 14 May 2005, 23:07 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
to my knowledge, that is not the case. plugins/modules can be closed source so long as they do not use the gpl-ed code internally


Top
 Offline Profile  
 
 Post subject:
PostPosted: 14 May 2005, 23:30 
User avatar

Joined: 29 Aug 2004, 21:24
He didn't say we weren't going to release the source, just that we weren't going to release it until we were finished. Now, can we drop the subject?


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 05:27 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
here's a tentative interface i whipped up...

Code:
#pragma once

#include "command.h"
class IGlobalAICallback;

#define GLOBALAI_INTERFACE_VERSION 1

#include "float3.h"

class IGlobalAI
{
private:
   IGlobalAICallback*      m_pCallback;
   int                  m_iTeam;

public:
   virtual void InitAI(IGlobalAICallback* callback, int team)=0;
   // unit id of the commander.  let's the AI start action
   virtual void Start(int commanderid);

   virtual void UnitCreated(int unit)=0;
   virtual void UnitDestroyed(int unit)=0;

   // this is handled as an installed callback on a specific "spotter" unit
   // *hint* i'd probably use this on a peeper, send it into an enemy base, and recon all hits
   // to store in memory
   virtual void EnemyEnterLOS(int spotter, int spotted)=0;

   // not sure how this will be implemented yet...
   // im thinking along the lines of allies giving eachother commands or
   // notifications of their actions to coordinate attacks
   virtual void GiveMessage()=0;
   
   // i guess this will be called every frame, to let the AI do as it will
   virtual void Update()=0;
};


and

Code:
#pragma once

#include "float3.h"
#include "command.h"
struct UnitDef;

// typedef void (* ENTERLOSCALLBACK)(int spotter, int spotted);

class IGlobalAICallback
{
private:
   // this must be set to the AIs team number
   int      m_iTeam;
public:
   virtual void InitCallback(int team)=0;
   // not sure how this will work yet, as in IGlobalAI
   virtual void SendCommandMsg(int team)=0;

   // taunting :-D
   virtual void SendTextMsg(int player, const char* text, int priority)=0;
   
   virtual int GetCurrentFrame()=0;

   virtual void AddEnterLosCallback(int unit)=0;  //, ENTERLOSCALLBACK cback);
   virtual void DeleteEnterLosCallback(int unit)=0;

   virtual int GiveOrder(int unitid, Command* c)=0;
   // this sends a group order to what the AI has "selected".
   // must have called SendSelection
   virtual int GiveGroupOrder(Command* c)=0;

   // use this to sync up a selected group, if you want to send many mass orders
   // to the same group of units.  most AIs probably won't use this
   virtual int SendSelection(const vector<int>* units)=0;
   virtual const vector<int>* GetSelection()=0;

   // as per the Group AI, these return 0 if you don't have los to the unit in question
   virtual int GetUnitAiHint(int unitid)=0;
   virtual int GetUnitTeam(int unitid)=0;
   virtual float GetUnitHealth(int unitid)=0;         //the units current health
   virtual float GetUnitMaxHealth(int unitid)=0;      //the units max health
   virtual float GetUnitSpeed(int unitid)=0;            //the units max speed
   virtual float GetUnitPower(int unitid)=0;            //sort of the measure of the units overall power
   virtual float GetUnitExperience(int unitid)=0;   //how experienced the unit is (0.0-1.0)
   virtual float GetUnitMaxRange(int unitid)=0;      //the furthest any weapon of the unit can fire
   virtual const UnitDef* GetUnitDef(int unitid)=0;   //this returns the units unitdef struct from which you can read all the statistics of the unit, dont try to change any values in it, dont use this if you dont have to risk of changes in it

   virtual const UnitDef* GetUnitDef(const char* unitName)=0;

   //this will return a value even if you only have radar to it, but it might be wrong
   virtual float3 GetUnitPos(int unitid)=0;            //note that x and z are the horizontal axises while y represent height


   //the following functions allows the dll to use the built in pathfinder
   //call InitPath and you get a pathid back
   //use this to call GetNextWaypoint to get subsequent waypoints, the waypoints are centered on 8*8 squares
   //note that the pathfinder calculates the waypoints as needed so dont retrieve them until they are needed
   //the waypoints x and z coordinate is returned in x and z while y is used for error codes
   //>=0 =worked ok,-2=still thinking call again,-1= end of path reached or invalid path
   virtual int InitPath(float3 start,float3 end,int pathType)=0;
   virtual float3 GetNextWaypoint(int pathid)=0;
   virtual void FreePath(int pathid)=0;

   //This function returns the approximate path cost between two points(note that it needs to calculate the complete path so its somewhat expansive)
   virtual float GetPathLength(float3 start,float3 end,int pathType)=0;

   //the following function return the units into arrays that must be allocated by the dll
   //10000 is currently the max amount of units so that should be a safe size for the array
   //the return value indicates how many units was returned, the rest of the array is unchanged
   virtual int GetEnemyUnits(int *units)=0;               //returns all known enemy units
   virtual int GetEnemyUnits(int *units,const float3& pos,float radius)=0; //returns all known enemy units within radius from pos
   virtual int GetFriendlyUnits(int *units)=0;               //returns all friendly units
   virtual int GetFriendlyUnits(int *units,const float3& pos,float radius)=0; //returns all friendly units within radius from pos

   //the following functions are used to get information about the map
   //dont modify or delete any of the pointers returned
   //the maps are stored from top left and each data position is 8*8 in size
   //to get info about a position x,y look at location
   //(int(y/8))*GetMapWidth()+(int(x/8))
   //some of the maps are stored in a lower resolution than this though
   virtual int GetMapWidth()=0;
   virtual int GetMapHeight()=0;
   virtual const float* GetHeightMap()=0;                  //this is the height for the center of the squares, this differs slightly from the drawn map since it uses the height at the corners
   virtual const unsigned short* GetLosMap()=0;         //a square with value zero means you dont have los to the square, this is half the resolution of the standard map
   virtual const unsigned short* GetRadarMap()=0;      //a square with value zero means you dont have radar to the square, this is 1/8 the resolution of the standard map
   virtual const unsigned short* GetJammerMap()=0;      //a square with value zero means you dont have radar jamming on the square, this is 1/8 the resolution of the standard map
   virtual const unsigned char* GetMetalMap()=0;         //this map shows the metal density on the map, this is half the resolution of the standard map

   virtual float GetElevation(float x,float z)=0;      //Gets the elevation of the map at position x,z

   virtual bool CanBuildAt(const UnitDef* unitDef,float3 pos)=0; //returns true if a given type of unit can be build at a pos (not blocked by other units etc)

   virtual float GetMetal()=0;            //stored metal for team
   virtual float GetEnergy()=0;            //stored energy for team
   virtual float GetMetalStorage()=0;            //metal storage for team
   virtual float GetEnergyStorage()=0;            //energy storage for team
};


I'm going to start implementing the stubs and giving this AI control over an actual player. input is welcome on this interface


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 07:16 
Spring Developer
User avatar

Joined: 13 Nov 2004, 08:35
Location: Central Time Zone, USA
It looks good over all. I have just a few concerns.

1. No way to get command queues. This would allow the AI to detect idle units. Additionally, it would allow the AI to get a queue, rearrange, add to or subtract from and send a new group of orders back.

2. No way to easily get resource flow rate. One could get the rate by subtracting stockpiles between frames, but Spring probably already has an internal flow rate monitor. We don't want the AI to be nanostalling before it detects a massive negative flow. I.e. your fusion reactor was destroyed.

3. I assume a unit is "created" when its construction is started. A functions saying to the AI, unit "completed" or some such would probably be helpful.

And finally, I would like to know a little more about the program flow. As it is now, it seems that the AI would be in series with the rest of the program. Is this something we need to worry about, or is it already in an independent thread?


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 08:22 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
i think ill just have spring call update every frame, and the AI can do its work then, so have the bulk of the AI being done there. as far as your other points, i agree completely, ill add those in.


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 08:35 
User avatar

Joined: 29 Apr 2005, 06:46
I just read the last couple pages of this thread and I must say it's amazing that someone would start a project for spring on the notion of complete closed source being they're working with an opensource engine.

Now I'm working on a massive project to better handle the needs of Spring. The Construction Set I'm working on is extensive. I've chosen the middle path. While the file format is wide open (see HPI diagram thread) and even the implimentation of that format will be open (via a dll and source) the work put into the core app itself may not be open. Aspects of the program will be open, the parts that ARE open, the zip libraries, for example. For the most part, the non-open parts of the system will just be massive internal functions that must be done to manage such a wide variety of files. These things are useless to someone interested in the format of the files, not how their managed in my specific program because they're program should differ in some way.

I'm not re-inventing the wheel, I'm just giving it better rims.

-Buggi


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 09:35 
Site Admin

Joined: 13 Aug 2004, 16:13
What do you think you would win by keeping part of the source closed buggi?

Jou: I think you should add an interface for AIs (group and global) to communicate via memory sharing. Something simple like

void* GetSharedMemoryArea(string name,int size);

Would be guaranteed to return an area of size size all 0 for the first caller. Would point to the same area when more AIs get the same named area. How to structure the memory would be up to the AIs.

Also it might not be so smart to use stl stuff in the interface since that will lock dll writers to use the same compiler as the main program is compiled with more or less (stl implementations being internally somewhat different between compilers). I just used them in the groupai as a stopgap thing but if you want to create something real you should implement some small versions of the needed classes yourself.

On a similar note you shouldnt have any variables in the interface just pure virtual functions.


Top
 Offline Profile  
 
 Post subject: Just reminding
PostPosted: 17 May 2005, 10:38 

Joined: 08 Sep 2004, 14:32
Also, Juoninkomiko, you remember about
UnitUnderAttack function? (and damage dealt per second)
Could there be a function that tells if a projectile/missile/Nuke is flying in your LOS or Radar, and it's direction?
A function to tell whether the spot on a map is sea, or land and whether it has wreckage/DT on it? (Maybe there's a function for this already, I don't remember...)
Wonder if the CanBuildAt() function tells whether a place is blocked by reclaimable objects/your units(so you can still build there) or terrain?

Alik


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 18:20 
User avatar

Joined: 29 Apr 2005, 06:46
Nothing SJ...

They could always reflect my code if they wanted the source :)

I'm not saying it would be closed, if something is interested in knowing how I did "this" or "that" then I'd share.

-Buggi


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 21:04 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
i thought about and determined that global and group ai's should be totally separate entities... if anyone has a compelling argument to oppose that, now's the time :)

about memory sharing, i think that's a good way of coordinating attacks between ai allies, and group ai's communicating with one another, so i'm adding that in as well. however, as per the previous statement, i'm not going to let group ai's and global ai's share the same memory.

about stl - totally slipped my mind, i'm removing that in a heartbeat.

alik - right now, canbuildat is just a stub that returns true in the globalai callback. i'm not sure how i'll put that in yet. about the damage per second, i think that should be left to the AI, since it would require alot of bookkeeping by spring for something that an AI might not necessarily use.

as far as unit creation, it was my intent to have that message sent when the unit/building is completed... hopefully that can be done easily. i'll post the updated tentative interface soon to reflect these changes


Top
 Offline Profile  
 
 Post subject:
PostPosted: 17 May 2005, 21:17 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
Only the callback interface was updated, here it is:

Code:
#pragma once

#include "float3.h"
#include "command.h"
struct UnitDef;

typedef void (* ENTERLOSCALLBACK)(int spotter, int spotted);

class IGlobalAICallback
{
public:
   virtual void InitCallback(int team)=0;
   // not sure how this will work yet, as in IGlobalAI
   virtual void SendCommandMsg(int team)=0;

   // returns the size of the created area
   virtual int CreateSharedArea(char* name, int size);

   // if null is returned, no shared area exists
   // returns the size of the area through the size parameters
   virtual void* GetSharedArea(char* name, int* size);

   // taunting :-D
   virtual void SendTextMsg(int player, const char* text, int priority)=0;
   
   virtual int GetCurrentFrame()=0;

   virtual void AddEnterLosCallback(int unit, ENTERLOSCALLBACK cback);
   virtual void DeleteEnterLosCallback(int unit)=0;

   virtual int GiveOrder(int unitid, Command* c)=0;
   // this sends a group order to what the AI has "selected".
   // must have called SendSelection
   virtual int GiveGroupOrder(Command* c)=0;

   virtual Command* GetCurrentCommand(int unitid)=0;
   // returns the number of commands in the queue for a given unit
   virtual int GetCommandQueueLen(int unitid)=0;
   // returns the command queue for a particular unit.  up to the AI to allocate sufficient
   // memory for the call, which is sent in the memsize parameter.  returns -1 on fail due to insufficient memory
   virtual int GetCommandQueue(int unitid, Command* commands, int memsize)=0;

   // use this to sync up a selected group, if you want to send many mass orders
   // to the same group of units.  most AIs probably won't use this
   virtual int SendSelection(const int* units, int numunits)=0;
   virtual int GetSelection(int* units, int memsize)=0;

   // as per the Group AI, these return 0 if you don't have los to the unit in question
   virtual int GetUnitAiHint(int unitid)=0;
   virtual int GetUnitTeam(int unitid)=0;
   virtual float GetUnitHealth(int unitid)=0;         //the units current health
   virtual float GetUnitMaxHealth(int unitid)=0;      //the units max health
   virtual float GetUnitSpeed(int unitid)=0;            //the units max speed
   virtual float GetUnitPower(int unitid)=0;            //sort of the measure of the units overall power
   virtual float GetUnitExperience(int unitid)=0;   //how experienced the unit is (0.0-1.0)
   virtual float GetUnitMaxRange(int unitid)=0;      //the furthest any weapon of the unit can fire
   virtual const UnitDef* GetUnitDef(int unitid)=0;   //this returns the units unitdef struct from which you can read all the statistics of the unit, dont try to change any values in it, dont use this if you dont have to risk of changes in it

   virtual const UnitDef* GetUnitDef(const char* unitName)=0;

   //this will return a value even if you only have radar to it, but it might be wrong
   virtual float3 GetUnitPos(int unitid)=0;            //note that x and z are the horizontal axises while y represent height


   //the following functions allows the dll to use the built in pathfinder
   //call InitPath and you get a pathid back
   //use this to call GetNextWaypoint to get subsequent waypoints, the waypoints are centered on 8*8 squares
   //note that the pathfinder calculates the waypoints as needed so dont retrieve them until they are needed
   //the waypoints x and z coordinate is returned in x and z while y is used for error codes
   //>=0 =worked ok,-2=still thinking call again,-1= end of path reached or invalid path
   virtual int InitPath(float3 start,float3 end,int pathType)=0;
   virtual float3 GetNextWaypoint(int pathid)=0;
   virtual void FreePath(int pathid)=0;

   //This function returns the approximate path cost between two points(note that it needs to calculate the complete path so its somewhat expansive)
   virtual float GetPathLength(float3 start,float3 end,int pathType)=0;

   //the following function return the units into arrays that must be allocated by the dll
   //10000 is currently the max amount of units so that should be a safe size for the array
   //the return value indicates how many units was returned, the rest of the array is unchanged
   virtual int GetEnemyUnits(int *units)=0;               //returns all known enemy units
   virtual int GetEnemyUnits(int *units,const float3& pos,float radius)=0; //returns all known enemy units within radius from pos
   virtual int GetFriendlyUnits(int *units)=0;               //returns all friendly units
   virtual int GetFriendlyUnits(int *units,const float3& pos,float radius)=0; //returns all friendly units within radius from pos

   //the following functions are used to get information about the map
   //dont modify or delete any of the pointers returned
   //the maps are stored from top left and each data position is 8*8 in size
   //to get info about a position x,y look at location
   //(int(y/8))*GetMapWidth()+(int(x/8))
   //some of the maps are stored in a lower resolution than this though
   virtual int GetMapWidth()=0;
   virtual int GetMapHeight()=0;
   virtual const float* GetHeightMap()=0;                  //this is the height for the center of the squares, this differs slightly from the drawn map since it uses the height at the corners
   virtual const unsigned short* GetLosMap()=0;         //a square with value zero means you dont have los to the square, this is half the resolution of the standard map
   virtual const unsigned short* GetRadarMap()=0;      //a square with value zero means you dont have radar to the square, this is 1/8 the resolution of the standard map
   virtual const unsigned short* GetJammerMap()=0;      //a square with value zero means you dont have radar jamming on the square, this is 1/8 the resolution of the standard map
   virtual const unsigned char* GetMetalMap()=0;         //this map shows the metal density on the map, this is half the resolution of the standard map

   virtual float GetElevation(float x,float z)=0;      //Gets the elevation of the map at position x,z

   virtual bool CanBuildAt(const UnitDef* unitDef,float3 pos)=0; //returns true if a given type of unit can be build at a pos (not blocked by other units etc)

   virtual float GetMetal()=0;            //stored metal for team
   virtual float GetMetalRate()=0;            // rate flow for metal
   virtual float GetEnergy()=0;            //stored energy for team
   virtual float GetEnergyRate()=0;            // rate flow for metal
   virtual float GetMetalStorage()=0;            //metal storage for team
   virtual float GetEnergyStorage()=0;            //energy storage for team
};


Top
 Offline Profile  
 
 Post subject:
PostPosted: 18 May 2005, 04:31 
User avatar

Joined: 08 Sep 2004, 21:59
Location: Qc, Canada
jouninkomiko wrote:
i thought about and determined that global and group ai's should be totally separate entities... if anyone has a compelling argument to oppose that, now's the time :)


If some callback functions would be useful in the group AI, I hope you'll add them there as well.


Top
 Offline Profile  
 
 Post subject:
PostPosted: 18 May 2005, 07:34 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
im going to add a means for the global ai to assign group ai's to... well, groups. sooooooon (its late, and my payment for being home from school is that i get to mow the lawn in the morning!)


Top
 Offline Profile  
 
 Post subject:
PostPosted: 19 May 2005, 10:11 
AI Coder
User avatar

Joined: 14 Sep 2004, 10:32
Location: Cookieland
Actually I think that groupAI and Global AI should be mergable if the coder wishes in whatever form they wish. Such is the need for variety and flexibility.

And Buggi, interesting that you keeping half closed half open but it sorta defeats the point to an extent. Eitherway best nto to revive that particular topic of discussion


Top
 Offline Profile  
 
 Post subject:
PostPosted: 20 May 2005, 03:03 

Joined: 26 Aug 2004, 07:11
Location: Virginia Tech
mergeable? like how? right now, the thing that makes sense is to enable a global ai to distribute commands to groups commanded by group ai's, and give them a means to share a memory space.


Top
 Offline Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 214 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: Bing [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group

Site layout created by Roflcopter et al.