PSO Autopilot logo illustration
PSO Autopilot logo

PSO Autopilot

Unreal Engine startup preparation

FAQ for smooth first play.

Answers for setup, shader warmup, smart cache skip, loading screens, texture readiness, packaging, and troubleshooting.

Memory-safe batches Loads startup content in controlled steps.
Smooth loading UI Time-sliced work protects the game thread.
Smart repeat boots Skips completed warmups when the cache matches.

Start Here

The essentials for deciding where PSO Autopilot fits in your Unreal project.

Best first step

Use Window > PSO Autopilot Startup Setup, choose Level To Open After Warmup, select a preset, validate, fix safe items, and create the startup flow.

Recommended preset

Balanced is the default for most projects. Use Safe Startup for large projects and Fast Warmup for smaller projects.

Production pattern

Open a lightweight loading level first, warm the destination content there, then travel to the gameplay map.

Repeat launches

Smart cache skip can bypass repeat warmups when the same startup content already completed successfully on that machine.

What is PSO Autopilot?

PSO Autopilot is an Unreal Engine plugin that prepares startup content before gameplay so first-play shader and texture costs happen under a controlled loading screen instead of during interactive play.

It focuses on three practical goals: memory-safe batch loading, smooth loading-screen updates, and smart repeat launches when a previous warmup already matches the current content set.

What problem does it solve?

Many UE projects hitch the first time a player reaches heavy content because shaders, PSOs, textures, and package dependencies are being touched for the first time. PSO Autopilot shifts that work into a startup preparation phase.

The goal is not to hide every possible runtime hitch. The goal is to make common first-run startup costs predictable, visible, and less disruptive.

Is this only for large games?

No. Large projects benefit from the memory-safe batching, but smaller projects can also benefit from fewer first-play stutters and a cleaner startup flow. The presets let you choose how conservative or aggressive the warmup should be.

Does it compile shaders in the background?

It drives Unreal's native shader and PSO preparation path by loading selected content, gathering materials and primitive data, and requesting PSO precache work. The work is time-sliced so the loading screen can keep updating.

Does it remove every possible stutter?

No plugin can guarantee that. Runtime stutters can come from streaming, spawning, physics, animation, IO, Niagara, plugin code, driver behavior, or content that was never included in the warmup set.

PSO Autopilot reduces a specific and common class of startup and first-play hitches by preparing the content you target.

Where can I get it or ask for help?

Use the Fab listing for the product page and the Discord server for support, setup questions, and troubleshooting.

Setup Wizard

The beginner path configures the production pipeline without requiring manual Blueprint wiring.

How do I install the plugin?
  1. Copy the PSOAutopilot folder into your project's Plugins folder.
  2. Regenerate project files if your project uses C++.
  3. Compile the project.
  4. Open the editor and enable the plugin if Unreal prompts you.
Where is the setup wizard and what does it do?

Open Unreal Engine and choose Window > PSO Autopilot Startup Setup. The wizard provides a One-Click Simple Setup flow to guide your configuration. It features a Project-Aware Preflight Validator that scans your active project, generates an Automatic Readiness Card with color-coded results, and provides instant inline Fix buttons for safe items. The wizard header also displays the installed plugin version (e.g. PSO Autopilot v1.3.2) so you can confirm which build you are running.

Where is the /Game/PSOAutopilot folder? I cannot find it in my project.

/Game/ is a path prefix, not a folder name. Unreal uses it to refer to your project's Content/ folder. On disk and in three different names, these are the same place:

  • On disk: YourProject/Content/
  • In the Content Browser sidebar: the node labeled Content
  • In Unreal paths: /Game/

So /Game/PSOAutopilot/PSOAutopilot_Loading means a level named PSOAutopilot_Loading inside a folder named PSOAutopilot inside your project's Content/ folder.

The PSOAutopilot subfolder is not created on install. It appears the moment you click one of the wizard's Create buttons (loading level or loading widget). Until then, the path is just a default the wizard intends to create; it is not a missing asset.

To navigate to it: open the Content Browser, click the Content node in the left sidebar (under All), and look for the PSOAutopilot folder once it has been created. Do not click Engine — that node shows engine and plugin C++ classes, which are not your project's content.

What should I choose in Simple Setup?
  • Loading Level: the lightweight level loaded first, where the PSO Autopilot Loader actor and the loading screen live before Level To Open After Warmup opens. Leave empty to let the wizard create one at /Game/PSOAutopilot/PSOAutopilot_Loading, or point this at an existing world asset you have already built (added in 1.2.1).
  • Level To Open After Warmup: the map players should reach after preparation finishes. This is the same destination concept as the Boot Loader's Level To Open After Warmup; it can be a main menu, hub, or gameplay map depending on your startup flow.
  • Loading Screen: your widget class, or the wizard-created editable templates at /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen (plus _Minimal and _Telemetry variants).
  • Content to Prepare: folders that contain startup-critical assets.
  • Quality Preset: Safe Startup, Balanced, or Fast Warmup.
  • Skip When Already Prepared: enabled for normal production startup.
  • Prepare Textures Early: enabled when first-frame texture pop-in matters.
  • Editor Iteration Mode: use Unreal's editor compilation for daily PIE work, or run the full PSO Autopilot warmup when you want to validate the loading flow inside editor preview.
  • Optional advanced foldout: if you stay in Simple Setup but want to make the final pipeline-cache wait easier to observe during validation, expand the advanced controls and lower Min PSO Queue To Wait.

The Loading Level and Level To Open After Warmup must be different. The picker shows the standard asset browser, so you do not need to type a path manually.

Can my game open the main menu first before gameplay?

Yes. Use the map players should land in immediately after PSO Autopilot finishes. If your product flow is loading screen → main menu → player selects gameplay, then Level To Open After Warmup and the Boot Loader's matching destination field should usually be your main menu. Do not send players into a random gameplay map just to satisfy the label.

The important distinction is:

  • Loading Level: the lightweight boot map that contains the PSO Autopilot Loader and runs startup preparation.
  • Level To Open After Warmup: the destination map opened after preparation, such as your main menu.
  • Content to Prepare: the folders, maps, blueprints, materials, characters, UI, VFX, and other startup-critical assets you want warmed before the destination appears.

So a menu-first game should usually be configured as PSO_Level → MainmenuLevel, with gameplay assets covered by Content to Prepare, explicit warmup assets, Primary Asset Labels, or runtime calls to RegisterRuntimeWarmupAsset(...). The main menu destination does not automatically prove that all later gameplay assets were discovered.

If you have a language picker, account screen, splash map, or other custom startup map before the PSO loading level, any shader hitches in that earlier map happen before PSO Autopilot can run. Keep those pre-PSO maps extremely lightweight, move that UI into the PSO loading level, or make the PSO loading level the real first map.

What does Allow Custom Startup Level do?

Allow Custom Startup Level only suppresses the setup warning that normally expects your project startup map to be the PSO Autopilot Loading Level. It does not make the custom startup map run PSO Autopilot automatically, and it does not warm content that appears before the PSO loading level opens.

Leave it off for the standard flow: your packaged game starts directly in the PSO loading level, PSO Autopilot prepares content, then the Boot Loader opens Level To Open After Warmup.

Turn it on only when you intentionally boot into another map first, such as a language picker, account login, legal screen, launcher handoff, or custom splash flow. In that case, that earlier map is your responsibility: keep it extremely lightweight, or manually transition to the PSO loading level before showing shader-heavy UI, materials, meshes, or animation.

