Getting started
This walks through a minimal, end-to-end setup: enable the plugin, create a manager, register a saveable actor, save it to disk, and load it back.
1. Enable the plugin
Enable Pulse Save in Unreal Editor (Edit > Plugins), then restart the editor.
2. C++ module dependency
If you use Pulse Save in C++, add PulseSave to your module dependencies:
PublicDependencyModuleNames.AddRange(new string[]
{
"Core",
"PulseSave"
});
3. Implement UPulseSaveInterface on a saveable object
Every function on IPulseSaveInterface is a BlueprintNativeEvent with a default implementation, so you only need to override what you actually use. At minimum, give the object a stable identifier:
// MyActor.h
UCLASS()
class AMyActor : public AActor, public IPulseSaveInterface
{
GENERATED_BODY()
public:
virtual FName GetUniqueSaveIdentifier_Implementation() const override { return SaveId; }
UPROPERTY(EditInstanceOnly, Category = "Save")
FName SaveId;
};
See Implementing saveable objects for the full contract, and Core concepts for why saving through a model instead of the actor directly is recommended once you go beyond trivial data.
4. Create a save manager and add a collector
UPulseSaveManager is a plain UObject (its outer must provide a valid world context, e.g. a UGameInstance or an actor). Give it a save game and at least one collector — without a collector, no objects are gathered.
UPulseSaveManager* SaveManager = NewObject<UPulseSaveManager>(GetGameInstance());
// You can also always retrieve the current save game later via SaveManager->GetSaveGame().
FPulseSaveGame MySaveGame = FPulseSaveGame::New();
SaveManager->SetSaveGame(MySaveGame);
SaveManager->AddCollectorByClass(UPulseSaveActorCollector::StaticClass());
In Blueprint: Construct Object from Class (class PulseSaveManager, outer with world context), then Set Save Game and Add Collector By Class.
5. Save and load
Save() / Load() are asynchronous: they return true once the process has started (not once it has finished). Listen to OnProcessed() (native) or OnProcessedEvent (Blueprint) for completion, or OnProcessedWithReport() / OnProcessedWithReportEvent if you also want a diagnostic summary.
SaveManager->OnProcessed().AddLambda([](UPulseSaveManager* Manager, bool bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Process finished, success=%d"), bSuccess);
});
if (!SaveManager->Save())
{
// Nothing to save (no collector, or every object was excluded) — check GetLastProcessReport() / logs.
}
You can check readiness before calling either function:
if (SaveManager->CanSave()) { SaveManager->Save(); }
6. Persist the save game to disk
// Write
UPulseSaveUtils::SaveGameToSlot(MySaveGame, TEXT("MainSlot"), 0);
// Read (typically before creating the manager, or before calling Load())
FPulseStrongSaveGame Loaded = UPulseSaveUtils::LoadGameFromSlot(TEXT("MainSlot"), 0);
SaveManager->SetSaveGame(Loaded.Pin());
SaveManager->Load();
Blueprint nodes: Save Game To Slot and Load Game From Slot.
For file-based slots and slot discovery UIs, use the Blueprint slot library:
UPulseSaveSlotBlueprintLibrary -> Save Slot Save Game
UPulseSaveSlotBlueprintLibrary -> Load Slot Save Game
UPulseSaveSlotBlueprintLibrary -> List Slot Names
UPulseSaveSlotBlueprintLibrary -> Does Slot Exist
This is useful for save-slot pickers, metadata screens, and slot cleanup flows without writing custom C++ code.
7. Saving/loading a single object on its own
Sometimes you need to save or load one object outside of the main flow — e.g. an actor spawned at runtime that should load its data immediately, or an actor that must be saved right before it is destroyed. Use SaveSingleObject / LoadSingleObject; these do not use collectors and do not affect GetCurrentState():
SaveManager->OnProcessedSingle().AddLambda([](UPulseSaveManager*, UObject* Object, bool bSuccess) { ... });
SaveManager->LoadSingleObject(SpawnedActor);
Next steps
- Core concepts — the model/MVVM pattern, save records, persistence.
- Save manager workflow — process states, diagnostics, timeouts.
- Models and collectors — building custom collectors and models.