Ai
by J L · in Combat Starter Kit · 12/09/2008 (2:32 pm) · 23 replies
Was all the AI stuff stripped out ? Cause I was wanting to add bots in game and there is like no AI stuff at all it seems
About the author
#2
12/09/2008 (11:17 pm)
Yea we don't really have any ai in the kit. I have added both the ai guard and ai patrol resources in a game I'm working on. They work fine in CSK. Even the updated ai stuff for the aiplayer file works alright.
#3
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=15320
12/10/2008 (6:16 am)
Wow, this is going to bve a pain trying to put it back in without breaking a bunch of stuff. I was looking at this resource here but with so many different things that are ripped from the scripts there is no way a noob like me can do this and not break something contantly.www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=15320
#4
12/10/2008 (7:46 am)
Nothing was removed by the CSK that was essential that I can see, only the stock AIplayer script. You will have to make allowances for differences in the scripts just like you would for every resource out there. The AI that came with Torque really isn't anything special - all it does is follow a path that you defined in the editor. You've got your SDK so that means you still have the example of stock Torque, compare what is different and then made the needed adjustments. There is no resource here that was ever designed to work without conflit with the CSK - though many of them do. That resource pretty much gives you a drop in replacement for it the scrpted AI that will attack, chase, and defend. That would actually be a simple addition since there are no source code modifications in that resource.
#5
With this-
here is what it is in the CSK
So I looked it oiver and its some funky changes in my eyes, remember I am not that good at this....... YET I am just confused as to how it would be replaced into the CSK withpout me breaking something, and if there is a certain order stuff needs to be in or not.
edited for spelling
12/10/2008 (10:49 am)
The part that is confusing me the most is step 2 in that resourceQuote:2. In the file player.cs function Armor::damage() replace this-
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (%obj.getState() $= "Dead")
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);With this-
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (%obj.isbot == true)
{
%obj.attentionlevel=1;
%obj.enhancefov(%obj);
}
if (%obj.getState() $= "Dead")
{
if (%obj.isbot == true)
{
if (%obj.respawn == true)
{
%obj.delaybeforerespawn(%obj.botname, %obj.marker);
%this.player=0;
}
}
else
{
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
}
}here is what it is in the CSK
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
if (%sourceObject.client)
%sourceClient = %sourceObject.client;
else
%sourceClient = %sourceObject;So I looked it oiver and its some funky changes in my eyes, remember I am not that good at this....... YET I am just confused as to how it would be replaced into the CSK withpout me breaking something, and if there is a certain order stuff needs to be in or not.
edited for spelling
#6
What I did was break the addition to the ::damage() function into two parts. The if (%obj.isbot == true) is a self contained branch that can be placed just about anywhere - all it does is set a few "sense" variables if the bot takes damage, and the if (%obj.getState() $= "Dead") needs to be merged with the existing if statement.
12/10/2008 (11:41 am)
Ok I can see where you would be confused, but it's really only a simple addition. You'll break it up into two parts. I think the part that's throwing you off is where the resource says:%sourceClient = %sourceObject ? %sourceObject.client : 0;and the CSK says
if (%sourceObject.client)
%sourceClient = %sourceObject.client;
else
%sourceClient = %sourceObject;That's just two different ways of saying the same thing. Not many people understand the ? : conditional syntax. The if/else statements is probably easier to read and understand.What I did was break the addition to the ::damage() function into two parts. The if (%obj.isbot == true) is a self contained branch that can be placed just about anywhere - all it does is set a few "sense" variables if the bot takes damage, and the if (%obj.getState() $= "Dead") needs to be merged with the existing if statement.
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
if (%sourceObject.client)
%sourceClient = %sourceObject.client;
else
%sourceClient = %sourceObject;
// adv guard ai addition begin
if (%obj.isbot == true)
{
%obj.attentionlevel = 1;
%obj.enhancefov(%obj);
}
// adv guard ai addition end // - could have gone after the friendly fire section
// friendly fire handling. type = Override used to bypass friendly fire settings
if (%damageType !$= "Override")
if (%sourceClient.team.teamid == %client.team.teamid)
if (%sourceClient != %client)
if ( $Game::FriendlyFire == false)
{
echo("Ignoring friendly fire");
return;
}
%obj.applyDamage(%damage);
if (%obj.getState() $= "Dead")
{
%obj.disableCollision();
// advanced guard ai addition begin
if (%obj.isbot == true)
{
if (%obj.respawn == true)
{
%obj.delaybeforerespawn(%obj.botname, %obj.marker);
%this.player = 0;
}
}
else // advanced guard ai addition end
%client.schedule(0, "onDeath", %sourceObject, %sourceClient, %damageType, %location);
}
#7
12/10/2008 (2:02 pm)
Ok using that code there I get this error, i click on load mission and it shows about one second of loading bar and then i get a CTDsystem/server/scripts/player.cs Line: 978 - parse error
>>> Advanced script error report. Line 978.
>>> Some error context, with ## on sides of error halt:
%obj.delaybeforerespawn(%obj.botname, %obj.marker);
%this.player = 0;
}
}
else // advanced guard ai addition end
%client.schedule(0, "onDeath", %sourceObject, %sourceClient, %damageType, %location);
}
function Armor::onDamage(%this, %obj, %delta)
##{##
// This method is invoked by the ShapeBase code whenever the
// object's damage level changes.
if (%delta > 0 && %obj.getState() !$= "Dead") {
// Increment the flash based on the amount.
%flash = %obj.getDamageFlash() + ((%delta / %this.maxDamage) * 2);
>>> Error report complete.
Compiling system/server/scripts/aiPlayer.cs...
Loading compiled script system/server/scripts/aiPlayer.cs.
Compiling system/server/scripts/aiPlayerDatablocks.cs...
Loading compiled script system/server/scripts/aiPlayerDatablocks.cs.
#8
12/10/2008 (2:34 pm)
Make sure that you have the closing brace for function Armor::damage(). I think you might have missed it because that's usually what it means when you get a parse error on a starting brace.
#9
12/10/2008 (3:33 pm)
Yep, thats what it was, thank you very much sir, now I just gotta tweek settings
#10
12/10/2008 (3:51 pm)
Oh goodness I want to use a different thing for a bot but when I goto change the shape I have the other stuff for the CSK there. ANy suggestions ?datablock PlayerData(PlayerBody)
{
//renderFirstPerson = true; //Ari's FPS Hack
renderFirstPerson = false;
emap = true;
useWeaponBackFraction = "1";
className = Armor;
[b]shapeFile = "~/data/shapes/players/player.dts";[/b]
cameraMaxDist = 3;
computeCRC = false;
#11
Are you wanting to change the equipment for the bots?
Do you want multiple types of bots?
It's probably not obvious until you gain more experience with Torque, but what the CSK does for the player's is set up an inheritance layout for the teams and classes. Your bots can be derived from any of these different classes/armors.
No working code this time - more of an explanation. You'll be better served once you understand - trust me.
You have the default PlayerBody. That's your main datablock that every player-type shares and inherits "traits" from. Under that you have the two teams:
PlayerTeam1 and PlayerTeam2 are the new datablocks. They look kind of empty compared to that first one don't they? The : symbol in the datablock name means that these two new datablocks also share all of the fields from the default PlayerBody. In these secondary (children) datablocks you only need to add the fields that you wish to be different from the default in these cases the teamID and the shapefile for each team. That gives you two player bodies - one for each team.
The classes/armors are a further continuation of this idea.
Do you see the pattern there? You want to do things this way in order to keep from duplicating the same code over and over. Instead of trying to find one specific field among dozens of huge datablocks, you can instead set up your datablocks to inherit from a parent class to make it easier to keep track of only the necessary changes.
If you look at the AIplayer datablock from the resource you'll see a similar system.
Knowing this you should be able to take the existing team/class datablocks and derive any number of different bots.
This script inheritance feature can be used in a lot of different places, in fact the CSK does make use of it in several areas. It's the difference between clean, well laid out code versus a copy/paste cobbled together mess.
12/10/2008 (11:42 pm)
Are you wanting to change the shapefile for the bots? Are you wanting to change the equipment for the bots?
Do you want multiple types of bots?
It's probably not obvious until you gain more experience with Torque, but what the CSK does for the player's is set up an inheritance layout for the teams and classes. Your bots can be derived from any of these different classes/armors.
No working code this time - more of an explanation. You'll be better served once you understand - trust me.
You have the default PlayerBody. That's your main datablock that every player-type shares and inherits "traits" from. Under that you have the two teams:
datablock PlayerData(PlayerTeam1 : PlayerBody)
{
teamid=1;
shapeFile = "~/data/shapes/players/redplayer.dts";
// other team 1 specific stuff goes here
};
datablock PlayerData(PlayerTeam2 : PlayerBody)
{
teamid=2;
shapeFile = "~/data/shapes/players/blueplayer.dts";
// other team 2 specific stuff goes here
};PlayerTeam1 and PlayerTeam2 are the new datablocks. They look kind of empty compared to that first one don't they? The : symbol in the datablock name means that these two new datablocks also share all of the fields from the default PlayerBody. In these secondary (children) datablocks you only need to add the fields that you wish to be different from the default in these cases the teamID and the shapefile for each team. That gives you two player bodies - one for each team.
The classes/armors are a further continuation of this idea.
datablock PlayerData(PlayerBody1Class1 : PlayerTeam1){...}PlayerBody1Class1 is the name of the new armor/class datablock derived from the PlayerTeam1 datablock which was derived from the default PlayerBody datablock. Again you only need to list the fields that you wish to be different. In this case it's the equipment for the different classes. You could give each class different movement rates, footprints, mass, debris shape, etc, etc.datablock PlayerData(PlayerBody1Class2 : PlayerTeam1){...}PlayerBody1Class2 is the name of the new armor/class datablock derived from the PlayerTeam1 datablock which derives from the PlayerBody datablock.Do you see the pattern there? You want to do things this way in order to keep from duplicating the same code over and over. Instead of trying to find one specific field among dozens of huge datablocks, you can instead set up your datablocks to inherit from a parent class to make it easier to keep track of only the necessary changes.
If you look at the AIplayer datablock from the resource you'll see a similar system.
datablock PlayerData(DefaultPlayer : PlayerBody){...}; The DefaultPlayer is the name of the bot's datablock that derives/inherits from the PlayerBody datablock - the new (child) datablock only lists the differing fields from the parent datablock. Knowing this you should be able to take the existing team/class datablocks and derive any number of different bots.
PlayerData(AssaultBotTeam1 : PlayerBody1Class5){...};
PlayerData(SniperBotTeam2 : PlayerBody2Class1){...};You'll have to change your Ai spawn function to accommodate your new AI datablock names. This script inheritance feature can be used in a lot of different places, in fact the CSK does make use of it in several areas. It's the difference between clean, well laid out code versus a copy/paste cobbled together mess.
#12
Improved AI Guard Unit is one of the most feature-complete AI ive seen so far, works like a charm with CSK no problems yet, i'd also recommend the books by Ken Finney '3D Game Programming All-In-One' and 'Advanced 3D Game Programming All-In-One' as they helped me learn years of torque-ing in a matter of months (without Ken Finney's book i would have never known about Torque either!)
though the books are purely Torque-Script since the engine relies so heavily upon this it would still be very wise to consider!
12/26/2008 (4:43 pm)
@JasonImproved AI Guard Unit is one of the most feature-complete AI ive seen so far, works like a charm with CSK no problems yet, i'd also recommend the books by Ken Finney '3D Game Programming All-In-One' and 'Advanced 3D Game Programming All-In-One' as they helped me learn years of torque-ing in a matter of months (without Ken Finney's book i would have never known about Torque either!)
though the books are purely Torque-Script since the engine relies so heavily upon this it would still be very wise to consider!
#13
@CSMP
thanks for the book stuff, ordered already
12/31/2008 (7:34 am)
Ok, all my stuff is working, but there is no option in the shapes place for the aimarker when i am running the editor.@CSMP
thanks for the book stuff, ordered already
#14
1. Invalid ShapeFile for AIMarker
2. AIPlayer.cs script not being loaded
3. AIPlayer::LoadEntities(); Added to Game.cs inside of StartGame() function
12/31/2008 (6:27 pm)
I could only think of 3 problems off the bat, hopefully one helps.1. Invalid ShapeFile for AIMarker
2. AIPlayer.cs script not being loaded
3. AIPlayer::LoadEntities(); Added to Game.cs inside of StartGame() function
#15
}
function endGame()
12/31/2008 (10:05 pm)
Ok so, I am guessing this is still classifiedc as being in the StartGame()Function ? and I would have to add it between}
function endGame()
Quote:function startGame()
{
if ($Game::Running) {
error("startGame: End the game first!");
return;
}
// Inform the client we're starting up
for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
%cl = ClientGroup.getObject( %clientIndex );
commandToClient(%cl, 'GameStart');
// Other client specific setup..
%cl.score = 0;
%cl.teamid=0;
}
// Start the game timer
if ($Game::Duration)
$Game::Schedule = schedule($Game::Duration * 1000, 0, "onGameDurationEnd" );
$Game::Running = true;
// Start the AIManager
AIPlayer::LoadEntities();
$FlagsInitialized = 0;
TurnSpawners(RedFlagPole.trigger, 1);
TurnSpawners(BlueFlagPole.trigger, 2);
}
function endGame()
{
if (!$Game::Running) {
error("endGame: No game running!");
return;
}
// Stop the AIManager
AIManager.delete();
#17
that is the only errors I see related to the AI Guard code
01/02/2009 (9:21 am)
There is this error here, but I have the stuff right in my aiplayer.cs which is located below the quoteQuote:Loading compiled script system/server/scripts/aiPlayerDatablocks.cs.
system/server/scripts/aiPlayer.cs (89): preload failed for AIPlayerMarker: ShapeBaseData: Couldn't load shape "~systemshapessoldiersoldier.dts".
datablock StaticShapeData(AIPlayerMarker)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "AIMarker";
// Basic Item properties
shapeFile = "~\system\shapes\soldier\soldier.dts";
};that is the only errors I see related to the AI Guard code
#18
I seen what my problem was. I left "data" out of my path. It should have been in place of "system". God do I feel stupid :/
01/02/2009 (9:32 am)
Okay i corrected my shapeFile = "~\system\shapes\soldier\soldier.dts"; to reflect shapeFile = "~/system/shapes/soldier/soldier.dts";I seen what my problem was. I left "data" out of my path. It should have been in place of "system". God do I feel stupid :/
#19
Thats the only error that i can see that is related to the ai guard, I see the shapefile now, but he just stands there, and I can shoot through him. Also when I go into the map to select my team, it says
error unable to get teamid
01/02/2009 (9:36 am)
Arggh, ok now i get an errorQuote:Loading compiled script system/server/scripts/game.cs.
system/server/scripts/game.cs (233): Unable to find function AIPlayer::LoadEntities
Thats the only error that i can see that is related to the ai guard, I see the shapefile now, but he just stands there, and I can shoot through him. Also when I go into the map to select my team, it says
error unable to get teamid
#20
The AIMarker should have been hidden and respawned with AIPlayer given the LoadEntities is executed correctly.
P.S. if your getting TeamID errors then move the LoadEntities to before the very last closing bracket for the StartGame function, that might be why both of the bugs are happening!?
I only use the global variable for Debug AI on/off uses, in which i have a checkbox on the StartMissionGUI.
01/02/2009 (7:17 pm)
If you can shoot through kork then what you see should be the AIMarker (it will not move as it is a StaticShape).The AIMarker should have been hidden and respawned with AIPlayer given the LoadEntities is executed correctly.
P.S. if your getting TeamID errors then move the LoadEntities to before the very last closing bracket for the StartGame function, that might be why both of the bugs are happening!?
$FlagsInitialized = 0;
TurnSpawners(RedFlagPole.trigger, 1);
TurnSpawners(BlueFlagPole.trigger, 2);
if ($Pref::Server::EnableAI = "1")
{
AIPlayer::LoadEntities();
}
}I only use the global variable for Debug AI on/off uses, in which i have a checkbox on the StartMissionGUI.
Associate Michael Hall
Distracted...
Stock Torque AI is pretty lame anyway, most people add one of the many AI resources instead. I personally haven't combined the CSK with any AI but it's certainly possible if you make allowances for the changed code, you should at least be able to easily re-add the pathed AI bot.
Generally AI would be a custom solution from one project to the next. You have the source so anything is possible