Persistent Identities
In Unreal Engine, actor names (e.g., StaticMeshActor_42 or BP_Chest_C_1) are volatile: they mutate when levels are re-saved, change when actors are moved to different streaming cells, and collide when levels are instanced.
Aegis Save eliminates name-based fragility by establishing Permanent, Bit-Exact 128-Bit GUID Identities across every persistent object in your game.
1. The Four Identity Archetypes
| Identity Archetype | Source of Truth | Lifecycle & Behavior | Example Use Case |
|---|---|---|---|
| 1. Hand-Placed Level Actor | Adopted ActorGuid (Serialized to package) | Permanent across world re-partitioning, cell streaming, and cooked builds. | Level-placed loot chests, doors, puzzles, world bosses. |
| 2. Runtime Spawned Actor | Monotonic Counter (Persisted in Global scope) | Assigned at runtime via SpawnPersistentActor; recreated automatically on load. | Dropped player weapons, dynamic campfires, vehicle spawns. |
| 3. Registered Plain Object | Stable Label via MakePersistentIdFromLabel | Deterministic 128-bit hash derived from a stable name string; persists non-actors. | Inventory managers, quest journals, player stats models. |
| 4. Instanced Level Actor | Cook-time Ancestor Composition (C-83) | Level Instance transform and placement seeds composed deterministically into actor GUIDs. | Reusable modular dungeon rooms, instanced enemy outposts. |
2. Hand-Placed Actors & Cooked Read-Back (§6.0s)
When you place an actor in Unreal Editor and attach UAegisPersistenceComponent, Aegis automatically adopts the actor's editor-assigned ActorGuid into the component's own serialized PersistentId property.
The Cooked Build Hazard — And How Aegis Solves It
In Unreal Engine, AActor::ActorGuid is wrapped in WITH_EDITORONLY_DATA: it is stripped completely from cooked standalone and Shipping client builds.
Many marketplace plugins fail in Shipping builds because they rely on ActorGuid at runtime. Aegis Save solves this through Pre-Save Package Identity Stamping:
- During level editing and map saving (
PreSave),UAegisPersistenceComponentcaptures the editor GUID and serializes it into the actor's persistent package data. - In cooked client builds where
actorGuid=N/A,UAegisPersistenceComponentrecovers its adoptedPersistentIdbit-exact withHasValidId() == true(Section 6.0s Verified).
Editor Authoring: [Details Panel] ──► Adopt ActorGuid ──► Serialize PersistentId into Map Package
│
Cook Pipeline: [Cook & Package] ──► ActorGuid Stripped │
▼
Shipping Client: [Loaded in Game] ◄── Read-Back Bit-Exact PersistentId (actorGuid = N/A)3. Runtime Spawned Actors (SpawnPersistentActor)
Actors spawned during gameplay cannot use editor GUIDs because they do not exist in the level file. If you use standard SpawnActor, the actor will vanish when you reload a save.
To spawn an actor that survives save and load:
[Spawn Persistent Actor (Aegis)]
├── Class: BP_DroppedWeapon
├── Transform: HitLocation
└── Return Value ──► [Set Weapon Ammo]#include "Core/AegisSubsystem.h"
UAegisSubsystem* Aegis = UAegisSubsystem::Get(this);
AYourDroppedItem* SpawnedItem = Aegis->SpawnPersistentActor<AYourDroppedItem>(
AYourDroppedItem::StaticClass(),
SpawnTransform
);Aegis assigns a deterministic, monotonically increasing 64-bit sequence counter stored in the save container's Global scope. When the save is reloaded, Aegis automatically re-instantiates the spawned actor class, reassigns its persistent identity, and restores its saved properties.
4. Plain Objects: Deterministic Labels
For UObjects that are not actors (such as custom UMG models, inventory state classes, or quest trackers), use MakePersistentIdFromLabel:
[Make Persistent Id From Label ("PlayerBackpack")]
│
▼
[Register Persistent Object]
├── Object: InventoryObjectRef
├── Identity: (From Label)
└── Scope: Player#include "Core/AegisSubsystem.h"
UAegisSubsystem* Aegis = UAegisSubsystem::Get(this);
const FGuid BackpackId = Aegis->MakePersistentIdFromLabel(TEXT("PlayerBackpack"));
// Register under Player scope so it persists across map transitions
Aegis->RegisterPersistentObject(MyBackpackInstance, BackpackId, EAegisScope::Player);Use Stable String Literals
Always pass constant string literals (e.g., TEXT("QuestManager") or TEXT("SkillTree")). Never generate labels using dynamic indices, timestamps, or display names that can change between game sessions.
5. Level Instances & Ancestor Composition (C-83)
When a designer places a Level Instance (ALevelInstance), all actors inside that sub-level exist in multiple places across the world. If each placed instance used identical authored GUIDs, saving would cause catastrophic identity collisions.
Aegis solves this with Cook-Time Deterministic Ancestor Composition:
- At cook time,
UAegisPersistenceComponent::PreSavewalks up the parent Level Instance hierarchy. - It hashes the parent Level Instance placement seed with the actor's authored identity (C-83).
- Both Embedded (Partitioned) and Standalone (LevelStreaming) Level Instances generate unique, collision-free identities across streaming cycles (FO-27 / AC-214 Verified).
Next Steps
- See how persistent identities survive streaming in World Partition & Streaming.
- Learn how destroyed actors are tracked in Destroyed Actors & Tombstones.