If your flow is intro movie → PSO loading level → language menu → main menu, the PSO loading level should still be the configured startup map after the movie system hands off to gameplay. If you instead start in the language menu or another real map before PSO Autopilot, enable Allow Custom Startup Level deliberately and accept that pre-PSO content is outside the plugin's protection.

If logs show hitches or new PSOs before LogPSOAutopilot: Starting PSO Autopilot Warmup..., Allow Custom Startup Level is a common reason. Those hitches happened before the plugin's warmup phase had control.

What does Create/Update Startup Flow do?

It creates or opens the default loading level, places or updates a PSO Autopilot Loader actor, sets the loading level as the project startup map, and applies the selected simple setup choices.

Run it again after changing Loading Level, Level To Open After Warmup, Content to Prepare, package-preload flags, or startup behavior. The loading level stores a serialized loader actor, so old actor values can survive until the startup flow is updated.

Current builds also update both GameDefaultMap and EditorStartupMap for the standard simple setup flow, so opening the editor and packaging use the same loading level unless you intentionally enable a custom startup map.

Why does the validator say my loader is out of sync?

The validator compares the placed PSO Autopilot Loader actor against the current Simple Setup snapshot. It now checks the destination level, whether the destination is registered as a warmup seed, package-preload behavior, and whether warmup starts on BeginPlay.

This is a blocking setup issue because packaged maps contain the serialized actor settings from the loading level. If you changed Simple Setup from a gameplay map to a main menu, or changed the content folders after creating the loader, click Create/Update Startup Flow so the placed actor is rewritten with the current values.

If Allow Custom Startup Level is off and the project startup map is not the PSO loading level, the validator reports an error rather than a soft warning. That means the packaged game can start somewhere PSO Autopilot never controlled.

Why does pressing Play in the editor skip PSO Autopilot?

Current builds default Editor Iteration Mode to Use Unreal Editor Compilation. In PIE, Editor, Editor Preview, and Game Preview worlds, PSO Autopilot completes immediately before starting its warmup path so Unreal can use the normal editor shader compilation behavior.

This does not disable packaged builds. Switch Editor Iteration Mode to Run PSO Autopilot Warmup, use Standalone Game, launch with -game, or make a Development package when you want to validate the complete startup warmup.

What does the Project-Aware Preflight Validator check?

The validator generates an Automatic Readiness Card by scanning Level To Open After Warmup, the loading level, loading widget, content folders, cook settings, package preload paths, boot map separation, batch size, ignored content types, and whether the startup loader is present. You can resolve issues instantly using the provided inline Fix buttons.

Is Simple Setup less powerful than Advanced Mode?

No. Simple Setup writes a beginner-friendly settings snapshot that feeds the same runtime subsystem. Advanced Mode exposes the lower-level controls for teams that need more precise targeting and tuning.

Which preset should I use?

Balanced is the recommended default. Safe Startup lowers risk for large or memory-sensitive projects by using more conservative batch behavior. Fast Warmup spends more frame time during loading and is best for smaller projects with comfortable memory headroom.

Do I need a custom loading screen?

No. The wizard can create editable Widget Blueprint templates at /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen plus _Minimal and _Telemetry siblings. These project-owned assets are parented to UPSOAutopilotEditableLoadingScreenWidget, so you can edit them directly in UMG without runtime layout injection.

The older UPSOAutopilotLoadingScreenWidget class still exists, but it is now the native fallback convenience widget only. Use it when you explicitly want the stock runtime-generated layout; use the wizard templates when you want an editable project asset.

The widget asset itself does not exist until you click the wizard's Create Widget fix button on the loading-screen preflight row. Before then, the path is just a default the wizard intends to create; the preflight warning is expected on a fresh install.

Where does the wizard show the installed plugin version?

The wizard's logo banner displays the version (e.g. PSO Autopilot v1.3.2) directly beneath the logo. The value comes from the plugin descriptor's VersionName, so a project that bundles an updated plugin reflects the new version on the next editor launch without any code change.

How It Works

The runtime is a state machine that scans, fingerprints, loads, prepares, streams, cleans up, and completes.

Scan
Find startup content
Hash
Check smart skip
Load
Batch content safely
Prepare
Warm PSOs and textures
Travel
Open gameplay map
Why does it use batches?

Loading everything at once can spike memory and freeze the loading screen. PSO Autopilot loads a controlled number of content items, prepares them, releases references, and optionally forces garbage collection before the next batch.

How does it keep the loading screen responsive?

The subsystem spends only a configured amount of game-thread time per frame on preparation work. The default advanced budget is 5.0 ms, and presets adjust this for safer or faster behavior.

What engine systems does it use?

It uses standard Unreal Engine APIs such as FStreamableManager, the Asset Registry, material PSO precache APIs, texture streaming controls, package loading, and garbage collection.

What progress messages should players see?

Player-facing messages are intentionally plain: finding startup assets, checking previous warmup, loading assets in safe batches, preparing shaders, preloading gameplay map, and ready.

Technical status is available separately through Get Technical Status Message and the optional telemetry panel.

How is the progress bar value computed across the warmup?

On Startup Preparation Progress reports a single 0.0–1.0 value, but PSO Autopilot maps three sequential phases into separate sub-bands so the bar stays meaningful end-to-end instead of pinning to 100% while the engine is still working:

  • 0.00 → 0.85 — asset warmup (load + PSO precache batches). Driven by Prepared Content Items / Total Content Items.
  • 0.85 → 0.95 — gameplay-map package preload. Driven by completed-vs-total package count.
  • 0.95 → 1.00 — engine pipeline cache draining (FShaderPipelineCache). Driven by 1 - Remaining / StartingBacklog.

The final 0.95–1.00 slice only runs when there is real work pending in the engine pipeline cache. After -clearPSODriverCache, a driver update, or a fresh GPU install, this slice covers the slow PSO compile pass — the loading screen stays up and the bar keeps advancing instead of handing off to OpenLevel while pipelines are still compiling.

The status text during the final slice reads Compiling engine pipeline cache: N of M PSOs remaining, X.Xs elapsed. through Get Technical Status Message.

What happens after preparation finishes?

The built-in loader can release retained preload references and open Level To Open After Warmup. Custom flows can bind to On Startup Preparation Complete and decide what to do next.

Can warmup be cancelled?

Yes. The subsystem exposes Stop Preparing Startup Content through Blueprint and StopWarmup() in C++. It resets state, releases loaded content, and broadcasts completion.

Can I play an intro video while shaders compile?

Yes. Use the PSO Autopilot Cinematic Loader (Epic Pro Upgrade). Assign an MP4/MediaSource to it, and it will play the video while compiling. If compilation finishes early, it enables a "Press Any Key to Skip" prompt. If the video finishes but compilation is still running, it seamlessly crossfades to a looping fallback UI spinner.

Can I compile shaders in the background during gameplay?

Yes. The Just-In-Time (JIT) Micro-Warmups feature provides a Blueprint node: Warmup Actor Class (Time-Sliced). This is perfect for calling right before a massive boss spawns, ensuring zero hitches by warming the asset in the background over several frames without freezing active gameplay.

How do I eliminate stutter in open-world/World Partition games?

Use the Spatial / World Partition Warmup component. Attach the PSOAutopilotSpatialComponent to your Player Pawn. As the player traverses the world, the plugin uses the time-sliced chunking engine to silently warm up the materials of grid cells just outside the loading radius.

Content Targeting

Good results depend on selecting content that represents what players touch immediately after loading.

