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


This site uses Just the Docs, a documentation theme for Jekyll.