Reduce cpu usage of AI controller?

The code behind the AiController (or Controller) it seems is mostly hidden in native code. I have many AI on my map, and I’d like to know if there is any way to reduce the system resources that are being used.

I’ve tried playing with SightCounterInterval (which is how often player visibility is checked), but that doesn’t seem to have any noticeable affect on cpu usage. Does anyone know what is happening that is so expensive in Controller?

did you try profiling it with the GameplayProfiler? having many AIs also adds quite some cost in the form of Pawns so it would be good to identify what is causing it (and even if it’s the AI code, which functions are responsible for it).

In my case and as described by CobaltUDK in his thread, I do a distance-based optimization where I send the AI to a basic sleeping state and disable / early-return a lot of the Pawn functions

If you have lots of AIControllers on the map, then probably what’s taking up all the time is the world tick. You should use the gameplay profiler to find out if there’s anything your game is spending a lot of time on, but it’s probably just a matter of having lots of AIControllers that all need to tick, even if they’re not doing anything especially time-consuming.

What you might want to consider is only spawning controllers for the pawns that actually need to be controlled. If your player isn’t going to see or interact with the pawns, then those pawns don’t need controllers. Or at the very least you should give them states that involve a lot of sleep between functions.

I ran into that issue a few months ago. I tested 5,000 pawns in my game, and that started off completely unplayable. I was getting something below 0.5 fps with a quad-core i5 and a GTX 750. With some optimization, I was able to get that up to about 20 fps. In the end I still had to limit the number of pawns that are actually in play at any time to keep the fps above 30, but you might be surprised at what UDK can handle.

Some optimizations to try out: Don’t give pawns controllers unless they’re actually needed. Check the pawns’ last draw time to see if they’re on-screen and need to be doing something, and if they’re off screen, let them slack off. Make use of MoveSmooth instead of MoveTo whenever possible. Use sleep() liberally to time things instead of checking for stuff on every tick.

Edit:

Question for you all: Do any of you happen to know if sleeping actors still tick? If they don’t continue to tick, then sleeping on its own would be an optimization, to remove actors from the world tick cycle when not needed. But anyway, at the very least, instead of doing stuff every tick, you can still have states that sleep for a while between doing that stuff.

I send the far pawns to a sleeping state, as said. That works well, but I want to destroy them and re-spawn, because with 1000 bots in the map still is a bit slow even in the sleeping state.

But I have seen a big difference when the pawns are not moving. I think that the bottleneck is in the move* latent functions. I want to do a test moving some pawns using “moveto”, and the same but moving them using acceleration in the tick event. I will test setlocation, move and movesmooth to see which is better. The setlocation method will needed some trace to the floor.

Perhaps the tick method is faster, and then is possible to make less robotic movements for the pawns. I will write in the forum the result, probably for the next month.

In my “sleeping state”, I use “setTickIsDisabled(true)” on the pawns. So only the controller is using tick (but is fast), checking regulary the distance to the player to awake the pawns. Also I need to hide the pawn (and their components and weapons) to get better results. And disable collisions.

Putting my AI to sleep is an option for some of them, but not all, as in my game to world continues regardless of the player (AI fight other AI and hunt, etc).

Just out of interest… what exactly are you doing (or bypassing) in your sleep state?

I’v also noticed that my pawns seem to as much resources as my controllers (even if their mesh is hidden).

I haven’t used the gameplay profiler yet. I will look into that. I fear that the optimizations required may be in the native code. Although there are usually always work-arounds using unrealscript.

This, once at the start of the sleep state:

Pawn.SetCollision(false,false);
Pawn.Mesh.SetHasPhysicsAssetInstance(false);
Pawn.SetPhysics(Phys_none);
MyPawnClass.mesh.bNoSkeletonUpdate=true;
if (Pawn.base == none || (Pawn.base != none && !Pawn.base.isa(‘InterpActor’)) ) { Pawn.SetTickIsDisabled(TRUE); } //mantain the tick if the pawn is moving, for example, in a ship in other place of the map
Pawn.SetHidden(true);

Probably with the settickisdisabled and the sethidden is enough, but I use all for si acaso.

Also the state has this ignores:

ignores SeePlayer,NotifyPhysicsVolumeChange,NotifyLanded,NotifyHitWall,NotifyFallingHitWall,NotifyBump,CurrentLevelUnloaded,NotifyJumpApex,NotifyMissedJump,ReachedPreciseDestination,NotifyPathChanged,BeginAnimControl,SetAnimPosition,FinishAnimControl,PlayActorFaceFXAnim,StopActorFaceFXAnim,SetMorphWeight,SetSkelControlScale,PostBeginPlay,ReplicatedEvent,Possess,UnPossess,NotifyPostLanded,RatePickup,StopFiring,HearNoise,SeeMonster,EnemyNotVisible,SetupSpecialPathAbilities,MoveUnreachable,LongFall,MayFall,AllowDetourTo,MoverFinished,HandlePathObstruction,NotifyHeadVolumeChange,NotifyCoverAdjusted,IsSpectating,IsInCombat,InterpolationStarted,InterpolationFinished,SetTeam,touch,bump;

@CobalUDK You’re right that only SetTickIsDisabled() seems to be needed on the pawns. Toggling a disabled state on my AI pawns based on the distance from the player has given me around a 20% boost in fps (i’m very happy with the result).

Thanks for sharing your insight, really appreciate it.

Good… :slight_smile:

I did the tests, sending several bots to 3 diferent states, one using “moveto”, other using acceleration in the tick event, and other using “movesmooth” in the tick.

Performance using “moveto” and acceleration was practically the same.

Using “movesmooth” was about 10% faster, but because the animtree is ignored (pawns not animated when walking).

I am thinking about not using “moveto” and using instead the acceleration in tick method, because in this way I can add inertia to the movements and direction changes, instead the linear and robotic feel of moveto. But I need to rewrite a lot of code.