What content should I prepare?

Start with the destination map or main menu, startup characters, weapons, UI widgets and UI materials, VFX that appear immediately, common environment assets, and folders that hold first-play content.

For PSO coverage, prioritize the assets that use materials: maps, static meshes, skeletal meshes, character and weapon Blueprints, Niagara/VFX systems, widgets, landscape/environment folders, and data-driven startup content roots. Material folders are useful support entries, but they are rarely enough on their own.

What belongs in Content to Prepare?

Use folders that represent what the player can see or load soon after startup. Good entries are usually broad runtime-content roots, not dozens of tiny material-only subfolders.

  • Maps and menu/UI: your main menu map, first playable maps, UI widget folders, UI material folders, and immediately visible loading/menu art.
  • Actors and gameplay objects: character, weapon, vehicle, pickup, enemy, and interactable Blueprint folders used near startup.
  • Meshes and environments: static mesh, skeletal mesh, Nanite, landscape, water, prop, and first-area environment folders.
  • Effects: Niagara, particle, decal, post-process, and material effect folders that appear before or shortly after gameplay begins.
  • Data-driven roots: Primary Asset Labels, loadout/cosmetic selections, or explicit assets for content loaded by strings, save data, DataTables, or runtime choices.

Keep paths as Unreal package folders such as /Game/FirstPerson/Weapons or /Game/Environment/Waterpark. Do not use Windows paths, individual object paths, or editor-only folders.

Are material folders enough?

Usually no. A PSO is not just a material shader; it is a combination of material, mesh type, vertex factory, render pass, render state, platform, and RHI. Warming only material folders may compile some shader data but still miss the real combinations created by static meshes, skeletal meshes, Niagara, Nanite, landscapes, and UI widgets.

Material folders are good secondary targets. For stronger results, also include the folders containing the maps, meshes, actor Blueprints, widgets, and VFX that actually reference those materials.

Should I just scan all of /Game?

For small projects, scanning /Game can be acceptable, but targeted folders are safer and faster. For larger projects, target the folders and explicit assets needed for startup. Broad scans increase startup work and can include content players will not see for a long time.

Do not add /Game to Additional Asset Directories to Cook or DirectoriesToAlwaysCook unless you intentionally want Unreal to cook the whole project. The setup wizard now avoids adding that root cook entry and can remove it when the validator finds it.

What are explicit warmup assets?

Explicit assets are specific maps, blueprints, materials, or other objects you want prepared even if they are not found by folder scanning. They are useful for soft-referenced systems and important startup assets.

Does Content to Prepare scan subfolders recursively?

Yes. If you add a root such as /Game/SomeFolder, PSO Autopilot scans that folder recursively, so assets in child folders such as /Game/SomeFolder/Materials, /Game/SomeFolder/Meshes, and deeper subfolders are included automatically.

This recursion only covers folders beneath the path you selected. Include Referenced Content is a separate feature that follows package references outside that folder tree.

Use Unreal package paths like /Game/SomeFolder. The examples in the docs use the no-trailing-slash form.

What does Include Referenced Content do?

It expands the warmup set by following package dependencies from selected roots. This helps catch materials and assets reachable through maps, actor blueprints, component templates, primary asset labels, and soft references.

How deep should dependency expansion go?

Depth 1 is a practical default for many projects. Increase it when important startup assets are several references away. Reduce it if the warmup set becomes too broad.

How do I handle dynamically selected startup content?

Call RegisterRuntimeWarmupAsset(...) before starting the warmup. This is useful for selected characters, cosmetics, loadout assets, modular content, or boot flows that decide content at runtime.

Can I exclude content types?

Yes. Advanced Mode includes content types to ignore. Use this when a scan picks up unnecessary or unstable object types that should not be loaded during startup preparation.

Why did PSO Autopilot find zero assets?

Common causes are blank folder entries, invalid package paths, missing cook settings, scanning an empty folder, or relying on content that is only reachable through references while dependency expansion is disabled.

Run the setup validator first. Then check that folder paths use Unreal package paths such as /Game/Characters, not Windows paths.

Why did I add many folders but only see one startup asset?

Folder count is not processed-item count. The loading screen counts discovered warmable assets inside those folders, not the number of folder entries. Adding 48 folders does not mean the UI should process 48 items.

If a packaged build shows only 1, that is often the destination map seed registered by the Boot Loader. It usually means your configured folders contributed zero runtime-discoverable warmup assets. Check that the folders are valid /Game/... package folders, contain warmable runtime assets, are cooked/staged, and are visible in the packaged AssetRegistry.

The setup validator now previews the warmup discovery breakdown by type. In packaged logs, look for Warmup settings:, Warmup asset discovery details:, and the scan-folder samples printed around discovery. Those lines show whether Content to Prepare reached the runtime snapshot and whether the packaged AssetRegistry could see the folders.

If the only discovered item is the destination seed, treat it as a setup/cook problem rather than a shader-count problem. The usual causes are stale Simple Setup data, a loader actor that was not updated after the content list changed, folders that were not cooked, or folders that contain editor-only/non-warmable assets.

Blueprint And C++

Use the one-node flow for the common path or the subsystem API for custom startup pipelines.

What is the simplest Blueprint setup?

Call Start PSO Autopilot Loading Flow. Set Level To Open After Warmup, optional loading widget, and options. The node registers the destination level, queues package preload, shows the widget, starts preparation, releases retained preload, and opens the destination level.

How do I build a custom loading screen flow?
  1. Open a lightweight loading level first.
  2. Get the PSO Autopilot Subsystem from the Game Instance.
  3. Bind On Progress Updated to your loading bar and status text.
  4. Register any runtime-selected content.
  5. Call Start Preparing Startup Content.
  6. On completion, travel to the gameplay map.
Can I use a fully custom UMG widget without inheriting from UPSOAutopilotLoadingScreenWidget?

Yes. The bundled UPSOAutopilotLoadingScreenWidget is convenience-only, and the wizard's editable assets now use UPSOAutopilotEditableLoadingScreenWidget instead. The subsystem exposes its full API to Blueprint, and Start PSO Autopilot Loading Flow accepts any TSubclassOf<UUserWidget>, so a plain Widget Blueprint parented to UserWidget works without C++ inheritance.

The boot loader and one-node loading flow now auto-update any widget that implements PSOAutopilotLoadingScreenReceiver. If your widget does not implement that interface, you can still bind to the subsystem delegates manually.

Option A — Editable template path: use the wizard-created /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen asset (or the _Minimal / _Telemetry siblings) and customize the layout directly. Those widgets inherit from UPSOAutopilotEditableLoadingScreenWidget, so the plugin updates optional bindings like WarmupProgressBar, WarmupStatusText, WarmupProgressSummaryText, and the optional telemetry widgets when they exist.

Option B — Pure BP widget with the one-node flow:

  1. Create a Widget Blueprint based on plain UserWidget, optionally implementing PSOAutopilotLoadingScreenReceiver.
  2. On Event Construct, call Get Game Instance SubsystemPSO Autopilot Subsystem.
  3. Bind On Startup Preparation Progress to drive your progress bar and status text.
  4. Bind On Startup Preparation Complete to your fade-out animation, then Remove from Parent.
  5. Pass this Widget Blueprint class into the Loading Widget input on Start PSO Autopilot Loading Flow.

Option C — Manual sequencing (skip the helper entirely):

  1. Create WidgetAdd to Viewport with your Widget Blueprint.
  2. Call Start Preparing Startup Content on the subsystem.
  3. On On Startup Preparation Complete, call Release Loaded Content for any package you queued with Load Package Before Play, then Open Level, then remove your widget.

