SaveGame
This section documents EDInteractionSystem’s SaveGame pipeline.
It is designed to persist and restore:
- Removed foliage instances (destroyed/harvested foliage stays removed after reload)
- Interactable actors (and custom saveable actors), including:
- current HP
- interaction blocked/denied state
- destroyed state
- any game-specific variables marked with
SaveGame
The workflow is multiplayer-ready:
- Save/Load runs on the server (authority).
- When a save is applied, state is replicated to clients using normal replication (and the plugin’s already replicated foliage removal state).
Entry point
The entry point is the GameState component:
UEDInteractionGameStateComponent
Main server functions:
SaveInteractionToSlot(SlotName, UserIndex)LoadInteractionFromSlot(SlotName, UserIndex, bApplyImmediately)ApplyLoadedInteractionSave(SaveGameObject)
What gets saved
1) Removed foliage
The system stores removed foliage instances as:
StaticMesh(soft reference)Location(world space)
Saved into:
UEDInteractionSaveGame::RemovedFoliageInstances(FEDSavedRemovedFoliageInstance)
On load, removal is re-applied by finding the matching instance by StaticMesh + Location and removing it.
2) Saveable actors (interactable and/or custom)
Actors are saved into:
UEDInteractionSaveGame::SavedActors(FEDSavedActorExtendedData)
Each entry includes:
SaveKey: stable identifier used to match the actor on loadTransform: actor transform (applied on load if the root component is Movable)InteractableState: basicUEDInteractableComponentstate (HP, deny/blocked, etc.)SavedObjects: serialized bytes for selected objects (actor and/or components) usingArIsSaveGame = true
SaveKey (stable identifier)
The system needs a stable key to find “the same” actor again when loading.
Priority order:
- If the actor implements
IEDInteractionSaveable,GetEDSaveKey()is used. - If the actor has
UEDInteractableComponent,UEDInteractableComponent::GetEffectiveSaveKey()is used:- If
SaveKeyis set on the component, it is used. - Otherwise, the actor name is used.
- If
- Final fallback: actor name.
Recommendations:
- For placed level actors, set
SaveKeyexplicitly to avoid relying on actor names. - For dynamically spawned actors, implement
IEDInteractionSaveableand generate your own key (for example, a gameplay ID).
Saving custom variables (UPROPERTY(SaveGame))
To save game-specific variables on your actor or component:
- Mark properties with
UPROPERTY(SaveGame)
Objects are serialized using:
FObjectAndNameAsStringProxyArchivewithAr.ArIsSaveGame = true
That means only properties tagged as SaveGame are included.
Example (C++):
UPROPERTY(SaveGame, BlueprintReadWrite)
int32 TimesInteracted = 0;
Destroyed state tracking
If a save-relevant interactable actor is destroyed, the system can remember it so that after loading it remains destroyed.
Automatic (interactables)
If an actor has:
UEDInteractableComponentwithbRelevantForSaveGame = true
then on server destruction it registers:
UEDInteractionGameStateComponent::MarkSaveKeyAsDestroyed(GetEffectiveSaveKey())
Manual (your gameplay)
If you destroy objects through custom logic (outside the interaction flow), you can mark them yourself:
MarkSaveKeyAsDestroyed(SaveKey)
On load:
- If the save key is present in
DestroyedActorSaveKeys, the actor is destroyed immediately.
API: adding saveable elements
You have three main ways to extend what gets saved.
A) Automatic tag-based saving
If an actor has tag:
EDSaveGame
it is considered a save candidate.
Also, UEDInteractableComponent exposes:
bRelevantForSaveGame
which automatically adds the EDSaveGame tag to the owning actor during initialization.
B) Explicit registration (server)
To save an actor even without the tag:
RegisterSaveableActor(Actor)UnregisterSaveableActor(Actor)
This is useful for dynamically spawned actors or systems managed from GameMode/GameState.
C) Interface control (IEDInteractionSaveable)
Implement IEDInteractionSaveable on your actor to control:
GetEDSaveKey()→ stable keyGetEDSaveObjects(Objects)→ list ofUObjects to serialize
If you do not implement the interface:
- The system serializes the actor and all its components by default.
Blueprint usage
- Ensure your
GameStatehasUEDInteractionGameStateComponent. - On the server (for example, in
GameModeon level start):LoadInteractionFromSlot("EDInteraction", 0, true)
- When you want to save (checkpoint / menu / autosave):
SaveInteractionToSlot("EDInteraction", 0)
C++ usage
if (AGameStateBase* GS = UGameplayStatics::GetGameState(World))
{
if (UEDInteractionGameStateComponent* Comp = GS->FindComponentByClass<UEDInteractionGameStateComponent>())
{
Comp->LoadInteractionFromSlot(TEXT("EDInteraction"), 0, true);
Comp->SaveInteractionToSlot(TEXT("EDInteraction"), 0);
}
}
Current limitations
- This system does not spawn missing actors on load; it restores state only for actors that exist in the level (and destroys them if marked as destroyed).
- If you rely on actor-name keys and you rename the actor, matching will break. Prefer
SaveKeyorIEDInteractionSaveable.