PSO Autopilot Manual
Welcome to PSO Autopilot. This plugin is a reliable, production-ready solution to Unreal Engine 5's notorious shader compilation stutter and lag.
The "Shader Compilation" plugins on various marketplaces attempt to solve stutter by brute-forcing the Engine—loading all of your project's assets into memory simultaneously. If you are building a massive 50GB open-world game, this simplistic approach guarantees catastrophic RAM spikes, completely frozen loading screens, and eventually, Out-Of-Memory (OOM) crashes on consoles or lower-end PCs.
PSO Autopilot is different. It was created from the ground up to orchestrate Unreal's native hardware pipeline asynchronously, managing memory, threads, driver caches, and startup sequencing with architectural precision.
🛡️ Robust Architecture
PSO Autopilot includes built-in safeguards like Blanket Scan Protection. If you accidentally clear your target directories, the plugin instantly aborts rather than attempting to scan your entire 100GB project folder, preventing massive Editor lockups.
Key Features at a Glance
- Memory-safe batching — flat RAM throughout the entire warmup cycle
- Time-sliced processing — 60fps loading screens with configurable frame budget
- Explicit warmup roots — maps, blueprints, labels, and runtime-discovered assets can be queued directly
- Dependency expansion — recursively pulls in referenced content instead of relying on a flat directory scan alone
- Smart fingerprint caching — skip warmup entirely on subsequent launches
- Editor-preview bypass — leave PIE/editor preview on Unreal's normal shader compilation path unless explicitly enabled
- Gameplay package preload — move more first-run startup cost under the loading screen before gameplay begins
- Texture pre-heating — standard and Virtual Texture streaming before the loading screen drops
- Full vertex-factory coverage — Local, Nanite, ParticleSprite, BeamTrail, and MeshParticle PSOs
- Drop-in Boot Loader — zero-code loading screen with progress bar and level transition
- Editable default loading widget — the wizard can create
/Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreenfor project-side customization - Blueprint-friendly delegates —
OnProgressUpdatedandOnWarmupComplete - Editor-aware — filesystem timestamps detected so you never test stale shaders
- Validated packaged demo flow — boot-level warmup, gameplay-map preload, and duplicate-warmup suppression in the bundled sample
🖥️ Supported Platform in This Release
The packaged marketplace build documented here is currently validated and configured for Win64. The source architecture is portable, but only Win64 is exposed in the released descriptor and packaging profiles for this version.
The 6 Pillars of PSO Autopilot
Our architecture is built upon the following pillars that make it unique in the Unreal ecosystem.
USP 1: Memory-Safe Chunking
Instead of loading thousands of assets simultaneously, PSO Autopilot utilizes Unreal's FStreamableManager to asynchronously stream your assets into memory in strictly controlled batches.
Once a batch is successfully compiled by the Engine's native FShaderPipelineCache, the plugin explicitly drops all asset references and requests a non-blocking Garbage Collection pass. Your RAM footprint remains completely flat throughout the entire process.
Async
Time-Sliced
Memory Cleared
USP 2: The Seamless Loading Screen
A frozen loading screen feels like a crash to a player. PSO Autopilot uses advanced C++ time-slicing within the Game Thread's Tick function. It processes Asset Registry queries and shader assignments for a strictly allocated timeframe per frame (e.g., 5.0 milliseconds).
If the time limit is reached, it yields execution back to the Engine. This guarantees that your loading screen videos, UI spinners, and progress bars remain buttery smooth at 60fps while intense compilation happens quietly in the background.
USP 3: Broader Real-Project Coverage
PSO Autopilot no longer depends on a single flat directory scan to find what needs warming. It can combine standard scan folders with ExplicitAssetsToWarm, AdditionalClassesToScan, runtime-queued assets, and recursive package dependency expansion.
This is what allows the plugin to warm content that is only reachable through maps, actor blueprints, soft references, Primary Asset Labels, or inherited component templates instead of missing those assets and hitching later during gameplay.
USP 4: Zero-Redundancy Boot (Smart Cache Hashing)
Players shouldn't have to wait for shaders they've already compiled. When a player boots your game for the second time, PSO Autopilot intelligently checks its generated MD5 fingerprint against the local config.
If the Pipeline State Objects (PSOs) for your project are already fully digested and stored on the user's hard drive, the plugin instantly skips the entire warmup sequence. A process that took two minutes on the first launch will take 0.05 seconds on all subsequent launches.
Current builds also handle fresh editor restarts correctly: a matched fingerprint skips the asset warmup immediately instead of being forced back into a full pass by a temporary pipeline-cache backlog.
⏱️ Editor Timestamping
During development (WITH_EDITOR), the Smart Cache hashing algorithm actually interrogates the physical filesystem modification timestamps of your materials. If you tweak a Material Graph and save it, PSO Autopilot detects the change and bypasses the cache skip, ensuring you never test with stale shaders.
USP 5: First-Run Startup Cost Shift
For projects where the worst hitch happens in the first seconds after launching gameplay, PSO Autopilot can now push more work into a controlled loading phase. A Boot Loader can register the destination map as a warmup seed, expand its dependency graph, and preload the target package before travel begins.
This does not make Unreal's level transition free, but it moves more first-run cost under the loading screen instead of letting it land on the player's first interactive frames. The bundled boot-flow sample also carries a handoff flag so the gameplay map does not accidentally start a second warmup pass.
USP 6: Visual Continuity (Texture Pre-Heating)
Solving shader stutter is only half the battle. If your textures and virtual landscapes pop in blurry after the loading screen drops, the immersion is still broken.
Because PSO Autopilot already safely loads your materials into memory, it now automatically interrogates them for their texture dependencies. It seamlessly issues high-priority streaming requests for standard Textures (forcing high-res Mips) and pre-pages Virtual Textures (RVT/SVT) directly into VRAM before allowing the loading screen to finish.
Quick Start Guide (Setup Wizard)
We've introduced a powerful Setup Wizard to make integration effortless. It includes a project-aware preflight validator, one-click simple setup, and an automatic readiness card with instant fix buttons.
- Open Unreal Engine, then go to Window > PSO Autopilot Startup Setup.
- In Simple Setup, choose your Game Level, Loading Widget, Content to Prepare, and a Performance Preset.
- Leave Editor Iteration Mode set to Use Unreal Editor Compilation for normal PIE iteration. Switch it to Run PSO Autopilot Warmup only when you specifically want to test the full startup warmup in editor preview.
- Click Validate PSO Autopilot Setup. The Wizard's Project-Aware Preflight Validator will scan your active project.
- Review the Automatic Readiness Card. It displays color-coded results (Green/Yellow/Red) for your setup.
- Use the inline Fix buttons to instantly resolve issues. Current builds add targeted cook folders, avoid adding the whole
/Gameroot, and can remove a stale root cook directory when detected. - Click Create/Update Startup Flow to generate your loading level and drop in the PSO Autopilot Boot Loader automatically.
🧪 Editor Play Uses Unreal's Default Path by Default
With Editor Iteration Mode set to Use Unreal Editor Compilation, pressing Play in the editor immediately completes the PSO Autopilot flow and lets Unreal compile shaders normally for that PIE session. Packaged builds, Standalone Game, and -game validation still use the production warmup path.
⚡ Minimum Viable Integration
The simplest Blueprint integration is Start PSO Autopilot Loading Flow. It registers the gameplay level, queues the level package to load before play, shows the loading widget, starts preparation, releases the retained preload, and opens the destination level.
🧭 Recommended Production Flow
The best current integration is a dedicated loading level that prepares and loads your destination game level before travel. This is the same flow used by the bundled /Game/Demo/Demo_BootFlow sample.
Configuration Settings
PSO Autopilot exposes powerful variables to Project Settings > Plugins > PSO Autopilot so you can tailor the memory/performance balance precisely to your hardware targets. All settings are stored in DefaultGame.ini under [/Script/PSOAutopilot.PSOAutopilotSettings].
Targeting
| Setting | Default | Description |
|---|---|---|
DirectoriesToScan |
(empty) | Array of content directories to recursively scan (e.g., /Game/Weapons, /Game/VFX). Do not set to /Game/ alone in large projects—isolate your heavy visual folders. Must contain at least one entry (Blanket Scan Protection). |
AdditionalClassesToScan |
(empty) | By default the plugin scans for UMaterialInterface. Add extra asset classes here when your warmable content is rooted in other asset types (for example actor blueprints or custom asset classes that reference primitive components and materials). |
ExplicitAssetsToWarm |
(empty) | Explicit root assets to include even if they are not found by the directory scan. Use this for maps, actor blueprints, Primary Asset Labels, or any special startup assets that should seed the warmup graph. |
⚠️ Avoid Empty Path Entries
If your DefaultGame.ini contains +DirectoriesToScan=(Path=""), the empty string causes the Asset Registry filter to return zero results even when valid paths are also present. Remove any blank entries.
📦 Do Not Always Cook the Whole Project
Use targeted warmup folders and targeted cook directories. Adding +DirectoriesToAlwaysCook=(Path="/Game") forces Unreal to cook the entire project and can make every package attempt look like a full recook after restart. The setup wizard now avoids adding that root entry and the validator can remove it when found.
Coverage & Startup Cost Shift
| Setting | Default | Description |
|---|---|---|
bExpandPackageDependencies |
true | Recursively expands package dependencies from the discovered seed assets so maps, blueprints, labels, and other roots can pull in their referenced warmable content. |
DependencyExpansionDepth |
1 | How many dependency hops to traverse beyond the original seed set. Increase this when a single map or blueprint leads to deeper chains of referenced warmable assets. |
bIncludeSoftPackageReferences |
true | Includes soft package references during dependency expansion so softly referenced content can be discovered before gameplay touches it. |
bIncludeManagementReferences |
true | Includes asset-manager and Primary Asset Label management references during dependency expansion. |
PackagesToPreload |
(empty) | Optional packages or assets to asynchronously preload before warmup completes. Use this to move more first-run map and package load cost under the loading screen. |
Memory Management
| Setting | Default | Description |
|---|---|---|
BatchSize |
100 | Number of assets loaded per batch. Lower to 50 for low-RAM targets (consoles, mobile). Higher values are faster but increase peak memory. |
bGarbageCollectBetweenBatches |
true | Request a GC pass after every batch is unloaded. Leave enabled for stable RAM. Disable only if warmup speed matters more than memory. |
Performance (Seamless UI)
| Setting | Default | Description |
|---|---|---|
MaxProcessingTimeMsPerFrame |
5.0 | Time budget (ms) for PSO processing per game-thread tick. A 60fps frame is 16.6ms—leaving 5ms gives the Engine 11.6ms for UI rendering. Increase up to ~10ms for faster warmup at the cost of choppier loading animations. |
Editor Preview
| Setting | Default | Description |
|---|---|---|
EditorIterationModeSimpleEditorIterationMode |
Use Unreal Editor Compilation | Controls whether PSO Autopilot runs during PIE/editor preview. Use Unreal Editor Compilation is recommended for normal iteration and bypasses PSO Autopilot in editor Play. Run PSO Autopilot Warmup runs the full loading flow inside editor preview for validation. Packaged builds are unaffected by this editor-only mode. Legacy config keys bEnableInEditorPreview and bSimpleEnableInEditorPreview remain supported. |
Visual Continuity (VRAM)
| Setting | Default | Description |
|---|---|---|
bPreHeatTextureStreaming |
true | Forces standard textures referenced by scanned materials to load their high-resolution mip levels into VRAM during the warmup cycle. |
bPreHeatVirtualTextures |
true | Sends predictive page-in requests for Virtual Textures (RVT/SVT) to prevent grey blocks on world load. |
Validation & Minimum Duration
| Setting | Default | Description |
|---|---|---|
bEnforceMinimumValidationDuration |
false | When enabled, keeps the warmup in a hold state for a configurable time after all batches finish. Useful for stress-testing or demos where you want to observe the validation phase. |
MinimumValidationDurationSeconds |
0.0 | The minimum total warmup duration in seconds (only applies when enforcement is enabled). |
State Machine
Understanding the internal state machine helps you diagnose issues and integrate custom UI. PSO Autopilot transitions through these states sequentially:
After scanning and fingerprinting, PSO Autopilot can optionally enter Preloading Packages before the first batch begins. The loop from Loading Batch through Waiting For GC then repeats for each chunk of assets. If demo validation timing is enabled, the machine enters Delay Minimum Duration before Finished, fires OnWarmupComplete, persists the fingerprint when the run succeeded cleanly, and returns to Idle.
Editor Preview Bypass
When Editor Iteration Mode is set to Use Unreal Editor Compilation and the world is PIE, Editor, Editor Preview, or Game Preview, StartWarmup() completes immediately before calling FShaderPipelineCache::ResumeBatching(). This keeps normal editor Play sessions on Unreal's built-in shader compilation behavior while preserving the full PSO Autopilot path for packaged/runtime validation.
Batch Loop Details
Scanning — waits for the Asset Registry to be ready, then builds the warmup list from scan directories, explicit roots, runtime-queued roots, classes, and optional dependency expansion.
Fingerprinting — hashes the final discovered asset set plus key settings so cache-skip decisions reflect the real startup workload.
Preloading Packages — asynchronously loads any queued gameplay packages before the loading screen is allowed to finish.
Loading Batch — Uses FStreamableManager::RequestAsyncLoad to stream assets without blocking the game thread. A 60-second watchdog timer protects against stuck loads.
Processing Batch — Time-sliced PSO precaching via PrecachePSOs(). Covers Local, Nanite, ParticleSprite, BeamTrail, and MeshParticle vertex factories.
Streaming Textures — Calls SetForceMipLevelsToBeResident() on standard textures and UpdateResource() on Virtual Textures. A 30-second timeout prevents indefinite waits.
Unloading Batch — Releases all FStreamableHandle references and clears temporary component arrays.
Waiting For GC — If enabled, requests a full-purge Garbage Collection to reclaim memory before the next batch.
Delay Minimum Duration — optional demo hold state that keeps the loading UI visible for a minimum total runtime.
UI & Blueprint Integration
The PSOAutopilotSubsystem provides robust Blueprint delegates and a drop-in loading screen actor to drive your UI.
PSO Autopilot Loader Actor Recommended
The APSOAutopilotBootLoader is the fastest way to add startup preparation to your game. Drop the PSO Autopilot Loader into your starting level (or, preferably, a dedicated loading level) and configure it from the Details panel—no C++ or Blueprint graph is required.
In the current sample flow, the loader can prepare the destination level before opening it, queue additional content, preload the destination package before travel, and then open gameplay only after startup preparation is complete.
| Property | Description |
|---|---|
| Loading Widget | Widget class shown while PSO Autopilot prepares startup content. The setup wizard creates and assigns an editable Widget Blueprint at /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen so you can customize the default screen in UMG. |
| Level To Open | Level opened after startup preparation finishes. Recommended: set this to your main menu or first gameplay level. |
| Warm Gameplay Level Before Opening | Includes the Level To Open so referenced content can be prepared before gameplay opens it. Recommended: On. |
| Preload Gameplay Level Package | Loads the Level To Open package before startup preparation completes so more first-run level-load cost happens under the loading widget. Recommended: On. |
| Auto Start | Automatically starts startup preparation when this loader begins play. Recommended: On. |
| Advanced Content | Optional specific content to prepare or load before play when important startup content is not reachable from the Level To Open. |
| Advanced Overrides | Per-loader tuning for content folders, item count, and frame budget. Recommended: leave off unless this loader needs different behavior from Project Settings. |
| Debug / Demo | Demo hold and force-run controls. Recommended: Off for shipped games. |
🔄 Settings Snapshot & Restore
When bApplySettingsOverride is enabled, the PSO Autopilot Loader captures a snapshot of your Project Settings before applying overrides. The original values are automatically restored when startup preparation completes or when the actor is destroyed, so your runtime settings are never permanently altered.
🛣️ Boot-Flow Handoff
The bundled demo carries a travel option from the boot map to the gameplay map so the destination demo manager can intentionally skip a duplicate warmup pass. If you build your own boot-to-gameplay flow, follow the same rule: do not call StartWarmup() again on the destination map if the boot flow already completed the work.
One-Node Blueprint Flow
Use Start PSO Autopilot Loading Flow when you want the recommended Stage Zero-style Blueprint entry point without wiring every subsystem call manually.
| Input | Description |
|---|---|
| Gameplay Level | Destination level to prepare, optionally preload, and open after startup preparation completes. |
| Loading Widget | Widget class shown during startup preparation. Use your branded widget or the wizard-created /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen asset. |
| Warm Gameplay Level Before Opening | Registers the gameplay level as content to prepare. Recommended: On. |
| Preload Gameplay Level Package | Loads the gameplay level package before travel so more first-run load cost happens under the loading widget. Recommended: On. |
| Remove Loading Widget When Ready | Removes the loading widget before opening the destination level. Recommended: On. |
| Ignore Previous Runs | Forces preparation even when smart skip would normally skip it. Recommended: Off outside testing. |
Delegates
On Progress Updated
Fires continuously during startup preparation.
Overall Progress (Float): A normalized 0.0 to 1.0 value representing the total completion percentage. Bind this directly to a UMG ProgressBar.
Current Status Message (String): Friendly live status text for the loading screen. Messages include: Finding startup assets..., Checking previous warmup..., Loading assets in safe batches..., Preparing shaders..., Preparing textures..., Preloading gameplay map..., and Ready.
Technical Status Message (String): Optional telemetry text available through Get Technical Status Message. Use it in a collapsible debug or telemetry panel when you want details like cache fingerprinting, batch counts, PSO task counts, package names, or texture streaming counts.
On Startup Preparation Complete
Fires exactly once when the entire process is finished or skipped because the content was already prepared. Bind this event to close your loading screen and transition to gameplay.
Custom UMG Widgets
Don't want to build a UI from scratch? The plugin includes a highly customizable C++ base class: UPSOAutopilotLoadingScreenWidget. If dropped into a project without a custom UMG design, its fallback system will procedurally generate a sleek, dark-mode progress bar and status text UI automatically.
The setup wizard can create /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen, an editable Widget Blueprint that inherits from UPSOAutopilotLoadingScreenWidget. Customize that asset directly, or create your own Widget Blueprint with the same parent class and assign it to the Startup Loader's LoadingScreenClass property.
Blueprint-Driven Loading Screen
You can also use the subsystem directly from any Blueprint. Get the subsystem reference, bind to OnProgressUpdated and OnWarmupComplete, then call StartWarmup(). This gives you complete control over when and how startup preparation runs.
// Blueprint pseudo-code
GameInstance -> GetSubsystem(PSOAutopilotSubsystem) -> subsystem
subsystem -> BindEvent(OnProgressUpdated) -> UpdateMyProgressBar
subsystem -> BindEvent(OnWarmupComplete) -> OpenLevel("MainMenu")
subsystem -> StartWarmup()
Fingerprint & Caching
PSO Autopilot uses an MD5 fingerprint to determine whether warmup needs to run. Understanding this system helps avoid unnecessary re-warmups and diagnose cache-related issues.
How the Fingerprint Works
- Discovery: After scanning directories, explicit roots, class roots, runtime-queued roots, and optional dependency expansion, the plugin generates a fingerprint string from the final discovered asset set.
- Editor timestamps: In
WITH_EDITORbuilds, filesystem modification timestamps of source materials are mixed into the hash. This means saving a material automatically invalidates the cache. - Settings participation: Dependency-expansion settings and engine version are mixed into the fingerprint so cache-skip decisions reflect the real startup configuration, not just the root paths.
- MD5 hashing: The fingerprint string is hashed to produce a compact, deterministic identifier.
- Cache check: On startup, the plugin compares this fingerprint against previously completed fingerprints stored in
GameUserSettings.ini. - Skip or run: If the fingerprint matches a cached entry, the asset warmup is skipped and
OnWarmupCompletefires immediately. This remains true after an Unreal restart even if the engine reports a temporary fresh-process pipeline-cache backlog.
Multi-Configuration Cache
PSO Autopilot stores up to 8 completed fingerprints simultaneously using an LRU (Least Recently Used) eviction policy. This means:
- Different Boot Loaders scanning different directories won't invalidate each other's caches.
- Switching between build configurations preserves prior warmup results.
- When the 9th unique fingerprint completes, the oldest entry is evicted.
Cache Storage Location
Fingerprints are stored in GameUserSettings.ini under the [PSOAutopilot] section as a comma-separated list in the CompletedFingerprints key. The plugin also reads the legacy single-fingerprint key for backward compatibility. You can clear this section to force a full re-warmup on the next launch.
Matched Cache Runs Complete Immediately
Smart-cache hits bypass asset loading, package preload, and demo minimum-duration holds. If a loader previously had debug flags such as bResetFingerprintOnBeginPlay enabled, re-running the setup wizard clears stale simple-setup debug overrides so cached launches do not accidentally become cold launches again.
⚠️ ResetCachedWarmupFingerprint
Calling ResetCachedWarmupFingerprint() on the subsystem clears all cached fingerprints. The Boot Loader exposes this via the bResetFingerprintOnBeginPlay checkbox. Use it during development when you want to guarantee the warmup runs.
🧪 Fingerprints Are Only Stored for Clean Runs
If the warmup finishes with asset-load failures or package-preload failures, PSO Autopilot intentionally does not persist the fingerprint. This prevents a partially successful startup run from being incorrectly treated as fully cached on the next launch.
Marketplace Demo
PSO Autopilot now ships with a buyer-facing startup flow instead of requiring manual demo construction. The bundled content includes:
/Game/Demo/Demo_BootFlow— boot map and default project startup map/Game/Demo/UI/WBP_LoadingScreen— loading screen used while startup content is prepared/Game/Demo/Demo_PSOTorture— gameplay map opened after preparation/Game/Demo/BP_BootLoader— placed PSO Autopilot Loader actor sample/Game/Demo/UI/BP_PSOAutopilot_HUD— gameplay telemetry overlay with cold/cached run controls/Game/DemoMaterials— 1000 material-instance stress assets
Demo Story
- If needed, regenerate the sample assets with
Scripts/CreatePSOAutopilotDemo.pyusing Unreal's-ExecutePythonScriptargument. - Open
/Game/Demo/Demo_BootFlow. - Press Play, preferably in Standalone Game for behavior closest to runtime.
- The boot map shows
WBP_LoadingScreen, warms/Game/DemoMaterials, preloads the gameplay map, and then opens/Game/Demo/Demo_PSOTorture. - The gameplay map detects the boot-flow handoff and skips duplicate preparation, so you only pay the startup cost once.
- The small telemetry overlay lets you run a cold pass and then a cached pass. Cached passes clearly report Warmup skipped because cache matched.
Packaged Smoke-Test Proof
A live packaged smoke test warmed 1001 startup assets, preloaded /Game/Demo/Demo_PSOTorture during the loading screen, released the retained preload before travel, opened the gameplay map, and skipped the duplicate warmup on the destination map.
Packaged-Build Checklist
- Use
/Game/Demo/Demo_BootFlowasGameDefaultMap. - Add
/Game/Demo/Demo_BootFlowand/Game/Demo/Demo_PSOTortureto the packaged maps list. - Always cook
/Game/Demoand/Game/DemoMaterials. - Package a Development build with logs when evaluating the demo overlay; package Shipping when validating the production loader path.
- Launch the packaged game once for the cold run, then launch it again for the cached run.
Direct Gameplay-Map Validation
If you want to test the raw demo manager path without the boot flow, open /Game/Demo/Demo_PSOTorture directly. That path forces a validation run, resets the warmup fingerprint cache, points scanning at /Game/DemoMaterials, and holds the UI for a minimum visible duration.
📦 Demo vs. Production
The PSOAutopilotDemoManager is designed for demonstrations and testing only. It temporarily overrides your Project Settings (batch size, frame budget, minimum duration) and restores them when done. It is automatically disabled in Shipping builds. For production use, use the APSOAutopilotBootLoader instead.
Fallback Widget
If no HUDClass is set on the Demo Manager, it automatically falls back to UPSOAutopilotDemoWidget's C++ fallback UI, which procedurally generates a compact telemetry panel with progress, timing, cold/cached controls, cache status, and a smooth spinner.
🛠️ Regenerating the Sample
Run Unreal with Scripts/CreatePSOAutopilotDemo.py via -ExecutePythonScript if you want to rebuild or normalize the sample levels, demo materials, boot widget, and boot actor defaults.
Best Practices
Target Precisely
Add only the directories that contain materials your players will see during gameplay. Scanning /Game/ on a large project will waste time on audio, data tables, and other non-visual assets. Typical targets:
/Game/Characters— player and NPC materials/Game/Weapons— weapon skins and attachments/Game/Environment— world materials and foliage/Game/VFX— particle and Niagara effects/Game/UI— only if you have material-based UI effects
For content that is rooted in maps, labels, or blueprints instead of plain folders, add those roots through ExplicitAssetsToWarm and enable dependency expansion instead of broadening your directory scan unnecessarily.
Tune Batch Size to Your Target Hardware
The default batch size of 100 works well for mid-range PCs with 16GB RAM. Adjust based on your target:
- Console / Mobile (8GB or less): Batch size 25–50
- Mid-range PC (16GB): Batch size 50–100
- High-end PC (32GB+): Batch size 100–200
Monitor your peak memory using stat memory or an external profiler during the warmup cycle to find the sweet spot.
Use a Dedicated Loading Level
For the cleanest integration, create a minimal level that contains only a BP_BootLoader actor and a sky/background. Set LevelToOpenOnComplete to your main menu or gameplay level. This ensures:
- The warmup runs before any gameplay assets compete for memory.
- The player sees a polished loading screen, not a half-loaded world.
- Level transition automatically handles cleanup of warmup resources.
Leave bRegisterLevelAsWarmupSeed and bPreloadLevelPackagesBeforeOpen enabled unless you have a specific reason to disable them. Those two switches are what let the boot flow warm and preload the destination map before gameplay opens it.
Queue Dynamic Roots Before Warmup Starts
If some of your startup content is chosen dynamically at runtime, queue it before the warmup begins instead of hoping a broad scan catches it. Use RegisterRuntimeWarmupAsset(...), QueuePackagePreload(...), or the Boot Loader's begin-play overrides.
Test in Standalone Game Mode
The Editor handles PSOs differently than a deployed executable. For accurate results:
- Use Standalone Game,
-gamemode, or a packaged Development build for production-like behavior. - Use
-gamemode:UnrealEditor.exe MyProject.uproject MyMap.umap -game -log -windowed - If you need to test inside PIE/editor preview, switch Editor Iteration Mode to Run PSO Autopilot Warmup first.
- Watch the
LogPSOAutopilotcategory in the output log for detailed telemetry.
Troubleshooting FAQ
Startup & Scanning
Q: The progress bar stays at 0% for a long time on boot.
A: Unreal Engine's Asset Registry initializes asynchronously in the background when the game boots. PSO Autopilot waits for this background scan to finish before querying assets to ensure none are missed. If your project is very large, this initial wait is normal. You can monitor progress in the log under LogPSOAutopilot: once the Asset Registry is ready, scanning begins immediately.
Q: The plugin instantly finishes and warns "DirectoriesToScan is empty!"
A: This is Blanket Scan Protection working as intended. If the targeting directories array is empty, the plugin aborts to prevent querying the entire Asset Registry. Add at least one targeted directory (e.g., /Game/Characters or /Game/VFX) in Project Settings > Plugins > PSO Autopilot > Directories To Scan.
Q: The scan finds 0 assets even though my directories are set correctly.
A: Check for these common causes:
1. Empty path entry: If DefaultGame.ini contains +DirectoriesToScan=(Path=""), this empty entry causes the Asset Registry filter to fail silently. Remove it.
2. Wrong path format: Paths must use the /Game/ prefix, not filesystem paths. Use /Game/Characters, not Content/Characters.
3. Asset Registry not ready: In -game mode, the background asset scan may not have started yet. Current builds handle this by kicking off an async full search and waiting until the registry is ready.
4. Your real roots are not directory-based: If the startup content is rooted in a map, blueprint, label, or dynamic runtime selection, add it through ExplicitAssetsToWarm or RegisterRuntimeWarmupAsset(...) rather than relying only on DirectoriesToScan.
Q: Scanning is very slow in the Editor.
A: In Editor builds, PSO Autopilot queries filesystem modification timestamps for every discovered asset to build the fingerprint. This is necessary to detect material changes but adds I/O overhead. In packaged builds this step is skipped, and scanning is significantly faster. To speed up Editor iteration, narrow your DirectoriesToScan to only the folders you're actively working on.
Q: Pressing Play in the editor no longer runs the warmup. Is the plugin disabled?
A: Not globally. Current builds default Editor Iteration Mode to Use Unreal Editor Compilation, so PIE/editor preview uses Unreal's standard shader compilation path and PSO Autopilot completes immediately. Packaged builds and runtime validation still use the warmup. Switch the mode to Run PSO Autopilot Warmup when you want to test the full flow in PIE.
Shader Compilation
Q: I see "Compiling PSOs..." in the log, but no shaders are actually building.
A: Ensure your project is configured to generate shader caches. In DefaultEngine.ini, verify that bShareMaterialShaderCode=True is set under [/Script/Engine.RendererSettings]. Also test in a Packaged Build or -game mode—the Editor handles PSOs differently than a deployed executable.
Q: Which vertex factories does PSO Autopilot cover?
A: The plugin submits PSO precache requests for these vertex factory types:
• Local Vertex Factory — Standard static meshes
• Nanite Vertex Factory — Nanite-enabled meshes (UE 5.x)
• Particle Sprite — GPU sprite particles
• Beam/Trail — Beam and trail particle emitters
• Mesh Particle — Mesh-based particle emitters
Skeletal mesh vertex factories are covered when the corresponding materials are scanned. Landscape and other specialized factories rely on the Engine's own PSO collection at draw time.
Memory & Performance
Q: My loading screen stutters or drops below 60fps during warmup.
A: The MaxProcessingTimeMsPerFrame setting controls how much game-thread time the plugin uses per frame. The default of 5.0ms should leave ~11.6ms for rendering at 60fps. If you're still seeing hitches:
1. Lower MaxProcessingTimeMsPerFrame to 2.0–3.0ms.
2. Reduce BatchSize—smaller batches mean less per-frame work.
3. Check if other systems (level streaming, audio loading) are competing for the game thread.
Q: RAM usage spikes during warmup. How do I reduce peak memory?
A: Three levers control memory usage:
1. Reduce BatchSize — Fewer assets loaded simultaneously means lower peak RAM. Try 25–50 for constrained platforms.
2. Enable GC Between Batches — Ensure bGarbageCollectBetweenBatches is true. The plugin performs a full-purge GC after each batch to aggressively reclaim memory.
3. Target fewer directories — Only scan folders with materials the player will actually see. Reducing total asset count is the most effective way to lower peak memory.
4. Be selective with package preload — PackagesToPreload and bPreloadLevelPackagesBeforeOpen intentionally move more work into startup, which can also increase temporary memory pressure. Preload only the packages that materially improve first-run smoothness.
Q: The warmup takes too long. How can I speed it up?
A: Warmup speed is a tradeoff with memory and UI smoothness:
1. Increase BatchSize to 150–200 (if RAM allows).
2. Increase MaxProcessingTimeMsPerFrame to 8–10ms (loading animations may be slightly choppier).
3. Disable texture pre-heating if visual pop-in is acceptable: set bPreHeatTextureStreaming and bPreHeatVirtualTextures to false.
4. Narrow your scan targets to only critical directories.
Q: I saw a D3D12RHI uniform buffer crash during a huge warmup. What changed?
A: Current builds throttle active PSO precache requests during time-sliced batch processing. This prevents very large material sets from flooding the renderer with unchecked background PSO work. If you still hit renderer instability, reduce BatchSize, narrow scan folders, and test with a Development packaged build log.
Texture Streaming
Q: The log shows "Texture streaming timed out." Is this a problem?
A: The plugin imposes a 30-second timeout on the texture streaming phase per batch. If some textures haven't finished streaming by then, the plugin advances to the next batch rather than waiting indefinitely. This is a safety mechanism. If you see this frequently:
1. Your batch size may be too large for your I/O bandwidth. Reduce BatchSize.
2. Virtual Textures with very large page tables may need more time. The timeout is generous enough for most projects.
3. The textures will still stream in during gameplay—this timeout just means they weren't fully resident before the loading screen dropped.
Q: Textures still pop in blurry after the loading screen finishes.
A: Ensure both bPreHeatTextureStreaming and bPreHeatVirtualTextures are enabled in Project Settings. If the issue persists:
1. The materials causing pop-in may be outside your scanned directories. Add their parent folders to DirectoriesToScan.
2. Texture streaming may have timed out (see above). Check the log for timeout warnings.
3. If using World Partition or level streaming, textures in streamed sub-levels are not covered by PSO Autopilot's pre-heat—they are managed by Unreal's runtime streaming system.
Fingerprint & Cache
Q: The warmup runs every time I launch, even though nothing changed.
A: The fingerprint may be changing between launches. Common causes:
1. Editor timestamp drift: In Editor/PIE, filesystem timestamps are included in the fingerprint. If your source control or build system touches file modification dates, the hash changes. This does not happen in packaged builds.
2. GameUserSettings.ini not saved: The fingerprint is written to GameUserSettings.ini. If the game crashes before this file is flushed, the cache is lost. Check that the file is writable.
3. bResetFingerprintOnBeginPlay is enabled: The Boot Loader or Demo Manager may be forcing a reset. Check the actor's properties. Re-running the setup wizard clears stale simple-setup demo/debug overrides on existing loader actors.
4. The previous run had warnings: Fingerprints are only stored for clean runs. Asset-load or package-preload failures intentionally force a fresh attempt next time.
Q: I changed some materials but the warmup was skipped. Stale cache?
A: In Editor builds, PSO Autopilot includes filesystem timestamps in the fingerprint, so saving a material should invalidate the cache. If it doesn't:
1. Verify the changed material is inside one of your DirectoriesToScan directories.
2. The material may be a Material Instance whose parent hasn't changed. Re-save the parent material to force a new timestamp.
3. If the changed content is only reachable through a map, blueprint, label, or soft reference, make sure that root is still represented in the discovered warmup set. The fingerprint now keys off the final discovered asset list, not just the raw directory list.
4. As a workaround, enable bResetFingerprintOnBeginPlay on your Boot Loader during development to always force the warmup.
Q: How do I manually clear the fingerprint cache?
A: Two methods:
1. At runtime: Call ResetCachedWarmupFingerprint() on the PSOAutopilotSubsystem before starting the warmup.
2. Manually: Open GameUserSettings.ini (in your project's Saved/Config/ folder) and delete the [PSOAutopilot] section.
Q: I have multiple Boot Loaders with different scan directories. Will they conflict?
A: No. PSO Autopilot stores up to 8 unique fingerprints using LRU eviction. Each Boot Loader generates its own fingerprint based on its scan configuration, and they are independently cached. The 9th unique fingerprint will evict the oldest entry.
Boot Loader
Q: The Boot Loader warns "LevelToOpenOnComplete was not found."
A: The level name you entered doesn't match any package on disk. The Boot Loader validates the level before attempting the transition to prevent crashes. Check that:
1. The level name matches exactly (case-sensitive on some platforms).
2. The level is included in your packaged build's list of maps (Project Settings > Packaging > List of maps to include).
3. You're using the long package name (for example /Game/MainMenu/MainMenu), not a filesystem path.
Q: Why does the gameplay map not start a second warmup after the boot map finishes?
A: That is the intended sample behavior. The boot-flow path hands off a travel option to the gameplay map, and the bundled demo manager checks that flag and skips duplicate warmup work. This prevents the startup cost from being paid twice.
Q: The loading widget doesn't appear.
A: Check the following:
1. Ensure a valid Player Controller exists. The Boot Loader requires a local player controller to create widgets.
2. If using a custom LoadingScreenClass, verify it's a valid Widget Blueprint that compiles without errors. The setup wizard's default editable widget should live at /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen.
3. Check the output log for LogPSOAutopilot messages—the Boot Loader logs whether widget creation succeeded or failed.
Q: The folder only contains the loading map, but Play shows a C++ loading widget. Why?
A: Older setup data could point directly at the native UPSOAutopilotLoadingScreenWidget fallback instead of a project-owned UMG asset. Run the setup wizard and use the loading-widget fix or Create/Update Startup Flow. Current builds create and assign the editable /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen Widget Blueprint.
Q: My Project Settings get permanently changed after using the Boot Loader.
A: This should not happen. The Boot Loader captures a snapshot of your settings before applying overrides and restores them when warmup completes or when the actor is destroyed. If settings appear stuck:
1. Check if the game crashed before RestoreSettingsOverrides() ran. In that case, the CDO may have been modified but the INI file was not overwritten.
2. Restart the Editor to reload settings from DefaultGame.ini.
3. Verify that bApplySettingsOverride is actually enabled—if it's false, no snapshot is taken and nothing is restored.
Batch Processing
Q: The log shows "Batch load timed out." What happened?
A: A 60-second watchdog timer protects against stuck async loads. If an FStreamableManager::RequestAsyncLoad call doesn't complete within 60 seconds, the plugin cancels the load, marks the batch as failed, and advances to the next batch. Causes include:
1. Corrupted or excessively large assets that take too long to load.
2. Disk I/O contention (e.g., antivirus scanning, another application thrashing the disk).
3. The assets have external dependencies that trigger cascading loads. This is rare but can happen with deeply nested Blueprint references.
The warmup will continue with remaining batches. Failed batches are counted and reported in the completion log.
Q: The warmup completes but reports some failed batches. Should I worry?
A: A small number of failed batches (1–2 out of many) is usually harmless—those specific materials may have compilation issues unrelated to PSO Autopilot. The shaders for those materials will be compiled on-demand at draw time (with a potential micro-stutter). If many batches fail, investigate the assets in those batches for corruption or unsupported material features.
Integration & Platform
Q: Unreal keeps cooking almost everything after I restart the editor. What should I check?
A: Check Project Settings > Packaging > Additional Asset Directories to Cook and your config for +DirectoriesToAlwaysCook=(Path="/Game"). That root entry tells Unreal to always cook the whole project. Current setup-wizard fixes avoid adding it and can remove it; use specific folders such as /Game/Demo, /Game/DemoMaterials, or your real startup content folders instead.
Q: Can I call StartWarmup() from C++ instead of using the Boot Loader?
A: Yes. Get the subsystem from your GameInstance and call StartWarmup() directly:
UGameInstance* GI = UGameplayStatics::GetGameInstance(this);
UPSOAutopilotSubsystem* PSO = GI->GetSubsystem<UPSOAutopilotSubsystem>();
PSO->OnWarmupComplete.AddDynamic(this, &AMyActor::OnWarmupDone);
PSO->StartWarmup();
Q: What platforms does the current packaged release support?
A: The current packaged marketplace build is validated and configured for Win64. The underlying code is portable Unreal C++, but only Win64 is exposed in the released plugin descriptor and packaging profiles for this version.
Q: Is the plugin safe to use in Shipping builds?
A: Yes. The core subsystem (UPSOAutopilotSubsystem) and Boot Loader (APSOAutopilotBootLoader) work in all build configurations including Shipping. The Demo Manager (APSOAutopilotDemoManager) is automatically disabled in Shipping builds via a compile-time guard.
Q: Can I run the warmup in a background thread instead of the game thread?
A: No. PSO precaching (PrecachePSOs) must happen on the game thread because it interacts with the rendering subsystem and material proxies. This is an Unreal Engine requirement, not a PSO Autopilot limitation. The time-slicing architecture ensures the game thread is only occupied for a configurable number of milliseconds per frame, keeping your UI responsive.
Logging & Debugging
Q: How do I enable detailed logging?
A: All PSO Autopilot messages use the LogPSOAutopilot log category. To see them:
1. In-Editor: Open the Output Log and filter by LogPSOAutopilot.
2. In -game mode: Add -log to your launch arguments to open the log window.
3. In packaged builds: Add -log or check the saved log file in Saved/Logs/.
The plugin logs state transitions, batch progress, asset counts, fingerprint values, timing data, and any warnings or errors.
Q: The log shows "IsWarmupRunning() is true, ignoring StartWarmup call."
A: You called StartWarmup() while a warmup is already in progress. The plugin guards against re-entrant calls. Wait for OnWarmupComplete to fire before starting another warmup, or check IsWarmupRunning() before calling.
Q: The warmup seems stuck in "Processing Batch" for a very long time.
A: This state is time-sliced, so it only runs for MaxProcessingTimeMsPerFrame per tick. If you have thousands of materials with complex shader permutations, this phase can take minutes. Check the log for the PSO remaining count—if it's decreasing, the plugin is working normally. If it's truly stuck at a fixed number, there may be a shader compilation issue with a specific material. Try reducing your scan scope to isolate the problematic asset.
Copyright © 2026 GregOrigin. All Rights Reserved.