Useful BlueprintPure getters for driving your own UI: Get Technical Status Message, Get Prepared Content Items, Get Total Content Items, Get Current Progress Summary Text, Get Completed Preparation Steps, Was Preparation Skipped, Is Demo Hold Active, Get Demo Hold Remaining Seconds.

Ready-made templates: use Tools > PSO Autopilot > Create/Open Loading Widget Templates or run Scripts/CreateEditableLoadingWidget.py from the project. The workflow generates /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen, WBP_PSOAutopilotLoadingScreen_Minimal, and WBP_PSOAutopilotLoadingScreen_Telemetry, each with a populated Designer tree and a visible Event Graph seeded with the expected parent calls. The default template is also assigned to PSO Autopilot Loader actors when the script can find them.

How do I show a black screen instead of the loading UI on repeat startups?

When Smart Cache Skip is enabled, you may want to hide the UI while the game is only waiting on background engine tasks (Asset Registry scanning and Map preloading). The cleanest approach uses the state-based getter; the older string-matching approach is kept below for reference.

Option 1 (Recommended): Gate on warmup state via Is Compiling Shaders

  1. Open your loading widget.
  2. Wrap your entire UI (progress bar, text, spinner, etc.) inside a Canvas Panel or Overlay, leaving a black background image behind it.
  3. Set the UI container's default Visibility to Hidden.
  4. On Event Tick (or a 4–10 Hz timer): get the PSO Autopilot Subsystem and call Is Compiling Shaders.
  5. If True, set the container's Visibility to Self Hit Test Invisible. If False, keep it Hidden.

Is Compiling Shaders returns true only while the subsystem is in ProcessingBatch, StreamingTextures, or FlushingPipelineCache. It does not fire during the brief scan/fingerprint phases that run on every boot, including cached ones — so the UI stays hidden when Smart Skip matches. If you need finer control, call Get Current Preparation State and switch on the EPSOWarmupState enum directly.

Option 2 (Legacy): String matching on the status message

  1. Open the widget and wrap the UI as above.
  2. In your progress-update handler, check if the friendly StatusMessage contains "Preparing shaders".
  3. If True, show the UI; if False, hide it.

This works but is brittle: status strings are localizable and can change between releases. Prefer Option 1 in new code.

Option 3: Using Was Preparation Skipped (Show UI during scan, hide on match)

  1. Get the PSO Autopilot Subsystem.
  2. Call Was Preparation Skipped.
  3. If True, set your UI container Visibility to Hidden.
  4. This will show the "Checking..." UI for ~1 second and then immediately go black once the cache matches.
Which Blueprint events should I bind?

Bind On Startup Preparation Progress for progress and status text. Bind On Startup Preparation Complete for travel, menu reveal, or other handoff behavior.

How do I show a "remaining seconds" estimate on the loading screen?

The subsystem exposes two BlueprintPure helpers for this:

  • Get Estimated Remaining Seconds — returns a float. A negative value means "no estimate available yet" (very early in the warmup, while idle, or right after a Smart Skip). Treat that as "hide the label."
  • Has Estimated Remaining Seconds — convenience boolean; true only when the seconds value is usable.

Recommended Blueprint pattern in your loading widget's Event Tick (or a 4–10 Hz timer):

Has Estimated Remaining Seconds?
  True   → Get Estimated Remaining Seconds
           → Format Text "~{0} s remaining" (round/floor as needed)
           → Set Text on your ETA label, Set Visibility = Visible
  False  → Set Visibility = Hidden  (or display "Estimating...")

The estimator is phase-aware: during FlushingPipelineCache it uses the real PSOs-per-second drain rate from FShaderPipelineCache, which is exactly the slow phase players notice most after a cold start or a wiped driver cache. During the asset and preload phases it falls back to linear extrapolation from the overall progress fraction. The returned value is cached internally for 0.25 s so a tick-bound binding is cheap and the displayed number does not jitter.

What C++ class owns the runtime behavior?

UPSOAutopilotSubsystem is the runtime core. It is a Game Instance subsystem and a tickable object, so it can run across the loading flow and report progress every frame.

What does the Boot Loader actor do?

APSOAutopilotBootLoader is a production-friendly actor for loading levels. It can apply simple setup settings, show the loading widget, register Level To Open content, queue package preload, start warmup, and open the destination level when ready.

It exposes the following Blueprint-callable events and functions:

  • On Startup Preparation Progress (event) — forwards (Progress, StatusMessage) to your Blueprint so you can drive a custom progress bar.
  • On Startup Preparation Finished (event) — fires when warmup completes. Use this to show a confirm button, swap widgets, or start your own transition.
  • Dismiss Loading Widget (function, added 1.2.1) — removes the loading widget from the viewport. Call this from your custom flow (e.g. after a confirm-button click) when you want to tear the widget down without relying on the next Open Level call to clear it.
How do I show a confirm button instead of auto-opening Level To Open?

Disable Auto Open Level on the Boot Loader actor. Starting in 1.2.1, when Auto Open Level is off the loading widget is no longer auto-removed by the loader — your Blueprint owns the rest of the flow.

Recommended pattern:

  1. In the Boot Loader actor's Details panel, uncheck Auto Open Level. (You can leave Remove Loading Widget When Ready at its default; it is ignored while Auto Open Level is off.)
  2. In your loading widget, add the confirm button hidden by default.
  3. Bind to the Boot Loader's On Startup Preparation Finished event and set the button's visibility to Visible.
  4. On the button's click handler, call Open Level (by Name) with your target map, then optionally call the Boot Loader's Dismiss Loading Widget function. Opening a level clears widgets automatically, so Dismiss is only needed if you want to hide the widget while staying in the current level.

Before 1.2.1 the loader removed the widget as soon as warmup completed, which yanked the confirm button out from under the player — on a fresh boot the timing might appear to work in PIE, but smart-cache-skip would remove the widget the same frame it was added in packaged builds (black screen on the second run). Upgrading to 1.2.1 resolves both cases.

Can I use my own save system or menu flow?

Yes. Run PSO Autopilot after you know the startup content set. Register dynamic assets first, start warmup, and continue your own flow on completion.

Performance And Memory

Tuning controls trade startup duration against memory pressure and loading-screen smoothness.

What controls memory use?

The main controls are Items Per Step, content targeting, dependency depth, and Clean Memory Between Steps. Smaller batches and cleanup between batches reduce peak memory at the cost of more startup time.

What controls loading-screen smoothness?

Frame Time Budget (ms) controls how much preparation work happens per frame. Lower values protect UI smoothness. Higher values finish faster but can make animations or videos less smooth on slower machines.

Why not load every asset at once?

Large projects can have thousands of assets and massive dependency graphs. Loading everything at once can produce RAM spikes, frozen UI, and out-of-memory crashes. PSO Autopilot's core value is doing this work in safer steps.

What should I do for a memory-sensitive project?

Use Safe Startup, keep content targeting focused, keep dependency depth low, and leave cleanup between batches enabled. Test on the lowest-memory hardware you intend to support.

What should I do if startup takes too long?

Reduce the content set, lower dependency depth, disable unnecessary texture preheat, or move from Safe Startup to Balanced or Fast Warmup. Make sure Smart Skip is enabled for repeat launches.

What should I do if the loading screen freezes?

Lower the frame time budget, reduce items per step, use Safe Startup, and check whether your own loading screen is doing heavy work. If video playback is involved, validate on target hardware.

