Optimization
Optimization is a heavy subject in Unreal. It is the root cause of most end-user "issues" and is often the area where players feel developers should have spent more time.
My goal here is to shed light on how to better optimize your projects from a systems-level perspective. As this section grows, this page will evolve into a directory for more specific sub-folders, but the URL will remain the same.
When Should You Look at Optimization?
There is a common mantra in development: "Don't optimize early." This usually means you shouldn't waste time micro-optimizing every small change before the system is even finished. While I agree with the sentiment, the "when" is always up for debate.
My rule: Optimize whenever you feel the need to. After adding a new system, check your profiling tools to see how that addition affects the game as a whole. While an experienced developer can often "feel" when a game becomes laggy or unresponsive, you shouldn't rely on gut feeling alone. Profilers exist to turn that "feeling" into actionable data.
A Fact on Blueprints: If you are having performance issues and your logic is primarily in Blueprints, the issue is likely the overhead of the Blueprint Virtual Machine (VM). This isn’t a "hot take"—it’s a technical reality. For heavy lifting, C++ is non-negotiable.
What Are Some Basic Tools?
The first thing I turn to—outside of a simple FPS counter—is the stat command system.
1. stat Unit
Before diving into specific code, you need to know where the bottleneck is. stat Unit breaks down the frame time into:
- Frame: Total time.
- Game: Time spent on the CPU (Game Thread).
- Draw: Time spent by the CPU preparing data for the GPU.
- GPU: Time the graphics card takes to render the frame.
2. stat Game
If stat Unit tells you the "Game" thread is the bottleneck, stat Game is your next stop. It provides a real-time breakdown of:
- World Tick Time: How long it takes to update all actors.
- Blueprint Time: How much of that tick is being eaten by the VM.
- PhysX/Chaos: Physics calculation costs.
3. Beyond Stats: Unreal Insights
While stat commands are great for a quick glance, they only show you a "snapshot." Unreal Insights is the real workhorse. It records a "trace" of every single function call across every thread.
- C++ Benefit: You can wrap your own code in
TRACE_CPUPROFILER_EVENT_SCOPE(MyCustomFunction)to see exactly how your logic is performing inside the Insights timeline.
The "Game Thread" Killers
For a systems developer, the Game Thread is where the real war is won.
The "Tick" Problem
The easiest way to destroy performance is by having hundreds of actors Ticking.
- The Solution: Use Timers, Delegates (Events), or the Significance Manager.
- C++ Rule: In your constructor, always set
PrimaryActorTick.bCanEverTick = false;by default.
Blueprint "Heavy Lifting" (The VM Tax)
The Blueprint VM has a high overhead for math-heavy or loop-heavy logic.
- Better: Perform the search or math in C++ using a fast pointer-based loop and return only the result to Blueprint.
Memory Alignment & TArrays
Since we're talking C-style C++, pay attention to your data structures.
- Reserve Memory: If you know a
TArrayis going to hold 100 elements, useMyArray.Reserve(100). This prevents the engine from re-allocating and copying the array multiple times as it grows. Read more on Optimizing TArray Usage.
Summary: The Optimization Workflow
If you’re staring at a laggy project, don’t guess. Follow this order:
- Run
stat Unit: Identify if you are Game, Draw, or GPU bound. - Check
stat Game: Look for the "Tick" or "Blueprint" time. - Profile with Unreal Insights: Find the exact function or node responsible for spikes.
- Refactor to C++: If a Blueprint system eats more than 1–2ms of your frame, move it to C++.
Optimization isn't a "final step"; it's a habit of choosing the lowest-overhead path while you're building.