Skip to content

Troubleshooting & Diagnostics ​

This guide provides practical diagnostic workflows and solutions for the most common issues encountered during persistence integration.


1. "My spawned actors vanish when I reload a save" ​

The Cause ​

If you spawned an actor using standard Unreal Engine GetWorld()->SpawnActor(), the engine treats it as transient. A persistence component provides identity, but it does not tell the engine how to re-instantiate an actor that is not part of the level package.

The Fix ​

Spawn the actor through Spawn Persistent Actor (in Blueprint) or Aegis->SpawnPersistentActor<T>() (in C++). Aegis will store its class and reconstruct it on load.


2. "I ticked SaveGame on my variable, but it never restores" ​

The Cause: The Transient Trap ​

The engine's serialization archive skips variables for several reasons even if SaveGame is checked. By far the most common cause is that the variable is also marked Transient (or SkipSerialization). In Unreal Engine, Transient strictly overrides SaveGame and discards the property silently!

How to Confirm: Get Persistence Report ​

Call the Get Persistence Report node on your actor:

  • If your variable does not appear in the report: It was never marked SaveGame.
  • If your variable appears with Is Captured = false: It was marked SaveGame but is being skipped because it is also marked Transient or editor-only!

The Fix ​

Remove Transient from the variable's declaration, or recompute the cached value dynamically in IAegisPersistenceEvents::OnAfterAegisLoad.


3. "My load hitches or freezes the game" ​

The Cause ​

LoadGame decompresses the file, reconstructs spawned actors, and applies state across all persistent actors in the world. In large worlds, restoring thousands of entities blocks the game thread for several frames.

The Fix ​

Always trigger loads during natural loading transitions:

  • Display a loading screen or fade the screen to black before calling LoadGame.
  • Once the OnSuccess pin of Load Game from Slot fires, unfade the camera and dismiss the loading screen.
  • (Note: Autosaves run in Incremental mode and do not hitch. Only explicit full-world loads and manual atomic saves block).

4. "My autosave hitches even though it is in Incremental mode" ​

The Cause: Mass Mutation Frame (FO-16) ​

Incremental mode bounds scheduled capture to 1.0 ms. However, any actor modified during the current frame is captured immediately to prevent world state tearing. If a single frame destroys an entire building, triggers 50 explosions, or mutates 200 actors simultaneously, capture-on-write will exceed the 1.0 ms budget.

The Fix ​

Stagger simultaneous mass mutations across 2 to 3 frames rather than executing hundreds of actor modifications in a single tick.


5. "My Blueprint actors share the same save / overwrite each other" ​

The Cause ​

If multiple placed instances of an actor resolve to the exact same record, the persistent identity was stamped onto the Blueprint's Class Default Object (CDO) rather than onto each individual placed instance.

The Fix ​

Never set or edit Persistent ID by hand in the Blueprint class editor. Let the component assign its identity automatically:

  • Placed actors receive unique IDs when you save the level map.
  • Spawned actors receive unique sequence IDs when spawned via SpawnPersistentActor.

6. "Editor warning: has an Aegis Identity Component with no persistent ID" ​

The Cause: Map Check Warning (FO-26) ​

This is the built-in Map Check validation catching an unseeded placed actor at edit time so it never turns into a player bug report.

The Fix ​

Simply Save the Level (Ctrl + S or File $\rightarrow$ Save All). Saving the map generates and serializes the persistent ID into the level package.


7. "My save file is huge or keeps growing" ​

Check These Two Items: ​

  1. Unoptimized Actor Walks: By default, Aegis walks all persistent actors on every save. Implement IAegisPersistenceEvents::GetAegisStateRevision on your actors so unchanged actors are skipped in microseconds.
  2. Streamed-Out Records: Get Record Count returns all records in the save container, including actors that are currently streamed out of World Partition cells. This is correct behavior, not a memory leak.

8. "How do I save a quest manager or a class that is not an actor?" ​

Plain UObjects cannot carry components. Register them explicitly:

  1. Generate a deterministic GUID using Make Persistent Id From Label with a stable string (e.g. TEXT("QuestManager")).
  2. Call Register Persistent Object passing the object instance and the GUID.
  3. Choose Player scope (if it should survive level changes) or Global scope.