How do I make the loading screen adapt to the user's hardware?

Enable Adaptive Frame Pacing (now available as an Epic Pro Upgrade). It acts as a dynamic governor, expanding the PSO budget on high-end hardware and aggressively throttling it down on constrained hardware to guarantee a buttery-smooth loading screen automatically.

My loading takes too long. How do I find the heaviest materials?

Use the "Bloat Finder" Profiler Dashboard. Run a startup validation in the Editor, then open Window > Tools > PSO Autopilot Bloat Profiler to see a live, sortable dashboard of the "Top 10 Heaviest Assets". Double-click any row to instantly open the unoptimized asset and fix it.

Are there built-in timeouts?

Yes. The pipeline includes recovery behavior for stalled batch loading, fingerprint work, texture streaming, package preload, and engine pipeline cache flush cases so a single bad item is less likely to stall startup forever.

What do the Advanced > Pipeline Cache settings do?

Three settings control whether the warmup waits for Unreal's engine PSO pipeline cache to finish compiling before completing:

  • Wait For Engine Pipeline Cache (default on) — master toggle. When enabled, the warmup enters a FlushingPipelineCache state at the end of the run and keeps the loading screen up while FShaderPipelineCache::NumPrecompilesRemaining() drains. Disable it if you prefer the historical behavior of completing as soon as asset batches are done.
  • Min PSO Queue To Wait (default 50) — backlog threshold. If fewer PSOs are pending than this number when the warmup is otherwise complete, the wait is skipped. Keeps already-warm boots snappy and avoids a noticeable pause for a tiny tail of pipelines. In current builds this is available in Advanced > Pipeline Cache and also in the optional advanced foldout inside Simple Setup.
  • Max Wait Seconds (default 120) — safety cap. If the pipeline cache hasn't drained within this many seconds, the warmup completes anyway and a warning is logged. Prevents content with a stuck PSO from holding the loading screen open indefinitely.

The wait drives the final 0.95–1.00 progress band and is what makes the bar advance smoothly during the slow PSO compile pass after -clearPSODriverCache, driver updates, or a fresh install.

Can I use different warmup tuning per platform?

Yes (1.3.2). Under Advanced > Per-Platform, add a Per-Platform Performance Override for any of Windows, Mac, Linux, Android, or IOS. When the game runs on the named platform, the override replaces the effective Items Per Step, Frame Time Budget, Clean Memory Between Steps, Min PSO Queue To Wait, and Max Wait Seconds — so a console or phone can run gentler tuning than desktop from one project.

The rules are deliberately strict so nothing changes by accident:

  • Enabled and the name matches the running platform → the override's values are used.
  • Disabled → ignored, so you can keep a tuned override configured without applying it.
  • Name does not match → ignored; that platform keeps the base Project Settings tuning.

Only those six performance fields are affected. Content targeting, dependency expansion, and texture pre-heating are unchanged. The overlay is applied when the runtime warmup snapshot is captured, so it composes cleanly with the Simple-Setup presets.

Smart Cache Skip

Repeat launches can skip preparation when the same startup set has already completed successfully.

What is Smart Cache Skip?

Smart Cache Skip checks whether the current startup content fingerprint has already completed on the local machine. If it matches, PSO Autopilot skips the asset warmup and continues immediately.

Matched cache runs also bypass demo minimum-duration holds. This remains true after an Unreal restart even if the engine reports a temporary fresh-process pipeline-cache backlog.

What is included in the fingerprint?

The fingerprint is based on the engine context, selected content, scan configuration, and asset information. When the startup set changes, the fingerprint changes and a fresh warmup is expected.

Why is the first launch slower than the second launch?

The first launch prepares content and records completion. A later launch with the same fingerprint can skip preparation because the previous run already completed successfully. If a run finishes with asset-load or package-preload warnings, the fingerprint is intentionally not stored.

How do I force a cold run for testing?

Disable Skip When Already Prepared or call Clear Smart Skip History. The demo overlay also supports cold-vs-cached validation flows.

Can different startup configurations coexist?

Yes. The completion history stores multiple completed fingerprints so different startup paths do not have to overwrite one another immediately.

Does Smart Skip mean the GPU driver cache is guaranteed warm?

No. Drivers, engine changes, settings, and platform behavior can still affect cache state. Smart Skip means PSO Autopilot has a matching completed record for the selected startup configuration.

Current builds add two safeguards so a matched fingerprint never short-circuits a real cold start:

  • Command-line flag detection. If the engine was launched with -clearPSODriverCache (or -clearShaderCache), Smart Skip is bypassed automatically. The driver-side PSO cache is gone and the warmup must run to repopulate it. The log line Smart cache skip not used. ... DriverCacheClearedFlag=true confirms the gate fired.
  • Empty-precompile-queue check (strict, opt-in). When Require Empty Precompile Queue is enabled (Advanced > Smart Skip), Smart Skip will not be honored while FShaderPipelineCache::NumPrecompilesRemaining() is non-zero. This catches driver updates, fresh installs on new GPUs, and other cases where the asset fingerprint matches but the GPU pipelines aren't actually warm. Off by default because on a healthy repeat boot the engine briefly has PSOs queued while it loads .upipelinecache — they compile near-instantly against the warm driver cache, but enabling this strict mode would treat that window as "cold" and bypass the skip incorrectly, briefly flashing the loading UI on every boot. Turn it on if you want extra defense at the cost of occasional false positives.
How do I keep Smart Skip from short-circuiting after I clear the GPU PSO cache?

You don't have to do anything special — the safeguards above run automatically. The most common ways to deliberately force a fresh warmup:

  • Pass -clearPSODriverCache on the command line. Engine wipes the driver-side cache at startup; PSO Autopilot sees the flag and skips the smart-skip path for that run.
  • Call Clear Smart Skip History from Blueprint or C++. Wipes the stored fingerprints; the next launch runs a cold pass.
  • Toggle Skip When Already Prepared off in settings.

See the Packaging section for the full first-time-player simulation workflow, including the log markers that confirm the safeguards fired.

Does leaving Skip When Already Prepared enabled invalidate a -clearPSODriverCache test?

No. Leaving Skip When Already Prepared enabled does not invalidate a cold-run validation when you launch with -clearPSODriverCache.

Current builds bypass Smart Skip automatically when the engine was started with -clearPSODriverCache or -clearShaderCache. In logs, confirm the cold path with LogPSOAutopilot: Smart cache skip not used. ... DriverCacheClearedFlag=true.

If that line is present, you got a real first-run warmup even if the checkbox stayed on. Turning the checkbox off is still a valid manual way to force a fresh run, but it is not required when the clear-cache flag is already in use.

Textures

Texture preparation helps reduce blurry pop-in and virtual texture readiness issues during the first playable moments.

What does Prepare Textures Early do?

It asks Unreal to keep relevant UTexture2D mips resident for a period during startup preparation. This can reduce blurry textures when gameplay starts.

Does it support virtual textures?

Yes. Advanced settings include standard texture readiness and virtual texture readiness. The plugin tracks virtual-textured UTexture2D resources and waits for pending init or streaming where applicable.

Why do textures still pop in?

The content may not be included in the warmup set, the streaming pool may be too small, the material may be introduced after startup, or the platform may need more time to stream higher mips.

Can texture preheat increase memory use?

Yes. Keeping high-resolution mips resident uses memory. Disable it or narrow content targeting if startup memory becomes too high.

