Game Development Community

Immersive AI Engine by Gavin Bunney discussion

by Fyodor -bank- Osokin · in Torque Game Engine · 02/27/2007 (4:46 am) · 191 replies

Let's discuss the iAI engine here, not spamming the .blog is good :)

The first question - is it based on standard AIPlayer.cc from SDK?
May be it's written in documents, but I haven't read all of them yet..
#21
04/08/2007 (12:51 am)
In engine\immersiveAI\seek\path\iAIPathFind.cc
bool iAIPathFind::generatePath(iAIPathNode* startNode, iAIPathNode* goalNode, Vector<iAIPathNode*>& replyList, const bool smoothPath)
{
   PROFILE_SCOPE(iAIPathFind_generatePath);
change to
bool iAIPathFind::generatePath(iAIPathNode* startNode, iAIPathNode* goalNode, Vector<iAIPathNode*>& replyList, const bool smoothPath)
{
   PROFILE_[b]START[/b](iAIPathFind_generatePath);
then add "PROFILE_END();" just before any function returns.

After those profiler fixes, rinse and repeat for these functions
void iAIPathFind::smoothPath
iAIPathNode* iAIPathMap::getClosestNode
void iAIPathFind::resetNodeVariables

in engine\immersiveAI\seek\path\iAIPathGrid.cc add this line up at the top with the other includes
#include "dgl/dgl.h"
#22
04/08/2007 (1:07 am)
Now i'm just missing additions from iAIAgent and the console it seems
#23
04/08/2007 (1:38 am)
Ah crap! I just noticed banks version of the source code so all of my updates specific to the iAI files are redundant. Anyways I'm still having the same 23 errors relating to missing components from iAIAgent and Con.

p.s. The doc links from up at the top appear to be dead links now.
#24
04/08/2007 (2:42 am)
In engine\console\console.h at about line 473 add this
// New Immersion AI printer code
   void iAIMessagef(ConsoleLogEntry::Type type, const char *_format, ...);
   void iAIMessagef(const char *_format, ...);

then in engine\console\console.cc at about line 558 add these
void iAIMessagef(ConsoleLogEntry::Type type, const char* fmt,...)
{
   va_list argptr;
   va_start(argptr, fmt);
   _printf(ConsoleLogEntry::iAIMessage, type, fmt, argptr);
   va_end(argptr);
}

void iAIMessagef(const char* fmt,...)
{
   va_list argptr;
   va_start(argptr, fmt);
   _printf(ConsoleLogEntry::iAIMessage, ConsoleLogEntry::General, fmt, argptr);
   va_end(argptr);
}


then if you have the iAIGoalManager files in your project, strip them out

That was less work than I expected. Finally everything compiles. Have fun with this resource and sorry for all the posts!
#25
04/08/2007 (4:47 am)
Two more engine changes to enable some of the script functions

in engine\console\consoleLogger.cc at line 37 change this
static EnumTable::Enums logLevelEnums[] =
{
	{ ConsoleLogEntry::Normal,     "normal"  },
   { ConsoleLogEntry::Warning,    "warning" },
	{ ConsoleLogEntry::Error,      "error"   },
};

static EnumTable gLogLevelTable( 3, &logLevelEnums[0] );
to this
static EnumTable::Enums logLevelEnums[] =
{
	{ ConsoleLogEntry::Normal,     "normal"  },
   { ConsoleLogEntry::Warning,    "warning" },
	{ ConsoleLogEntry::Error,      "error"   },
	{ ConsoleLogEntry::iAIMessage,      "iAIMessage"   },
};

static EnumTable gLogLevelTable( 4, &logLevelEnums[0] );

also in engine\console\console.h change this
enum Level
   {
      Normal = 0,
      Warning,
      Error,
      NUM_CLASS
   } mLevel;
to this
enum Level
   {
      Normal = 0,
      Warning,
      Error,
	iAIMessage,
      NUM_CLASS
   } mLevel;

also the post above was edited to reflect this change
#26
04/08/2007 (11:50 am)
Hum, everything compiles now, but I still have difficulties to fathom how to make a navMesh and maybe even have it apear in cute blue lines like the screenshots...
#27
04/08/2007 (10:23 pm)
Still has problem:
Quote:Compiling...
iAIAgent.cc
iAIGoalManager.cc
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(64) : error C2039: 'setPreviousGoal' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(64) : error C2039: 'getCurrentGoal' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(65) : error C2039: 'setPreviousSolution' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(65) : error C2039: 'getCurrentSolution' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(68) : error C2039: 'setCurrentGoal' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(69) : error C2039: 'setCurrentSolution' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(112) : error C2039: 'getCurrentGoal' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(139) : error C2039: 'getCurrentGoal' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
\TGE1.5 SDK\engine\iAI\iAIGoalManager.cc(155) : error C2039: 'getCurrentSolution' : is not a member of 'iAIAgent'
../engine\iAI\agent\iAIAgent.h(31) : see declaration of 'iAIAgent'
iAIGoalLibrary.cc
#28
04/09/2007 (4:28 am)
@ skanda

Remove iAIGoalManager.cc and iAIGoalManager.h from the project. They are unfinished resources and can't compile.
#29
04/09/2007 (4:55 am)
@ Stephen
Thanks very much!
#30
04/12/2007 (6:27 am)
I have compiled iAI with the Torque Game Engine (1.4). There are a few problems running the script.

The script does not know the iAIMessage functions.
It has been inserted into the the c++ code per this topic in this forum post. iAIMessage is in the engine code.

There is a createRandomName function that is not supported. Not a real problem

The IAICC_AgentList is not supported
somekind of array with ids and names

I implement one of my characters and it did follow a path. Two agents following two different paths.
#31
04/12/2007 (8:16 am)
Excellent resource Gavin, i will be giving it a good look over once i get my house back in order here.
#32
04/30/2007 (12:44 am)
Hi. I've got this compiled and sorta working, very nice. I have a question though. It looks like the node graph is only being generated on the terrain. I want my AI to be able to navigate through and on interiors. Is there any existing support for this, was it a planned deature that didn't get implemented, or am I going to have to add it completely? I don't have a problem with that, you've already given me a huge jump start, I just want to know if I should be looking at anything in specific.

Conceptually, I was thinking of making a series of markers in the stage, ie designer placed nodes like the spawn points, and modifying the pathfinding to search for those markers and connect them to the terrain grid you auto generate.
#33
06/02/2007 (1:58 pm)
My ai couldn't find its own solution list until i changed line 92 of iAiagent.h from

const char* getAgentType() const { return this->mAgentType; }
to
const char* getAgentType() const { return mAgentType; }

Now it does something besides stand still and try to get a new goal every second.
#34
06/03/2007 (11:44 pm)
The patrolling bots never seem to attack each other or anything. Does anyone know anything about that before I start messing with their seek code and a hundred other things that could be at fault?
#35
06/09/2007 (8:58 am)
Anybody successfully gotten this to work on interiors? if not, I'll be working on it all day tomorrow and try to come up with something and post here.
#36
06/10/2007 (4:27 am)
Been working on this to see if I can at least get it functional. With the changes here in this thread I've gotten it to completely compile.

Problems:

Console says the grid is created, but I can't see any grid.
My agents are thinking, but coming up with nothing every time. (every time they think, they have to call iAIGoalManager.requestNewGoal(%this);, because there's nothing there previously).
They don't move around, they don't attack, they don't defend themselves, nothing.
#37
06/10/2007 (5:03 am)
Added a bunch of echo("whatever"); to my scripts to try and determine exactly where the script is going off-track.

Apparently it's never returning solutions.

Also, I'm finding that in the think function, it's only passing %this to requestNewGoal, when the function actually has 4 parameters.

For a test, I used echo on %agent (the second variable in the list). Sometimes it's echoing what it needs to...other times it's echo'ing leftover garbage from things like goals and other things. It makes no sense.

EDIT: %agent is echo'ing fine, it's actually %agent.getAgentType() that's screwing up. I'm thinking this has something to do with why it's not finding a solution

EDIT: oh, and for the record I'm using tge 1.5.2
#38
06/11/2007 (11:29 am)
Edited agent.getAgentType() so that it's now returning things like "sold" instead of things like "solgoHome haveFun"

But I'm still getting no solutions...still workin to track down the problem...

I'm not planning on dropping this straight into my project, but I would like to get it functional so that I can at least pull out a couple useful things. If I can't get it at least functional as-is, it'll probably be that much harder to merge part of it to my code. If I can get it working, then I know I can fully understand how it works and as such, use it appropriately in my own version.

If anything, I'd like to retain the pathfinding and A*...but I can't even tell that those are working. The script says the path map was successfully created, but I see nothing, and the characters won't move.
#39
06/11/2007 (3:50 pm)
Ok anyone whose bots aren't actually doing anything in the game can narrow down their problem by replacing the function iAIGoalManager::requestNewGoal in "server/scripts/immersiveAI/goals/iAIGoalManager.cs" with the expanded code below.

function iAIGoalManager::requestNewGoal(%this, %agent, %avoidCurrentGoal, %avoidCurrentSolution)
{
   // check valid parameters
   if ((!isObject(%agent)) || (%agent.getState() $= "Dead")){
      iaimessage(%agent," was not alive or valid while choosing a new goal.");
      return false;
   }

   // check if wanting to avoid the current goal
   %avoidWord = "";
   if (%avoidCurrentGoal == true)
      %avoidWord = %agent.currentGoal;
      
   // evaluate the agents goals
   %goal = %this.evaluateList(%agent, %agent.goalList, %avoidWord);

   // check goal found
   if (strlen(%goal) == 0){
      iaimessage(%agent," no new goal was found.");
      return false;
   }

   // get a list of solutions for the goal
   %solutionList = $iAIGoalLibrary.getSolutionList(%agent.getAgentType(), %goal);

   // check solution list found
   if (strlen(%solutionList) == 0){
      iaimessage(%agent," solution LIST for ai type ",%agent.getAgentType()," not found while choosing the new goal: ", %goal);
      return false;
   }

   // check if wanting to avoid the current solution
   %avoidWord = "";
   if (%avoidCurrentSolution == true)
      %avoidWord = %agent.currentSolution;

   // evaluate the solutions
   %solution = %this.evaluateList(%agent, %solutionList, %avoidWord);

   // check solution found
   if (strlen(%solution) == 0){
	  iaimessage(%agent," solution not found in solution list: ", %solutionList);
      return false;
   }

   // assign and execute the goal and solution to the agent
   %success = %this.assignGoal(%agent, %goal, %solution);
   if(%success)
      iaimessage("Successfully chose the new goal ",%goal," via solution ",%solution,"to the agent ",%agent);
   else
      iaimessage("Failed to assign the new goal ",%goal," or the solution ",%solution,"to the agent ",%agent);
   return (%success);
}

Also make sure you followed my above posts about getting iAIMessagef to work, and if you haven't yet enabled the message function in torquescript yet just add this
ConsoleFunction(iaimessage, void, 2, 0, "iaimessage(text [, ... ])")
{
   U32 len = 0;
   S32 i;
   for(i = 1; i < argc; i++)
      len += dStrlen(argv[i]);

   char *ret = Con::getReturnBuffer(len + 1);
   ret[0] = 0;
   for(i = 1; i < argc; i++)
      dStrcat(ret, argv[i]);

   Con::iAIMessagef("%s", ret);
   ret[0] = 0;
}
to "engine\console\consoleFunctions.cc". I would also recommend changing the print color of iAIMessagef to something unique if you plan on using it much. I made mine green by by adding this line to "engine\gui\controls\guiConsole.cc" around line 101.
case ConsoleLogEntry::iAIMessage:  dglSetBitmapModulation(ColorF(0.0f,0.7f,0.0f)); break;
and in "engine\console\consoleLogger.cc" around line 42 I changed this
static EnumTable::Enums logLevelEnums[] =
{
	{ ConsoleLogEntry::Normal,     "normal"  },
   { ConsoleLogEntry::Warning,    "warning" },
	{ ConsoleLogEntry::Error,      "error"   },
};

static EnumTable gLogLevelTable( 3, &logLevelEnums[0] );
to this
static EnumTable::Enums logLevelEnums[] =
{
	{ ConsoleLogEntry::Normal,     "normal"  },
   { ConsoleLogEntry::Warning,    "warning" },
	{ ConsoleLogEntry::Error,      "error"   },
	{ ConsoleLogEntry::iAIMessage,      "iAIMessage"   },
};

static EnumTable gLogLevelTable( 4, &logLevelEnums[0] );

The recommendations in the post are what helped me diagnose the first problem of getAgentType() returning the wrong value. The fix for that is in my second to last post above. That fix got the pathfinding working and my bots explore around, but they still don't defend or attack anything even when they're set to patrol, which I believe to be entirely script related but there's a lot of functions between patrolling and and actually hunting a target that could be at fault so it will take a while for me to determine where its broken.
#40
06/11/2007 (4:04 pm)
Above you mentioned changing the code to use proper profile blocks. One simple error though:
return closestNode;
	PROFILE_END();
}
needs to be changed to
PROFILE_END();
	return closestNode;
}
as you must end a profile before returning from the funtion. Otherwise the profile block is invalid.