9. "References between saved actors come back as null" ​

A reference from Actor A to Actor B can only resolve if Actor B exists in the world. In World Partition, if Actor B lives in an unloaded cell, the reference will remain null until Actor B's cell streams in. When Actor B streams in, Aegis automatically resolves the reference.

Struct / Map Nesting Limit

A reference that is a direct property or an element of an array resolves cleanly. However, object references nested inside custom structs or maps cannot be dynamically re-addressed and are left null. Keep persistent actor references as top-level properties or arrays.


10. "Can I load a save file in the Main Menu before calling Open Level?" ​

Yes! In fact, this is the recommended flow.
Because UAegisSubsystem is a UGameInstanceSubsystem, its memory store survives across OpenLevel calls. When you call Load Game from Slot on the Main Menu, the records are populated in memory. When the new level loads, persistent actors register with Aegis and apply their saved properties before their first gameplay tick (AC-303), eliminating visual pop-in completely.


11. "How do I know which map name to pass to Open Level when the player clicks Continue?" ​

When saving your game during gameplay, set DisplayName in FAegisSaveOptions:

text
[Get Current Level Name] ──► [Make FAegisSaveOptions (Display Name)] ──► [Auto Save]

In your Main Menu, call Get Slot Info. Read SlotInfo.DisplayName and pass it directly to Open Level. This reads the save header in 0.05 ms without decompressing world data!
(See Complete Game Flow & Level Transitions for full diagrams).


12. "Can I reload a checkpoint without a loading screen when the player dies?" ​

Yes. You do not need to reload the .umap package from disk on player death. Simply call Load Game from Slot directly in the running level. Aegis will restore placed actors to their checkpoint transforms, respawn any enemies killed after the checkpoint, and revert player health in memory in milliseconds. Teleport the player character to the checkpoint position and resume gameplay instantly.


13. "What happens if a player loads a save created in an older version of my game?" ​

Aegis Save uses a frozen binary wire format v1 with tagged properties:

  • If you deleted a variable in a patch: Aegis safely discards the saved data for that field with zero errors.
  • If you added a new variable in a patch: The new variable retains its default Blueprint/C++ value.
  • If you renamed a class or property: Use UAegisSchemaMigration to register property redirectors and upgrade the save container atomically.

14. "Why did my door snap back to closed after loading?" ​

Check these two common issues:

  1. Mobility: Is the door mesh set to Movable? In Unreal Engine, Static meshes cannot be moved or rotated at runtime.
  2. Pose Application: Did you remember to apply the restored variable in BeginPlay? Aegis restores the boolean variable bIsOpen = true before first tick, but your Blueprint must check if (bIsOpen) in BeginPlay to set the mesh's initial rotation or start the timeline at 1.0!

15. "Does Aegis Save work with Steam Cloud or Epic Online Services?" ​

Yes, out of the box.
Aegis Save writes save containers (.aegis) to Unreal's standard platform save directory:

text
[ProjectRoot]/Saved/SaveGames/[SlotName].aegis

To enable Steam Cloud syncing in your Steamworks Partner Dashboard:

  1. Navigate to App Admin → Steam Cloud.
  2. Under Auto-Cloud Configuration, add a new path:
    • Root: WinAppDataLocalLow (or AppInstallDir/Saved/SaveGames)
    • Pattern: *.aegis
  3. Steam Cloud will automatically synchronize your players' .aegis files across PCs!

16. "Can I save custom Structs, Enums, and Arrays?" ​

Yes. Any USTRUCT, UENUM, or TArray / TMap marked with SaveGame is automatically serialized by Aegis:

  • Primitives: bool, int32, float, double, FString, FName, FText.
  • Math Types: FVector, FRotator, FTransform, FQuat.
  • Containers: TArray<T>, TSet<T>, TMap<Key, Value>.
  • Custom Structs: Any struct defined with USTRUCT(BlueprintType) containing UPROPERTY(SaveGame) fields.
  • Actor References: Direct TObjectPtr<AActor> references between persistent actors in the same world resolve automatically!

Aegis Save — Enterprise World Persistence for Unreal Engine 5.