Packaging And Platforms

Packaged builds need the loading map, gameplay map, and warmup content cooked and staged correctly.

Does it work in packaged builds?

Yes. Package validation has covered Win64 editor, development game, and shipping game plugin builds. For your project, always validate the exact target platform and configuration you intend to ship.

What should I include in packaged maps?

Include the loading level and every map you can open immediately after warmup, including Level To Open After Warmup, language menus, main menus, hubs, and any custom handoff maps. If you use the demo, include /Game/Demo/Demo_BootFlow and /Game/Demo/Demo_PSOTorture.

Blueprint string paths and manual OpenLevel calls do not always create a cook reference. Add exact maps under Project Settings → Packaging → List of maps to include in a packaged build when the map is part of startup travel.

Why does the loading UI fade away and nothing opens after warmup?

Older builds could remove the loading widget before the final destination package was proven to exist, so a failed travel looked like the UI faded out and then nothing happened. Current builds check the destination package first and keep the loading widget visible with an actionable error if the package is missing.

The key log is usually similar to LoadPackage: SkipPackage: /Game/FirstPerson/UI/LanguageMenuLevel - The package to load does not exist on disk or in the loader. That means the map was not cooked or staged under that package path.

Add the exact destination map, for example /Game/FirstPerson/UI/LanguageMenuLevel, to packaged maps, or add the containing folder to Additional Asset Directories to Cook. Then rerun Create/Update Startup Flow if Simple Setup changed, package again, and verify the packaged log shows the destination package exists before travel.

What should I cook?

Cook the loading level, Level To Open After Warmup, and the targeted folders that contain startup content you expect to prepare. The setup validator can add recommended cook directories for common simple setup cases.

Avoid +DirectoriesToAlwaysCook=(Path="/Game") unless your intent is to cook the entire project. That root entry can make packaging look like it drops normal reference-based cooking and recooks everything. Current wizard fixes use specific folders and can remove the stale root entry.

Why did packaging start cooking almost everything?

Check whether /Game was added to Additional Asset Directories to Cook or to DirectoriesToAlwaysCook in config. A root cook directory tells Unreal to always include all project content.

Run the setup validator and use the Remove /Game fix if it appears. Then add only the loading map, gameplay map, and startup-critical folders such as /Game/Demo, /Game/DemoMaterials, or your real content folders.

Can I upload this to Fab as a plugin package?

Fab packages should use a clean plugin folder with descriptor metadata, source, resources, docs, and platform binaries generated by Unreal's BuildPlugin workflow. Engine-version-specific packages should be stamped for the target engine version.

Use the Fab listing for the buyer-facing product page.

Can I check warmup coverage automatically in CI?

Yes (1.3.2). The headless PSOAutopilotCoverage commandlet resolves your configured warmup content through the asset registry, prints a per-type report, and returns a non-zero exit code when the discovered asset count falls below a floor — turning a moved folder, a rename, or a missing cook entry into a failed build:

UnrealEditor-Cmd.exe MyProject.uproject -run=PSOAutopilotCoverage -MinAssets=900

Pick a -MinAssets value a little under what your project should resolve today. If discovery craters, the gate fails before the build ships with a near-empty warmup. For a full pre-flight, Scripts/Run-CI.ps1 chains build → automation tests → the coverage gate and fails fast on the first failed stage. These are development and validation tools — nothing here is required at runtime or shipped into a packaged game.

What does Package is unloadable: Version is too old mean for plugin content?

A packaging warning such as Package is unloadable: .../Plugins/Marketplace/PSOAutopilot.../Content/... Reason: Version is too old. Min Version: 214, Package Version: 0 means Unreal could not deserialize that asset for the current engine. Those assets are not reliable cook inputs and may be absent from the AssetRegistry.

For normal projects, use the wizard-created project-owned assets under /Game/PSOAutopilot instead of referencing bundled sample assets from an Engine plugin content folder. For plugin distribution, rebuild or resave the plugin content in the target Unreal version, or remove invalid bundled demo/sample assets from the package.

This warning is separate from runtime warmup. It is a cook-time asset compatibility problem, not evidence that PSO Autopilot has started compiling shaders during packaging.

Which platforms are supported?

The plugin uses standard Unreal APIs and the descriptor lists Win64, Mac, Linux, Android, and iOS. Package and playtest each platform because shader, texture, memory, and driver behavior can differ by target.

Should I test Development or Shipping?

Use Development with logs while validating setup and demo telemetry. Use Shipping when validating the production loader path and final player experience.

How do I test a packaged build properly?

Do not judge packaged behavior from a single short launch or a single captured frame. Validate four distinct cases:

  1. Cold run, visible diagnostics. Package a Development build, launch with -log -clearPSODriverCache, and either call Clear Smart Skip History or enable Ignore Previous Runs. This forces PSO Autopilot down the real warmup path instead of the cached-skip path.
  2. Level-package preload. If Preload Level To Open Package is enabled, expect the bar to enter the 0.85 → 0.95 slice with status text like Preloading gameplay map.... That phase is driven by package-preload counts, so your asset counter may stop changing there. Use Get Current Progress Summary Text or the package-preload getters instead of treating it as an asset-warmup failure.
  3. Pipeline-cache flush. The 0.95 → 1.00 slice only appears when there is real engine pipeline-cache backlog. To make that phase easy to observe, keep Wait For Engine Pipeline Cache enabled, launch with -clearPSODriverCache, and if needed lower Min PSO Queue To Wait so smaller backlogs still hold the loading screen.
  4. Cached run. Launch the packaged game again without clear flags. A healthy cached run should skip the heavy work and complete almost immediately.

Why does the packaged game sometimes show only 0 or 1 processed items, jump straight to 85%, then open Level To Open almost immediately? That pattern usually means one of two things:

  • No real startup asset set was discovered. The processed / total counter tracks warmup assets, not shaders or PSOs. If the packaged build only finds the Level To Open seed, you may see 1. If it finds nothing useful beyond package preload, you may see 0.
  • The asset phase was skipped by Smart Skip. If Skip When Already Prepared is enabled and the fingerprint matches a previous successful run, PSO Autopilot can bypass asset batches and still continue into level-package preload.

Why can PIE show normal counts while the packaged build does not? PIE warmup runs against the editor's asset registry and uncooked project content. Packaged warmup runs against the cooked runtime asset registry and only sees staged content that actually made it into the build. Because of that, a folder that appears to produce many warmable assets in PIE can legitimately produce far fewer assets in a packaged build if only part of that content was cooked, if references were not staged, or if the packaged run is only using the gameplay-level seed.

The 85% value is not "stuck shader progress." It is the start of the dedicated level-package preload slice. If Preload Level To Open Package is enabled, the bar can move from the asset phase directly into that band even when the asset counter barely changed.

Likewise, a cold run can appear to sit at 0% or show only 1 startup asset while the log is already printing large numbers of PSO events. That does not mean "only one shader compiled." The counter is asset-based, not PSO-based. One large UWorld or one complex Blueprint can count as a single warmup asset while still generating hundreds or thousands of material and PSO precache operations underneath it.

If Level To Open opens immediately after that, the final engine pipeline-cache wait likely did not engage. The most common reasons are: the package preload finished quickly, the engine had fewer pending PSOs than Min PSO Queue To Wait, or the run was already warm and used the cached-skip path.

How do I tell which case I am seeing? Bind Get Current Progress Summary Text instead of showing only raw percentages. It switches between asset counts, gameplay-package counts, pipeline-cache PSO counts, and cached-run states. If it says Cached Run, the fingerprint skip path was used. If it says Gameplay Packages X/Y, you are in the package-preload slice, not the asset-preparation slice.

