Game Development Community

dev|Pro Game Development Curriculum

ChinaTown Ai Deathmatch with Recast Pathfinding Part ONE

by Steve Acaster · 03/23/2012 (4:38 pm) · 11 comments

First up, your going to need ChinaTown setting up --- so if you don't already have it, open the Torque3D FPS Tutorial and create the ChinaTown Project, then come back later.

--------------

Okay, so you have an FPS Tutorial created project. Now you need to include the Recast resource posted by Daniel Buckmaster, then come back later.

---------------

Righty-ho. You've now got everything that was need compiled, so let's start with some notes:

Save and save often!

The recast resource is basic recast (that's why it's a free resource! Just like this is a basic Ai deathmatch tutorial!) so it's not perfect - there is a slight offset to the grid, but it is bloody good, and Danny did a great job on the resource.

ChinaTown is a very intricate design with a number of tight alleys and small doorways ... all of which is very Ai unfriendly. It is very easy for Ai to get stuck, but I they do have an option to try and pick new routes when this happens, thus minimizing the number of times they'll get complete wedged and become totally immobile.

How We Want The Ai To Work:

The Game starts, the Player spawns in, the Ai Spawns in, and then it's a one-on-one deathmatch duel. When the Player is killed he auto-respawns and the same goes for the Ai.

----------------

For writing scripts you'll need some sort of script/text editor - I thoroughly recommend Torsion.

We need an Ai for an Ai Deathmatch, so create a new file "aiPlayer.cs" and place it in "art/datablocks".
In this new file we want to establish the Ai datablock, and take it from the DefaultPlayer.

//-----------------------------------------------------------------------------
// yorks new Ai Player
//-----------------------------------------------------------------------------

datablock PlayerData(DemoPlayer : DefaultPlayerData)
{
   shootingDelay = 200;
   maxInv[LurkerAmmo] = 30;//this should be auto but hey ...
};

And then exec that in "art/datablocks/datablockExec.cs".
//...

// Load the default player datablocks
exec("./player.cs");
exec("./aiplayer.cs");//yorks - under player

// Load the ambient sound datablocks
//...

We now have an Ai datablock derived from the Player Datablock. Next, we need to set up the game to make it appear.

Start up your FPS Tutorial Project and choose the "WorldEditor" button and then "ChinaTown Day" map so we can see what we are doing. Hit "Go" and load it all up.

Alt-C into freecam once it loads up so you can move about easier.

Delete any pre-set Turrets, we want this to be just man-versus-bot dueling.

Next make the Player start from end by repositioning "DefaultPlayerSpawnSphere" (found under PlayerSpawnPoints simgroup) to:
42 -45 1
The SpawnSphere should now be at the bottom of an alley.

Create a new simgroup (library -> level -> system -> simGroup) and call it "aiSpawnGroup". This will be the main group that the Ai will use for both randomized spawning and also randomized goal destinations.

We want to add a whole load of WayPoint into this so go around the map and add some - BUT BE CAREFUL - ChinaTown is a very "tight" map and Ai can easily get stuck, so try and avoid cramped interiors and the upper floors of buildings. Also don't put them too close to the ground or your spawning Ai could fall through. You don't need a million, 20 WayPoints will be fine. WayPoint can be found with SpawnSphere in (library -> scripted -> misc). Once you have a load in, if they're not inside "aiSpawnGroup" you want to select them all and drag them in.

Next up, let's create the pathfinding solution and add a "navMesh" from (library -> level -> navigation). If you don't have this group called "navigation", you haven't put the Recast resource in ... so why are you down here!? Go back up and follow the link and integrate it into your build.

Call this new NavMesh "theNavMesh". Set it's position and scale so that it covers the map. Set the filename to "levels/chinatown_day.nm". Check "saveIntermediates" and then "build". Wait for it to finish. Now you might want to play around with the various other settings, but remember Ai are going to have a really difficult time stepping over things and they can't jump, so Keep It Simples Stoopids.

Here's what I've used, your mileage may vary.
new NavMesh(theNavMesh) {
      saveIntermediates = "1";
      buildThreaded = "1";
      build = "0";
      fileName = "levels/chinatown_day.nm";
      borderSize = "1";
      cellSize = "0.3";
      cellHeight = "0.3";
      actorHeight = "2";
      actorClimb = "0.3";
      actorRadius = "0.3";
      walkableSlope = "38";
      detailSampleDist = "6";
      detailSampleError = "1";
      maxEdgeLen = "1086324736";
      simplificationError = "1.3";
      minRegionArea = "8";
      mergeRegionArea = "20";
      tileSize = "32";
      renderMode = "Navmesh";
      renderInput = "0";
      renderConnections = "0";
      position = "0 0 0";
      rotation = "1 0 0 0";
      scale = "70 80 20";
      canSave = "1";
      canSaveDynamicFields = "1";
   };

Now we need a "navPath" to use "theNavMesh" and for or Ai to run down. Again this is under (library -> level -> navigation) and you want to call this object "navPath1". In it's "mesh" field enter "theNavMesh" so it's linked to our navMesh.

If you haven't saved yet - slap with wet fish. Look inside your project's "game/levels" folder and check the new *.nm file exists. If not, save the level and it should appear.

Okay that's all we need to do with ChinaTown physically ... or at least virtually ... so you can close down T3D and open up your Torsion or your favourite script/text editor.

Create a new *.cs file called "aiPlayer.cs" and save it in "scripts/server". This will be where the script to spawn and control our Ai will be. Add this for exec'ing in "scripts/server/scriptExec.cs":
//...
exec("./proximityMine.cs");

// Load our default player script
exec("./player.cs");
exec("./aiplayer.cs");//yorks - under player

