Game Development Community

Pathfinding on the kit at last

by Novack · in RTS Starter Kit · 02/07/2008 (6:04 pm) · 9 replies

Good news everybody, the immersive AI Engine, by Gavin Bunney and Tom Romano, has a fantastic pathfanding solution, and after some little work with it, I were able to port it to the RTS-SK (just the pathfinding).

Here is a pic:
tdn.garagegames.com/wiki/images/6/64/Grid2.JPGDoesnt look fantastic? :D

Here is the blog announcing it, and here is the TDN article with the downloads.

Any comments, feel free to post.

#1
02/18/2008 (9:54 am)
Hey i am trying to make buildable walls in my RTS and was wondering what peoples thoughts on using a pathfinding thing like this would be. I want to be able to click on one tower and then click on another tower and click build wall and it creates a wall between the two.

any thoughts on how to do that?
#2
02/18/2008 (10:09 am)
Brandon, I think the pathfinding point on that is the less important, at least from an initial aproach. First you need to implement the mechanics that actually makes what you want.

Though a generic extensible construction implementation (ala Age of Empires walls construction) would be very useful, there is still no devs working on it that I know about. I would recommend you to create a new thread on this forums, and see if we can contribute ideas, but take in mind its something that will requiere work.
#3
06/30/2008 (12:25 am)
First of great thing porting this to the RTSKit!

But I'm sorry to dig this (older) post up again, but I can't seem to get this compiled in Linux, this error keeps comming up:
--> Compiling immersiveAI/seek/path/iAIPathMap.cc
In file included from immersiveAI/seek/path/iAIPathGrid.h:23,
                 from immersiveAI/seek/path/iAIPathMap.h:23,
                 from immersiveAI/seek/path/iAIPathMap.cc:11:
immersiveAI/seek/path/iAIPathNode.h:51: error: 'iAIPathGrid' has not been declared
immersiveAI/seek/path/iAIPathNode.h:124: error: ISO C++ forbids declaration of 'iAIPathGrid' with no type
immersiveAI/seek/path/iAIPathNode.h:124: error: expected ';' before '*' token
make[1]: *** [out.GCC4.DEBUG/immersiveAI/seek/path/iAIPathMap.obj] Error 1

Anyone got this compiling under Linux? If so what order do you use in engine/targets.torque.mk as I think the problem might be there or otherwise in the order of inclusion of the header files.

Thanks for any help!

Greetings,

Arjan Gelderblom
#4
02/17/2010 (12:38 am)
The following is the successful merge of the RTS Kit + World Domination Mod + immersive AI port.

There were manual changes required to player.cs to get it to work with new logic.

function Player::onReachDestination(%this, %dest)
{
   echo("--------------------------------------");
   echo(" Player::onReachDestination status is (" @ %this.status @ ") and my current goal is (" @ %this.curGoal @ ")");
   
   %distance = VectorDist(%this.getPosition(), %this.curGoal);
   echo("Player::onReachDestination distance to curGoal (" @ %this.curGoal @ ") is (" @ %distance @ ")" );
   
   if ((%distance < 4.0) && (%distance > -4.0) && (!(%this.curGoal $= "")))
   {
      %this.curGoal = "";
      echo("Player::onReachDestination distance is less than 4.0 to current goal");
   }
   
   if (%this.status $= "Collecting" && %this.curGoal $= "")
   {
     %this.setActionThread("gather", true);
     echo("Player::onReachDestination--(" @ %this @ ") is currently collecting, scheduling collection in 2s.");    
     %this.collectResource(%this.collecting, 2000);
   }
   if (%this.status $= "Full" && %this.curGoal $= "")
   {
    //Gold.count +=  %this.currentAmt;
    echo("Player::onReachDestination-- (" @ %this @ ") is dropping off (" @ %this.resourceType @ ")");
    resourceStore::requestAddSupplies(%this.client, "LOCAL", "", %this.resourceType SPC %this.currentAmt, false);
    //resourceStore::SetSupply(%this.client, );
    %this.currentAmt = "";
    if (!(%this.resourcePos $= "" ) )
    {
      %this.setMoveDestination(%this.resourcePos);
      %this.curGoal = %this.resourcePos;
      %this.status = "Collecting";
      echo("Player::onReachDestination-- (" @ %this @ ") now moving to (" @ %this.resourcePos @ ")");

      return;
    }
    else
    {
      echo("Player::onReachDestination--peon caught trying to harvest at a spot that doesn't exist!");
      %this.setMoveGoal("");
      %this.status = "Idle";
      return;
    }
   }

   if(%this.curGoal $= "")
   {
      echo("Player::onReachDestination " SPC %this @ " - Arrived at current Goal!");
      return;
   }

   %nextWP = PathManager::getNextWaypoint(%this); //%this.getPosition(), %this.curGoal);
   
   if (%nextWP != -1)
	{
		%this.setMoveDestination(%nextWP);
		echo("Player::onReachDestination " SPC %this @ " - next waypoint = " @ %nextWP);
	} 
   else
   {
      %this.curGoal = "";
      echo("Player::onReachDestination" SPC %this SPC "has no more waypoints");
   }   
   
   echo("Player::onReachDestination - (" @ %this @ ") status=(" @ %this.status @ ") goal=(" @ %this.curGoal @ ")");
}