What should I check?

  • Content to Prepare / Directories To Scan should point at cooked runtime content that actually contains warmable assets.
  • Compare PSO Autopilot's warmup folders against Unreal's packaging cook list. If a folder is present in Content to Prepare or Directories To Scan but not cooked by your packaging settings, PIE can count it while the packaged build cannot.
  • Seeing those folders listed under Unreal's Additional Asset Directories to Cook is only a partial confirmation. It proves the folders were handed to Packaging, but it does not guarantee the packaged runtime will discover a large number of warmable assets inside them.
  • Do not equate cooked folder count with processed-item count. Adding 48 folders to Packaging does not mean the loading screen should show 48 processed items; the counter advances per discovered warmable asset inside those folders, not per folder path.
  • If you rely on referenced assets instead of direct folder scans, keep dependency expansion enabled.
  • For true cold validation, disable Skip When Already Prepared or clear the smart-skip history before launch.
  • If you want the final 0.95 → 1.00 PSO wait to be easier to observe during validation, lower Min PSO Queue To Wait in the pipeline-cache settings or the Simple Setup advanced foldout.

If the cold run is too fast to inspect, enable a minimum-duration hold. At the project level that is Hold Demo Screen / Minimum Demo Time (s); on the Boot Loader it is Hold Loading Widget For Demo.

For the bundled demo, the docs-recommended sequence is the same: package a Development build with logs, run once for the cold pass, then run again for the cached pass.

How do I simulate a first-time player to validate shader compilation?

"First-time startup" for a packaged build means every piece of user-machine state the game wrote on a previous run is gone. Four cache layers matter for shader testing:

  • Game's Saved directory at %LOCALAPPDATA%\<ProjectName>\Saved\ — holds GameUserSettings.ini (where PSO Autopilot's smart-cache fingerprint lives), config, savegames, and logs.
  • GPU driver PSO cache at %LOCALAPPDATA%\NVIDIA\DXCache, %LOCALAPPDATA%\AMD\DxCache, and %LOCALAPPDATA%\Intel\ShaderCache — driver-compiled pipelines from previous runs.
  • Engine stable pipeline cache (.upipelinecache shipped inside cooked content) — authored by you and only changes when you re-cook.
  • Roaming app data at %APPDATA%\<ProjectName> — some plugins or save systems put state here.

A minimal "fresh player on fresh PC" batch script:

@echo off
rem ---- adjust to your project ----
set PROJ=PSOAutopilot
set EXE=C:\PackagedBuild\Windows\PSOAutopilot.exe

rem 1. Wipe the game's saved state (config, fingerprint, savegames)
rmdir /s /q "%LOCALAPPDATA%\%PROJ%\Saved" 2>nul

rem 2. Launch -- -clearPSODriverCache wipes the NVIDIA / AMD / Intel driver caches.
rem    -log opens a console so you can watch shader activity live (Development build only)
"%EXE%" -clearPSODriverCache -log

Prefer the engine flag -clearPSODriverCache over manually deleting driver folders — it is the engine-supported path, covers NVIDIA, AMD, and Intel D3D12 in one go, and PSO Autopilot honors it so Smart Cache Skip will not bypass the warmup when the GPU driver cache has been wiped.

Is the shader autogen file log PSO Autopilot starting during packaging?

No. Lines such as Using Local Shader Compiler with 17 workers, Compiling shader autogen file: .../Intermediate/ShaderAutogen/.../AutogenShaderHeaders.ush, and Autogen file is unchanged, skipping write are normal Unreal packaging shader setup. They are not the PSO Autopilot runtime warmup starting early.

PSO Autopilot starts when the packaged game reaches the loader actor, the one-node loading flow, or your custom Blueprint/C++ call to start warmup. In logs, look for LogPSOAutopilot: Starting PSO Autopilot Warmup... to identify the plugin's runtime phase.

What log lines confirm shader compilation actually ran in a packaged build?

Launch a Development packaged build with -log and watch for these markers:

  • LogD3D12RHI: ClearPSODriverCache() — confirms the driver-cache wipe fired when -clearPSODriverCache is passed.
  • LogPSOAutopilot: Smart cache skip not used. ... DriverCacheClearedFlag=true — confirms the warmup actually ran instead of being short-circuited by a stale fingerprint.
  • LogShaderPipelineCache: Compiled X PSOs in Y ms — the engine precompile queue draining over time.
  • LogPSOAutopilot: PSO Autopilot Warmup Finished. Success=true — the warmup completed cleanly with no asset-load or preload failures.

Caveats and finer-grained options:

  • -log only opens a console window in Development and Test packaged builds, not in Shipping. To verify shader compile inside a Shipping build, scrape %LOCALAPPDATA%\<ProjectName>\Saved\Logs\ after the run, or add a small UMG widget that polls FShaderPipelineCache::NumPrecompilesRemaining() per frame and renders the value on screen.
  • For a surgical reset that keeps the player's other settings, delete only GameUserSettings.ini. That clears the PSO Autopilot fingerprint and leaves resolution, audio, and input bindings intact.
  • For the most thorough test on a representative target, run the build under a different Windows user account or inside a clean VM with GPU passthrough — that isolates driver state, registry entries, and DDC residue that a single-user wipe cannot reach.
Do I need to ship debug symbols?

Debug symbols are useful for development and support, but final distribution rules depend on your marketplace and build policy. Keep a symbol build available for diagnosing crashes even if the public package excludes symbols.

Demo

The bundled demo shows a cold startup pass, a cached pass, and the handoff from loading map to gameplay map.

What is included in the marketplace demo?
  • Boot map: /Game/Demo/Demo_BootFlow
  • Loading screen: /Game/Demo/UI/WBP_LoadingScreen
  • Gameplay map: /Game/Demo/Demo_PSOTorture
  • Gameplay overlay: /Game/Demo/UI/BP_PSOAutopilot_HUD
  • Stress content: /Game/DemoMaterials
What does the demo prove?

The demo warms startup assets, preloads the gameplay map during the loading screen, releases the retained preload before travel, opens the gameplay map, and then shows a cached run that can skip duplicate preparation.

How do I run the demo in a packaged build?
  1. Set GameDefaultMap to /Game/Demo/Demo_BootFlow.
  2. Add the demo boot map and gameplay map to packaged maps.
  3. Always cook /Game/Demo and /Game/DemoMaterials.
  4. Run once for a cold pass.
  5. Run again for a cached pass.
Can I regenerate demo assets?

Yes. Run Unreal with Scripts/CreatePSOAutopilotDemo.py through -ExecutePythonScript.

Troubleshooting

Most setup issues come from invalid paths, missing cook settings, broad scans, or content that is not included in the warmup set.

The loading screen never completes. What should I check?

Run the validator, check logs for batch load, package preload, texture streaming, and fingerprint timeout warnings, and confirm the destination map exists on disk and is cooked.

The warmup finds no content. What should I check?

Check for blank folder entries, invalid package paths, folders with no cookable content, disabled dependency expansion, or content that only exists through runtime selection and was never registered.

The game runs out of memory during startup. What should I do?

Use Safe Startup, reduce items per step, narrow content folders, lower dependency depth, leave cleanup between steps enabled, and disable texture preheat if texture memory is the problem.

The loading screen animation stutters. What should I do?

