AIPlayers running in circles starting in 3.6.2
by Adam Beer · in Torque 3D Professional · 12/02/2014 (6:10 pm) · 14 replies
I just updated my game to 3.6.2 last night in hopes of fixing some of the random crashes and instead it introduced another issue. AIPlayers are running in circles around the player object. I am calling setMoveDestination() on them with the targets position as the parameter and when they get relatively close I try to avoid them but instead they start running in a circle around me. This was not happening in 3.5 and there doesnt seem to be any changes to the AIPlayers move code or the Players. So what could be causing this? Were there any changes with the deeper math functions that could have caused this to break?
Note: I replaced the AIPlayer.cpp/h with 3.5's version and nothing changed so it seems that this is a deeper issue.
Note: I replaced the AIPlayer.cpp/h with 3.5's version and nothing changed so it seems that this is a deeper issue.
About the author
Adam is the owner of Ignition Games, an indie game and software development company.
#2
12/02/2014 (8:34 pm)
After some IRC discussion, swapping the math directory for 3.5'5, swapping the player.cpp/h for 3.5's and various other changes...no results on where this is coming from. Ill look into this more but for now I'm going to just revert my game back to 3.5 and try to debug the random crashes.
#3
12/02/2014 (11:46 pm)
Could we have a video or at least a script example so we can reproduce it?
#4
You can check this by calling AIPlayer.getPose() and it will return Sprint.
A quick hack-fix is to add
My guess is that this is a side effect of the recent changes to the move manager.
Also, sometimes, AIPlayers still do this!
12/03/2014 (12:15 am)
What's happening is that most of the time, AIPlayers are sprinting (notice how quickly they are moving now). When sprint is active, there's a DataBlock parameter called sprintYawScale which limits their turn rate. The result of this is that the AIPlayer cannot turn quickly enough to reach its moveDestination, and so continues to circle the moveDestination.You can check this by calling AIPlayer.getPose() and it will return Sprint.
A quick hack-fix is to add
%player.allowSprinting(false);to the AIPlayer::spawn function in AIPlayer.cs
My guess is that this is a side effect of the recent changes to the move manager.
Also, sometimes, AIPlayers still do this!
#5
Ill post up video later this afternoon.
12/03/2014 (6:06 am)
Where is the sprint pose being set though? I know in my code and script Im not setting any AI to sprint. Some AI go right toward me and some circle so where is this getting set?Ill post up video later this afternoon.
#6
I have not been able to get this to happen with either a debug or an optimized_debug build. With a release build, this happens frequently.
12/03/2014 (6:39 am)
It seems random, which makes me think that it is being set in the engine by some garbage memory somewhere.I have not been able to get this to happen with either a debug or an optimized_debug build. With a release build, this happens frequently.
#7
in AIPlayer.cpp, at the end of getAIMove, the move triggers are set in this loop:
MaxTriggerKeys is currently 6
The trigger for sprinting (sSprintTrigger) is 5
getImageTriggerState(int i) accesses the requested element of ShapeBase::mMountedImageList
ShapeBase::mMountedImageList is an array of size MaxMountedImages
MaxMountedImages is defined in shapeBase.h as 4
Therefore in AIPlayer::getAiMove, indices which are greater than MaxMountedImages are being used, and this exceeds the bounds of mMountedImageList, sometimes setting the value of sprint trigger depending on what happens to be in that memory location.
nasty.
12/03/2014 (8:20 am)
Did some hunting around, It's not the move manager.in AIPlayer.cpp, at the end of getAIMove, the move triggers are set in this loop:
for( S32 i = 0; i < MaxTriggerKeys; i++ ) movePtr->trigger[i] = getImageTriggerState(i);
MaxTriggerKeys is currently 6
The trigger for sprinting (sSprintTrigger) is 5
getImageTriggerState(int i) accesses the requested element of ShapeBase::mMountedImageList
ShapeBase::mMountedImageList is an array of size MaxMountedImages
MaxMountedImages is defined in shapeBase.h as 4
Therefore in AIPlayer::getAiMove, indices which are greater than MaxMountedImages are being used, and this exceeds the bounds of mMountedImageList, sometimes setting the value of sprint trigger depending on what happens to be in that memory location.
nasty.
#8
12/03/2014 (9:07 am)
You're my hero! What is your proposed change to fix this?
#9
I don't think that using the getImageTriggerState() in getAiMove is the appropriate way to do this. That function is supposed to get the trigger state of a mounted image, but is instead being used to set move triggers, which are completely different things.
It would be much better to expose this functionality to the console with a method such as AIPlayer::setTrigger(%triggerNum, %val). That would then make it easy to control shooting, alt-fire, crouch, prone sprint etc from script.
12/03/2014 (10:24 am)
For now, just use the allowSprinting(false) option.I don't think that using the getImageTriggerState() in getAiMove is the appropriate way to do this. That function is supposed to get the trigger state of a mounted image, but is instead being used to set move triggers, which are completely different things.
It would be much better to expose this functionality to the console with a method such as AIPlayer::setTrigger(%triggerNum, %val). That would then make it easy to control shooting, alt-fire, crouch, prone sprint etc from script.
#10
12/03/2014 (10:34 am)
Nice investigative work Guy! Anytime I read a posting and it ends with me smacking my forehead and thinking "Of course!" it's a good post. Excellent suggestion about the console methods too, I can see that being really useful.
#11
12/03/2014 (12:36 pm)
Nice work finding that. Wonder why it's started happening recently; I can't see any changes to related code. However that loop definitely needs fixing. AIConnection can do exactly what you propose with setTrigger, but it's been "deprecated" for years now. Maybe we should merge the remaining features it has into AIPlayer and get rid of it?
#12
I can add the trigger handling and make a pull request if you need someone to do it.
12/04/2014 (1:51 am)
I still sometimes use the AIConnection class, it's pretty useful for simulating connections to the server without needing to find real people to connect. You can set up simulated lag and packet loss on it, and get a feel for how that is going to affect things. But then, I still use fxShapeReplicators :)I can add the trigger handling and make a pull request if you need someone to do it.
#13
12/04/2014 (7:33 am)
I've submitted a pull request on GitHub for this. #1007
#14
12/04/2014 (1:32 pm)
Whoah when did we hit 1000? Thanks :).
Torque Owner Jesse Allen