Feel free to remove all the echo statements -- they were just for debugging.

Since the iAI port changes how the units move, I had to add the distance check in ... or the units never realized they "arrive" at the resource to start collecting.
#5
02/18/2010 (6:13 pm)
Major problem however ... when trying to load a mission with a size over 720x720 (mission area defined to -360 -360 360 360 works ... but -360 -360 460 360 -- crashes)

It appears to be an issue with building the "Path Map" ... and casting rays.
-------------------------
Entering loadMission(starter.RTS/data/missions/mission2.mis, 1)
   Entering endMission()
   Leaving endMission() - return 48
   *** LOADING MISSION: starter.RTS/data/missions/mission2.mis
   *** Stage 1 load
   Entering clearCenterPrintAll()
   Leaving clearCenterPrintAll() - return 
   Entering clearBottomPrintAll()
   Leaving clearBottomPrintAll() - return 
   Entering buildLoadInfo(starter.RTS/data/missions/mission2.mis)
      Entering clearLoadInfo()
      Leaving clearLoadInfo() - return 
   Leaving buildLoadInfo() - return 
   Entering sendLoadInfoToClient(1608)
      Entering messageClient(1608, 10, , Test World 2)
      Leaving messageClient() - return 
      Entering messageClient(1608, 11, , mission 2)
      Leaving messageClient() - return 
      Entering messageClient(1608, 12)
      Leaving messageClient() - return 
   Leaving sendLoadInfoToClient() - return 
   Entering loadMissionStage2()
      *** Stage 2 load
      Executing starter.RTS/data/missions/mission2.mis.
      *** Mission loaded
      Entering GameConnection::loadMission(1608)
         *** Sending mission load to client: starter.RTS/data/missions/mission2.mis
      Leaving GameConnection::loadMission() - return 
      Entering onMissionLoaded()
         Entering pathfinding_Initialize()
            Immersive AI :: Seek :: Building PathMap...
            Fatal: (c:\...\engine\ts\tsmesh.cc @ 1908) TSMesh::castRay (1)

edit: these details are thanks to adding "trace(true)" to my init.cs script ... has been very helpful with script debugging already.

#6
02/18/2010 (6:18 pm)
This is what 1908 in tmesh.cc looks like;
S32 startPlane = frame * planesPerFrame;
   for (S32 i=startPlane; i<startPlane+planesPerFrame; i++)
   {
      // if start & end outside, no collision
      // if start & end inside, continue
      // if start outside, end inside, or visa versa, find intersection of line with plane
      //    then update intersection of line with hull (using startTime and endTime)
      F32 dot1 = mDot(planeNormals[i],start) - planeConstants[i];
      F32 dot2 = mDot(planeNormals[i],end) - planeConstants[i];
      if (dot1*dot2>0.0f)
      {
         // same side of the plane...which side -- dot==0 considered inside
         if (dot1>0.0f)
            // start and end outside of this plane, no collision
            return false;
         // start and end inside plane, continue
         continue;
      }

      AssertFatal(dot1/(dot1-dot2)>=0.0f && dot1/(dot1-dot2)<=1.0f,"TSMesh::castRay (1)");
#7
02/18/2010 (6:43 pm)
How do I debug this more ? Is there a way to determine where its making this call in script ... and what it is trying to pass to the CC code ?

#8
02/18/2010 (7:24 pm)
Im looking into the iAIPathMap.cc ... and see where it prints the "Building PathMap..." line and what follows.

I see this line here and am curious -- it adds the numbers but some are negative so may have un-intended effect.
// set grid points are the initial mission area points in x&y to the extent of the mission area
   Point3F gridStart = Point3F(missionAreaPtr->getArea().point.x, missionAreaPtr->getArea().point.y, 100.0);
   Point3F gridEnd = Point3F(missionAreaPtr->getArea().point.x + missionAreaPtr->getArea().extent.x, missionAreaPtr->getArea().point.y + missionAreaPtr->getArea().extent.y, 100.0);

What if X=-360, Y=-648 and Extent.x =720, extent.y=1296

Will adding those have the desired effect ?
#9
02/20/2010 (2:36 am)
The trace(1) function helped resolve it -- just added it to the server init.cs and oddly enough, no more errors loading today.