Lower the frame time budget, reduce batch size, simplify the loading widget, and validate in a packaged build. Editor behavior is useful for setup but not always representative of shipping startup.

Smart Skip always skips, but I want a fresh run.

Disable Skip When Already Prepared or call Clear Smart Skip History. For demo validation, use a cold pass followed by a cached pass.

Smart Skip never skips. What could cause that?

The content set or settings may change every launch, the previous warmup may have completed with warnings, Skip When Already Prepared may be disabled, or the completion record may have been cleared.

Also check loader/demo debug flags. Re-running the setup wizard clears stale simple-setup demo overrides such as forced fingerprint resets on existing loader actors.

It always starts cooking or preparing again after restarting Unreal.

For packaging, remove any stale DirectoriesToAlwaysCook=(Path="/Game") entry so Unreal does not cook the entire project. For runtime warmup, make sure Skip When Already Prepared is enabled and no loader is resetting the smart-skip fingerprint on begin play.

Current builds skip matched cached warmups immediately after restart, even when a fresh editor process reports a pipeline-cache backlog.

The loading widget asset path looks wrong or the folder only has a map.

Older setup data could point at the native C++ fallback widget instead of a project-owned UMG asset. The widget can still appear in Play because the C++ fallback generates UI at runtime, but there is nothing editable in your content folder.

On a fresh install the wizard references the path /Game/PSOAutopilot/WBP_PSOAutopilotLoadingScreen in DefaultGame.ini before the asset exists — that is why the Preflight Validator warns about the path on first run. Click the wizard's Create Widget fix button on that row (or run Create/Update Startup Flow) and the wizard creates the editable Widget Blueprint templates parented to UPSOAutopilotEditableLoadingScreenWidget.

If you cannot find the path in the Content Browser, remember that /Game/ is Unreal's prefix for your project's Content/ folder — not a literal folder named "Game". Click the Content node in the Content Browser sidebar and look there.

My custom Widget Blueprint elements reset to the C++ defaults when I parent it to UPSOAutopilotLoadingScreenWidget.

This is standard Unreal Engine behavior, not a plugin bug. When a Widget Blueprint is reparented to some C++ UUserWidget subclasses that declare UPROPERTY values with constructor defaults, those defaults can overwrite child Widget Blueprint values when the widget is constructed, and overriding them per-instance in the BP graph can be fragile.

Current wizard widgets avoid this by using UPSOAutopilotEditableLoadingScreenWidget, which only updates optional named bindings and never rebuilds layout at runtime. For fully custom flows, composition is still the cleanest option: keep your Widget Blueprint parented to plain UserWidget and bind to the subsystem delegates directly, or implement PSOAutopilotLoadingScreenReceiver. See Can I use a fully custom UMG widget without inheriting from UPSOAutopilotLoadingScreenWidget? in the Blueprint And C++ section for the wiring.

I saw a D3D12RHI uniform buffer crash during warmup.

Current builds throttle active PSO precache requests during time-sliced batch processing so very large material sets do not flood the renderer with unchecked background work. This includes the single-large-asset case: one oversized UWorld or complex Blueprint can still generate a huge amount of PSO work even when the warmup list only contains 1 asset, so the warmup now resumes and re-throttles inside that asset instead of only between assets.

If renderer instability persists, lower the item count per step, narrow content folders, and test in a Development packaged build with logs.

Are aqProf.dll, VtuneApi.dll, PIX, or UnrealTraceServer startup warnings related to PSO Autopilot crashes?

Usually no. Messages such as Failed to load 'aqProf.dll', Failed to load 'VtuneApi.dll', Failed to load 'WinPixGpuCapturer.dll', or a missing UnrealTraceServer.exe are common environment and profiling-tool warnings in Development builds.

When you are triaging a startup warmup failure, focus first on LogPSOAutopilot, LogRHI, LogD3D12RHI, FShaderPipelineCache, and the fatal call stack. Those lines tell you whether Smart Skip was bypassed, how many assets were discovered, whether the engine is still compiling PSOs, and where the crash actually occurred.

Does a Session CrashGUID mean the game crashed?

No. Unreal often prints a Session CrashGUID during startup so crash reporting has an ID ready if the process fails later. That line alone is not crash evidence.

A real crash log usually contains a fatal marker near the end, such as Fatal error, Unhandled Exception, LowLevelFatalError, an ensure/assert that terminates, a call stack, or CrashReportClient activity tied to the failure. A clean exit usually ends with lines like RequestExit(0), LogExit: Exiting., and Log file closed.

When reporting a suspected PSO Autopilot crash, include the final 200 lines of the log and the first fatal/callstack section, not just the startup CrashGUID.

OpenLevel fails after warmup. What should I check?

Verify the Level To Open package path, add the map to packaged maps, ensure the map is cooked, and confirm the loading level is different from Level To Open.

Current builds check FPackageName::DoesPackageExist before removing the loading widget or calling OpenLevel. If the destination is missing, the widget stays up and the log points you back to Packaging → Maps to Cook or Additional Asset Directories to Cook.

Package preload times out. What should I check?

Check that the package path is valid, cooked, and not blocked by missing dependencies. Large maps may need content targeting or platform IO checks before preload completes reliably.

If the log says Cannot preload package or package to load does not exist on disk or in the loader, treat it as a missing cook/staging issue first. Add the map explicitly to packaged maps or cook the containing startup folder, then rebuild the package.

Texture streaming times out. Is that fatal?

No. The timeout logs a warning and proceeds so startup is not trapped forever by a texture that never reports completion. Investigate streaming pool size, missing mips, virtual texture settings, and target hardware.

The editor setup works but the packaged build behaves differently.

That is usually a cook-and-staging difference, not a different runtime algorithm. PIE can enumerate assets from the editor registry, while packaged builds only see cooked staged content in the runtime asset registry. If a warmup folder, dependency chain, or gameplay map reference did not make it into the package, the packaged build can discover fewer warmable assets and appear to skip straight to package preload.

Confirm maps and warmup folders are cooked, run a Development packaged build with logs, and compare the discovered asset count, package paths, and progress-summary text against editor output. If PIE shows many assets but packaged shows 0 or 1, check the cook list, dependency expansion, and whether the packaged run is only finding the gameplay-level seed.

The plugin compiles in one engine version but not another.

Use the package built for your engine version. Unreal Engine APIs and exported symbols can differ between releases, so Fab packages should be validated per target engine version.

What logs are useful for support?

Include the Unreal log from a Development packaged run, the setup validator messages, your plugin version, engine version, target platform, selected preset, startup maps, warmup folders, and the last visible status message.

Support And Updates

Clear setup details make troubleshooting much faster.

Where should I ask for support?

Join the Discord support server for setup questions, bug reports, and project-specific troubleshooting.

What should I include in a bug report?
  • Unreal Engine version and target platform.
  • Plugin version and whether the package came from Fab.
  • Preset, batch size, frame time budget, and smart-skip setting.
  • Loading map, gameplay map, warmup folders, and explicit assets.
  • Development packaged logs when the issue appears outside the editor.
Where is the product page?

The Fab product page is here: PSO Autopilot on Fab.

What is the fastest way to verify a setup?

Use the setup wizard, run validation, apply safe fixes, package a Development build with logs, launch once for a cold run, then launch again to confirm Smart Skip behavior.

Ready to set up PSO Autopilot?

Start with the wizard, keep the loading level lightweight, validate the packaged build, and bring logs to Discord if anything does not line up.

No matching answers. Try a broader term like setup, cache, package, texture, or loading screen.