In this lesson, you will learn how to prevent utility calculations from crushing your frame rate by implementing caching and update throttling for your AI decision-making systems.
When you have dozens of NPCs constantly calculating utility scores for every possible action, the CPU cost adds up quickly. If an NPC evaluates five different actions—each involving complex distance checks, sensory fusion, and normalized curve lookups—sixty times per second, the performance overhead becomes significant. We can optimize this by decoupling the calculation frequency from the decision frequency.
Implementing Time-Sliced Updates
Instead of recalculating utility every frame, use a timer to throttle updates. By staggering the evaluation of different NPCs across several frames, you can keep the CPU load consistent.
private float _updateInterval = 0.2f; // Update every 200ms
private float _timer;
void Update() {
_timer -= Time.deltaTime;
if (_timer <= 0) {
EvaluateUtility();
_timer = _updateInterval;
}
}
Leveraging Cached Results
Some utility factors, like a "Health Percentage" or "Distance to Home Base," don't change every single frame. If you have multiple evaluators relying on the same sensory data (like the Blackboard system we discussed earlier), cache the result for the duration of the frame.
Calculate the raw input once at the start of the EvaluateUtility method, store it in a local variable, and pass that reference to your various response curves. This avoids redundant arithmetic operations. Furthermore, if the world state hasn't changed significantly (i.e., the relevant sensory variables in your Blackboard remain within a specific delta), you can skip the full evaluation entirely and reuse the previous score.
By combining throttling (controlling when to update) with result caching (minimizing what to calculate), you ensure that your utility system scales linearly with your NPC count rather than exponentially. This keeps your game simulation smooth even when the population density increases.
Key Takeaway: To optimize utility evaluators, decouple decision timing from frame rate via timers and store redundant sensory data in local variables to prevent unnecessary re-calculation during a single update cycle.