// Load turret support scripts
//...

I have commented the scripts, so read through them, it should explain itself ... allegedly ...

First up we need a method to spawn our Ai duelist, so create a new function which will spawn an Ai with the "DemoPlayer" datablock.

function AIPlayer::customAiSpawn(%spawn, %goal)
{
   // Create the demo player object
   %player = new AiPlayer()
   {
      dataBlock = DemoPlayer;
	  position = %spawn.getTransform();
   };
   MissionCleanup.add(%player);

	//are we moving to attack the player or are we moving towards a node
	%player.attack = 0;
	
	//are we stuck?
	%player.stuck = 0;
	
	//movement nodes
	%player.currentNode = 0;
	%player.targetNode = 0;
	
	//pause a moment to let behind the scene stuff work out
	%player.schedule(1000, "aiStartUp", %goal);
   
	//give the Ai a rifle
	%player.mountImage("LurkerWeaponImage", 0);
	
	return %player;
}

And then we'll use another function to randomly find a "Waypoint" inside of the "aiSpawnGroup" and call the customAiSpawn with the "Waypoint".

function RandomSpawn()
{
	if(!isObject(aiSpawnGroup))
	{
		echo("Y U NO HAVE AISPAWNGROUP!?");
		return;
	}
	
	%count = aiSpawnGroup.getCount();
	if(%count < 2)
	{

		echo("Y U NO HAVE MULTIPLE SPAWNSPHERES IN AISPAWNGROUP!?");
		return;
	}
	
	echo("Random Spawn is randomly spawning!");
	
	//get the max. index from the group. 
	//Index starts at 0 and not 1.
	//so we need to take 1 off the count
	%max = %count - 1;
	
	//randomize!
	%index = getRandom(0, %max);
	
	//get the spawnSphere from the simgroup at the index
	%spawn = aiSpawnGroup.getObject(%index);
	
	//give him another spawnSphere to aim for as a starting goal
	%okay = 0;
	while(%okay == 0)
	{
		//randomize!
		%ind = getRandom(0, %max);
		
		//check that they're not the same as his spawnSphere!
		if(%ind == %spawn)
		{
			//we randomly chose the same spawnSphere - loop!
		}
		else
		{
			//get the spawnSphere from the simgroup at the index
			%goal = aiSpawnGroup.getObject(%ind);
			
			//and get out of this loop
			%okay++;
		}
	}
	
	//and spawn!
   %player = AIPlayer::CustomAiSpawn(%spawn, %goal);
   echo("Spawning Ai " @ %player @ " at " @ %spawn);
   return %player;
}

Save this and restart ChinaTown. Once in, drop down the console and type:

randomSpawn();
With any luck an Ai will have randomly spawned at one of the WayPoints parented to "aiSpawnGroup". The console should reply to you:
echo("Random Spawn is randomly spawning!");
Spawning Ai (Ai ID number) at (waypoint ID number)
(Ai ID number)

Go into flymode and try and find your new Ai - he'll be stationary and unresponsive. It'll be easier to find him if you hide TsStatic in the Visibility Options dropdown.

The important thing is that he's there.

Next up, how to turn this dummy into this video:




Part Two

#1
03/26/2012 (1:49 am)
@Steve

I downloaded the recast resource files and tried to build the project, but I seem to missing a header file. "coverPoint.h". I did a searche through all the directories as well as the folders in the zip file. This header doesn't seem to exist anywhere. Have you got a link to this file anywhere?
#2
03/26/2012 (3:56 am)
Maybe some sort of reading of the instructions in the Recast blog might help ...
#3
03/28/2012 (11:16 am)
hey am i suppose to do the whole fps tutorial i am only asking because it makes a online game not a AI game setup if i am wrong
#4
03/28/2012 (12:32 pm)
Every T3D game is multiplayer - but some are actually designed that way. There is a large chunk of housekeeping that you don't need to worry about if you don't want to actually make your game fully support multiplayer, but it won't hurt if you've done it.

And completing the tutorial will help in the long run anyway because you will become more familiar with Torque 3D, torquescript and general programming and art procedures and methods.
#5
03/28/2012 (12:49 pm)
Brian, just create the Project for the FPS Tutorial, that way you get ChinaTown, you don't have to do the tutorial itself for this, but I'd advise doing it sometime as you will learn a lot.
#6
04/27/2012 (1:32 pm)
i don't have the update i am saving every penny i get btw i mean that i have $4 and 3 cents :( i don't get anything till my birthday or Christmas

the reason i asked is if i do need to do the tutorial i cant and another thing does it only work with the map? cause i don't have it

#7
04/27/2012 (2:02 pm)
Integrating Recast doesn't require anything more than what you have (except downloading Recast). Recast itself should work with any map that you have - it should generate walkmeshes for terrain and objects in your scene. The rest of Steve's instructions should also work on any map out there - placing spawn points, etc. are all core features. Then you'd just have to balance the placement of spawns, ammo, weapons, etc to your liking.

You can download the demo to complete the tutorial if you like - aside from a nag screen it's free. You won't be able to set it up to use the resource, but you can still learn plenty about T3D.
#8
04/27/2012 (6:11 pm)
dude china town is not in the demo
#9
04/28/2012 (12:13 am)
nvm i made it now i wish i had a better comp so glitchy what i don't understand is that this is a REPUBLIC OF GAMES laptop that my dad gave tons more memory too so why is it glitching
#10
11/13/2012 (2:30 pm)
I need RTS Toolkit and FGE(Flight Game Example).Also I need Aiflyingvehicle Class.pls send me any one can do.
Email:moj.heidari@yahoo.com
#11
02/02/2015 (9:24 pm)
Can you make an update version of this?