Game Development Community

AIPlayer::singleShot and AIPlayer::fire freeze the engine

by Guy Allard · in Torque 3D Professional · 12/04/2014 (6:57 am) · 11 replies

On a brand new clone of the development branch.

Compile a release build.

Start the game.

Choose empty room.

pull down the console and spawn an aiplayer using
$bob=aiplayer::spawn(playerdroppoints);

stop him spinning wildly
$bob.stop();

Give him some hardware
game.loadout($bob);

Fire
$bob.singleshot();

At this point the game locks solid.

There's a post from 2010 here describing the same issue.

#1
12/04/2014 (7:04 am)
I'm thinking the firing method used in the RTS Prototype is a workaround for this. I'm not in a place where I can look; are those engine methods on the AIPlayer class?
#2
12/04/2014 (7:09 am)
I've always just set the shapeImage triggers myself, but was just seeing if some of my changes broke anything, and stumbled across this. Those methods are part of the AIPlayer script, and appear not to have worked correctly for a long time.

It's the schedule part of the function that is locking the engine, but I haven't figured out why.
#3
12/04/2014 (5:21 pm)
Interesting. I have run into this when I have my 'think' cycles set to high using a 'stock/custom' AI solution.

This issue might be a high-bred of that. Based on the code, you never tell the AI to stop or target or 'if no target' move on. Therefore, the AI gets stuck in a perpetual loop and eats up all the allocated memory, thus.... crash. Granted I am just basing this on the script posted but, think compute cycles, You AI is ALWAYS firing but, at what?

Just some 'ama-scripter' ideas. I am probably wrong.

Ron
#4
12/04/2014 (5:48 pm)
@richard: github.com/GarageGames/Torque3D/blob/69838bdc8c9bc055b9b1ae76f42b0f28d2a33909/Te... script.

Recall there was a goto embeded in the shapebaseimmage that was causing severe lockups like described, but that was quite a while ago... might be a similar issue though... I can say this end, been using a scheduled:

//actions
function AIPlayer::aiShoot(%this)
{
	if(!isObject(%this)||(%this.getState() $="Dead")) return;
	if(!isObject(%this.enemy)||(%this.enemy.getDamageState() !$="Enabled")) return;
	if(%this.canfire)
	{
      %this.setImageTrigger(0, true);
	}
   if (%this.getDatablock().rof)
      %Rof = (1/%this.getDatablock().rof);
   else
      %Rof = 1000;		
   %this.schedule(%Rof,"lockOutWeapon",true, %Rof);
}

function AIPlayer::lockOutWeapon(%this,%flag,%duration)
{
	cancel(%this.lockoutTime);
	%this.canfire = !%flag;
   
	if(%flag)
   {
      %this.setImageTrigger(0, false);
      %this.lockoutTime = %this.schedule(%duration,"lockOutWeapon",false,%duration);
   }
}

So perhaps it's that trigger down/up in quick succession causing a similar short-out?
#5
12/04/2014 (6:03 pm)
Yeah, that looks like it - I think I always schedule the trigger off for 32ms later, but I'd have to look to be sure.
#6
12/04/2014 (6:04 pm)
Will dig into it tonight. Oh wait, is this release only?

EDIT: Reproduced in development. Turns out scheduling an infinite loop is a bad idea:
%this.trigger = %this.schedule(%this.shootingDelay, singleShot);
%this.shootingDelay is "", which is parsed as 0, so you cause an infinite event loop. I didn't think events were processed immediately if you scheduled them with 0 time, but apparently they are.

Solution: why is singleShot firing multiple shots?
#7
12/05/2014 (12:10 am)
It should be using %this.getDatablock().shootingDelay, as the DemoPlayer datablock defines shootingDelay=2000

I just looked back through my old torquestuff stash, this eror was introduced with TGEA 1.7.0, and is also present in TGE1.5.2
#8
12/05/2014 (12:49 am)
It should also have a fallback in case there is no shootingDelay (say 1000ms), and I would question the logic of a function called singleShot creating an infinite stream of shots. That should be called continuousFire or something.
#9
12/05/2014 (3:57 am)
Would say fallback to wherever github.com/GarageGames/Torque3D/pull/1001 ends up. Not much point in having bots pulling triggers quicker than they can network.
#10
12/05/2014 (9:09 am)
Quote:
Turns out scheduling an infinite loop is a bad idea
i.imgur.com/XYcSrtZ.jpg
#11
12/05/2014 (5:08 pm)
Fixed in #1012. I will make a follow-up to rename singleShot, as it's inaccurate at the moment. I think calling singleShot should just fire once, whereas calling fire(true) should display the current behaviour. That fix will go into 3.7.