What an optimisation tool can and cannot see
Short answer: an offline tool can prove facts stored in assets and packages. It cannot prove what a running level instantiates, what a Blueprint does each frame, or what the GPU spends on a particular camera. A good report names that boundary. An empty report means only that none of its checks found anything.
What can be read without running the project
Unreal's Asset Registry exposes package paths, asset classes, dependencies and selected searchable tags without fully loading every asset object. Once an asset is loaded in the editor, a tool can inspect more serialized properties: a static mesh's LOD resources, Nanite setting, material slots, collision configuration and other data that exists in the package.
Those are useful facts. A mesh has one LOD or it does not. A texture has stored dimensions and mip settings. A component template has a shadow flag. The tool does not need to guess those values, and the same scan can be reproduced.
What the asset cannot tell you
An asset does not know how many times it will be instantiated, whether those instances are visible together, how large they are on screen, which lights affect them, or which scalability and platform settings will be active. It does not contain the future camera path or the contention on the game and render threads.
That is why a static “cost” attached to an asset is always an estimate with assumptions. Runtime captures remain necessary for frame time, overdraw, shader execution, streaming behaviour and hitches.
Why bCanEverTick does not find unnecessary Blueprint tick
bCanEverTick says that an actor or component class is allowed to register a tick function. It does not prove that a Blueprint has useful work connected to Event Tick, that tick starts enabled, that an instance leaves it enabled, or that the actor even exists in the measured level.
if (DefaultActor->PrimaryActorTick.bCanEverTick)
{
// Tick is permitted. This is not evidence that useful
// Blueprint work executes every frame.
}
A rule that reports every class with bCanEverTick as wasted tick will produce confident false positives. Proving unnecessary tick requires graph inspection, instance state and runtime timing. Even then, “unnecessary” is a design judgement unless the work can be shown to have no required effect.
Why construction-script components are invisible
Components stored as class-default subobjects are visible in the Blueprint's serialized templates. Components created or selected by a construction script do not necessarily exist as those templates. The script runs when an actor is constructed and may add components, choose meshes or change settings using instance data.
An asset-only scan that never constructs the actor cannot see the final component graph. Running every construction script during a scan is not a safe shortcut either: scripts can be expensive, depend on world state, create side effects or produce different output for each instance.
A no-findings result is not a health certificate
Every check has a scope. If a scanner checks LOD count, shadow flags and texture settings, a clean result says those checks found no matching conditions in the assets they could inspect. It says nothing about material instruction cost, Niagara systems, Blueprint logic, animation, physics, visibility, runtime spawning or a platform-specific render path unless those areas were actually measured.
Framegain publishes a separate “what is not checked” reference for this reason. The honest output from an optimisation tool is a bounded claim: what was inspected, what rule was applied, what evidence was found and what remains unknown.
Use static and runtime evidence together
- Use asset scans to find repeatable configuration facts and rank candidates.
- Use Unreal Insights for game-thread, render-thread and task timing.
- Use GPU captures and Nanite visualisations for rendered work.
- Use platform memory and streaming tools for residency and hitches.
- Re-run the same capture after a change. A plausible diagnosis is not a measured improvement.