How To Make AI Discussion
by Bryce · in Technical Issues · 11/04/2004 (2:44 pm) · 156 replies
I'm making a game called Metal vs. Flesh and I cant figure out how to make AI players.
#142
in function NPF(%srcid, %tgtid)
you have
%srcindx=GetNavNodeIndex(%srcid);
but then later you use it with the spelling
NavNodeSet.getobject(%srcindex).parent = -1;
extra 'e' means we are referencing the wrong object
03/26/2005 (3:02 pm)
One more:in function NPF(%srcid, %tgtid)
you have
%srcindx=GetNavNodeIndex(%srcid);
but then later you use it with the spelling
NavNodeSet.getobject(%srcindex).parent = -1;
extra 'e' means we are referencing the wrong object
#143
%node should probably be %targetobject.
The code works the way it is though, because you never refer to the nodes as objects. All the function does is create a list of nodes and their distances, sorts the distances to the shortest and displays that distance.
So the code doesn't care which value you put - because it doesn't really do anything with the information - that's probably why it slipped past.
03/26/2005 (3:05 pm)
You know what, I believe you are right.%node should probably be %targetobject.
The code works the way it is though, because you never refer to the nodes as objects. All the function does is create a list of nodes and their distances, sorts the distances to the shortest and displays that distance.
So the code doesn't care which value you put - because it doesn't really do anything with the information - that's probably why it slipped past.
#144
This was just a case of sloppiness on my part.
The code would work though - but as I recall I had to throw some extra error trapping in the code to build the path - to account for this.
Now I guess it makes sense why I had to do so.
Thanks. I'll put those changes in the code when I'm back at my desk with the files and re-load them to GG.
Mark
03/26/2005 (3:22 pm)
And again, I believe you are correct.This was just a case of sloppiness on my part.
The code would work though - but as I recall I had to throw some extra error trapping in the code to build the path - to account for this.
Now I guess it makes sense why I had to do so.
Thanks. I'll put those changes in the code when I'm back at my desk with the files and re-load them to GG.
Mark
#145
ahh I see thanks.
03/26/2005 (3:46 pm)
Quote:The code works the way it is though, because you never refer to the nodes as objects. All the function does is create a list of nodes and their distances, sorts the distances to the shortest and displays that distance.
ahh I see thanks.
Quote:Thanks. I'll put those changes in the code when I'm back at my desk with the files and re-load them to GG.very welcome glad to help. thanks again for this,I'll let you know if I find anything else. I plan on working with this a lot more in the next few days.
#146
here's a small thing:
warning some variable names have been changed for my game...just the pathArray I think.
This detects the special case when the closest node to the target and the source is the same node.
in SetBotPath(%bot, %tgt)
right after
add the following quick check and early exit
without that it was going into NPF and then ending up at the bottom of the function where you have the comment
03/29/2005 (12:27 am)
@Markhere's a small thing:
warning some variable names have been changed for my game...just the pathArray I think.
This detects the special case when the closest node to the target and the source is the same node.
in SetBotPath(%bot, %tgt)
right after
if(%srcid==-1 || %tgtid == -1)
{
%bot.ai_pathArray.add(%bot.getposition,0);
error("bot did not find good nodes to build path=");
error("bot: "@%bot@", target: "@%tgt);
return;
}add the following quick check and early exit
//quickCheck for simple one node to target
if(%srcid == %tgtid)
{
//just tack on this node and the real target pos and return the path
%bot.ai_pathArray.add(%srcid.getposition(),0);
%bot.ai_pathArray.add(%tgt.getposition(),1);
return;
}without that it was going into NPF and then ending up at the bottom of the function where you have the comment
Quote://We should never really reach here.
#147
if your' interested I can go into details. required only minor script changes for the most part. the only larger thing I had to change was the code that initially spawns the bots. since the InitContainerRadius you were using doesn't detect the plain ole missionmarkers
oh hell I'll just go into details...here's an example
you will need to make the following slight change...
in server\scripts\markers.cs
make the default in the create switch be
now you can add these missionmarkers and make new ones for whatever nefarious purposes you may have.
Here is some of my boot strapping code to load the AI's based on the markers instead of the container radius search
here's an example of an initial call
oh and in case I haven't said it enough Thanks Mark for your resource, it's helped immensely get the ai fires burning for me.
03/29/2005 (12:36 am)
Another thing I changed you might be interested was instead of using static shapes for AI spawn placeholders, I used custom mission Markers. These are theoretically lighter weight, and automatically hide themselves when not in the editor. just like a spawnsphere or path marker.if your' interested I can go into details. required only minor script changes for the most part. the only larger thing I had to change was the code that initially spawns the bots. since the InitContainerRadius you were using doesn't detect the plain ole missionmarkers
oh hell I'll just go into details...here's an example
datablock MissionMarkerData(AISheepSpawnMarker)
{
category = "AISpawners";
shapeFile = "~/data/uegMade/shapes/seeker/theseeker.dts";
};you will need to make the following slight change...
in server\scripts\markers.cs
make the default in the create switch be
default:
%obj = new MissionMarker() {
datablock = %block;
};
return(%obj);now you can add these missionmarkers and make new ones for whatever nefarious purposes you may have.
Here is some of my boot strapping code to load the AI's based on the markers instead of the container radius search
here's an example of an initial call
echo("AI loading Sheep ----------------------------");
%num = AIPlayer::LoadAIEntities(MissionGroup, SheepBody, "AISheepSpawnMarker", "Sheep", 0);
echo("created "@%num@" Sheep");function AIPlayer::LoadAIEntities(%theSimGroup, %aiDataBlock, %markerDataBlock, %nameBase, %nextEntityNum)
{
//this searches for all markerDataBlock s
//and creates a aiDataBlock ai at that location;
//WARNING this is a recursive function, you call it the first time
// on your root group....for instance MissionGroup, then it will
// call itself again on any sub SimGroups it finds
%count = %theSimGroup.getCount();
for(%i = 0; %i < %count ; %i++)
{
%object = %theSimGroup.getObject(%i);
if( %object.getclassname() $= "MissionMarker")
{
if( %object.getDataBlock().getName() $= %markerDataBlock )
{
%nextEntityNum++;
%aiDataBlock.Spawn(%nameBase@%nextEntityNum, %object);
}
}
else if(%object.getclassname() $= "SimGroup")
{
//recurse here
%nextEntityNum = AIPlayer::LoadAIEntities(%object, %aiDataBlock, %markerDataBlock, %nameBase, %nextEntityNum);
}
}
return %nextEntityNum;
}oh and in case I haven't said it enough Thanks Mark for your resource, it's helped immensely get the ai fires burning for me.
#148
When I set out to develop this resource I had no clue as to what the heck I was doing in Torque. So I just threw my limited knowledge into it to create a marker of some sort. So I just picked what I could make work at the time.
So I'm all for it if people can find ways to improve this resource.
Mark
03/31/2005 (5:45 pm)
Tres cool man, thanks.When I set out to develop this resource I had no clue as to what the heck I was doing in Torque. So I just threw my limited knowledge into it to create a marker of some sort. So I just picked what I could make work at the time.
So I'm all for it if people can find ways to improve this resource.
Mark
#149
04/01/2005 (6:27 am)
Is anyone else having trouble viewing Clint's code blocks? I'm using Windows XP Home on a friends Laptop and viewing the site with FireFox 1.0 ATM, I'll have to check it when I get home.
#150
04/01/2005 (7:38 am)
Yes, me too. i'm having an xp professional edition and using FireFox . i cannot test with iexplorer becouse of a last virus attack.
#151
04/01/2005 (7:52 am)
Working fine on my windows XP machine under firefox 10.2 and Ie6
#152
I'm using Firefox 1.0 and I saw some troubles right after I posted it too..still there it looks like. I tried moving some things around and double checked that the format tags were right, but it didn't help.
edit
ok, I moved the second codeblock to the top of that post, so you can see them both now. at least I can with my firefox setup.
04/01/2005 (11:11 am)
Hey the thread title changed, no wonder I couldn't find it the other day.I'm using Firefox 1.0 and I saw some troubles right after I posted it too..still there it looks like. I tried moving some things around and double checked that the format tags were right, but it didn't help.
edit
ok, I moved the second codeblock to the top of that post, so you can see them both now. at least I can with my firefox setup.
#153
04/04/2005 (8:29 pm)
The problem went away with Linux, go figure :)
#154
I was running some navnodes up the side of a mountain and mystified why they weren't conecting when obviously they should have been. I had a chain of orphaned nodes right next to eachother.
after tracking this down, it has to do with how you are doing the collisions.
you are colliding from position to position and if nothing is hit, saying they are connected.
This is a bit confusing since the position of the NavNode markers is about 1 meter below the center of the actual navnode you see in the editor. A possibly more intuitive approach would be to use the worldBoxCenter of the nodes. This means that the visual center of the nodes will be checked, which is more what I would expect.
the next thing that has to be changed for this to work is that when you get the collision results, you can no longer just say if foundobject == 0, you must now say if foundobject == 0 || foundobject ==targetobject
because you might be colliding with the node you are checking against, which is good since that's what we want to get to.
Another thing to do is to make sure that the sourceobject is listed as an ignore object in the call to containerRayCast
With these changes in place, things seem to be working more intuitively for me.
so in summary :)
1. use %obj.getWorldBoxCenter() instead of getPosition, or getTransform when deciding on a postion for the nodes
2. make sure the source of the collision is passed as the ignore object to containerRayCast
3. check the result against 0 _and_ the targetobject to see if we can get to the targetobject
I'm sorry if this was already discussed, I didn't search around, but wanted to share in case it hadn't been.
09/23/2005 (1:27 pm)
Ran into another issue today which I think will help some other people with this code.I was running some navnodes up the side of a mountain and mystified why they weren't conecting when obviously they should have been. I had a chain of orphaned nodes right next to eachother.
after tracking this down, it has to do with how you are doing the collisions.
you are colliding from position to position and if nothing is hit, saying they are connected.
This is a bit confusing since the position of the NavNode markers is about 1 meter below the center of the actual navnode you see in the editor. A possibly more intuitive approach would be to use the worldBoxCenter of the nodes. This means that the visual center of the nodes will be checked, which is more what I would expect.
the next thing that has to be changed for this to work is that when you get the collision results, you can no longer just say if foundobject == 0, you must now say if foundobject == 0 || foundobject ==targetobject
because you might be colliding with the node you are checking against, which is good since that's what we want to get to.
Another thing to do is to make sure that the sourceobject is listed as an ignore object in the call to containerRayCast
With these changes in place, things seem to be working more intuitively for me.
so in summary :)
1. use %obj.getWorldBoxCenter() instead of getPosition, or getTransform when deciding on a postion for the nodes
2. make sure the source of the collision is passed as the ignore object to containerRayCast
3. check the result against 0 _and_ the targetobject to see if we can get to the targetobject
I'm sorry if this was already discussed, I didn't search around, but wanted to share in case it hadn't been.
#155
08/22/2007 (8:29 pm)
Well, three years later (wow) I've finally got AI figured out. Check out some of my .plan files.
#156
3 years of WoW? That sounds about right :)
Anyways congratulations!
08/22/2007 (8:37 pm)
Holy Resurection Batman! We all thought this thread died years ago!3 years of WoW? That sounds about right :)
Anyways congratulations!
Torque Owner Clint S. Brewer
one problem: in navigation.cs
in the function UpdateNodePosition()
you have this chunk of code
if(%foundObject == 0) { //There was no obstruction so we're good to add this node as a child %dist= VectorDist(%client.player.getposition(),%targetobject.getposition()); %nodelist.add(%node, %dist); %i++; }I think you want to use %targetobject there instead of %node right?