Blueprint and C++ API reference
For most plugin APIs, Blueprint node names match the C++ function names (Blueprint uses spaced, title-cased names; C++ uses PascalCase).
UPulseSaveManager
Save game / collectors
| Blueprint node | C++ function |
|---|---|
| Set Save Game | void SetSaveGame(const FPulseSaveGame& InSaveGame, EPulseSaveModelRetentionPolicy ModelRetentionPolicy = Reset) |
| Clear Save Game | void ClearSaveGame(EPulseSaveModelRetentionPolicy ModelRetentionPolicy = Reset) |
| Add Collector | bool AddCollector(UPulseSaveCollectorBase* Collector) |
| Add Collector By Class | UPulseSaveCollectorBase* AddCollectorByClass(TSubclassOf<UPulseSaveCollectorBase> CollectorClass) |
| Remove Collector | bool RemoveCollector(UPulseSaveCollectorBase* Collector) |
| Get Collectors | TArray<UPulseSaveCollectorBase*> GetCollectors() const |
Process control
| Blueprint node | C++ function |
|---|---|
| Save | bool Save() — StartProcess(EPulseSaveManagerProcessType::Save) |
| Load | bool Load() — StartProcess(EPulseSaveManagerProcessType::Load) |
| Start Process | bool StartProcess(EPulseSaveManagerProcessType ProcessType) |
| Save Single Object | bool SaveSingleObject(UObject* Object) |
| Load Single Object | bool LoadSingleObject(UObject* Object) |
| Reset Cached Save Models | void ResetCachedSaveModels() |
| Get Current State | EPulseSaveManagerStateType GetCurrentState() const |
| Is Idle | bool IsIdle() const |
| Is Saving | bool IsSaving() const |
| Is Loading | bool IsLoading() const |
| Can Save | bool CanSave() const |
| Can Load | bool CanLoad() const |
| Get Last Process Report | const FPulseSaveProcessReport& GetLastProcessReport() const |
| Cancel Process | void CancelProcess() |
| Set Report Slot | void SetReportSlot(const FString& SlotName, const FString& EntryId = "") — the slot written into the reports. Set automatically by the slot functions below. |
| Get Report Slot Name | FString GetReportSlotName() const |
| Set Report Context | void SetReportContext(const FString& Context) — free text written into the reports to tell managers apart, e.g. "Player profile". Kept when the save game is replaced. |
| Get Report Context | FString GetReportContext() const |
| Flush Reports | void FlushReports() — writes the collected single-object and static-model reports now (see Reports) |
One-shot completion callbacks
Native-only C++ overloads (not exposed to Blueprint, since they take a native TDelegate):
| C++ function |
|---|
bool Save(const FPulseSaveManagerProcessedDelegate& OnComplete) |
bool Load(const FPulseSaveManagerProcessedDelegate& OnComplete) |
bool StartProcess(EPulseSaveManagerProcessType ProcessType, const FPulseSaveManagerProcessedDelegate& OnComplete) |
bool SaveSingleObject(UObject* Object, const FPulseSaveManagerProcessedSingleDelegate& OnComplete) |
bool LoadSingleObject(UObject* Object, const FPulseSaveManagerProcessedSingleDelegate& OnComplete) |
Blueprint-callable equivalents (take a single-cast dynamic delegate pin instead):
| Blueprint node | C++ function |
|---|---|
| Save (With Callback) | bool SaveWithCallback(FPulseSaveManagerProcessedCallback OnComplete) |
| Load (With Callback) | bool LoadWithCallback(FPulseSaveManagerProcessedCallback OnComplete) |
| Save Single Object (With Callback) | bool SaveSingleObjectWithCallback(UObject* Object, FPulseSaveManagerProcessedSingleCallback OnComplete) |
| Load Single Object (With Callback) | bool LoadSingleObjectWithCallback(UObject* Object, FPulseSaveManagerProcessedSingleCallback OnComplete) |
Each OnComplete fires exactly once, for that specific call only, then is discarded — unlike OnProcessed()/OnProcessedEvent/OnProcessedSingle()/OnProcessedSingleEvent, which stay bound across every future call. See Save manager workflow.
Slot convenience
Combines Save()/Load() with slot I/O in a single call. Two independent slot systems are supported — see Save manager workflow for when to use which.
FPulseSaveSlot-based (native, staged/atomic, multi-entry per slot):
| C++ function |
|---|
bool SaveToSlot(const FPulseSaveSlot& Slot, const FPulseSaveSlotEntryId& EntryId, const FPulseSaveManagerProcessedDelegate& OnComplete = {}, EPulseSaveSlotFlushMode FlushMode = Entry) |
bool LoadFromSlot(const FPulseSaveSlot& Slot, const FPulseSaveSlotEntryId& EntryId, const FPulseSaveManagerProcessedDelegate& OnComplete = {}, EPulseSaveModelRetentionPolicy ModelRetentionPolicy = Reset) |
Blueprint-callable equivalents (build a temporary FPulseSaveSlot internally, since that type itself isn’t Blueprint-exposed; FPulseSaveSlotEntryId is, so it’s used directly):
| Blueprint node | C++ function |
|---|---|
| Save To Slot | bool SaveToSlotByName(const FString& SlotName, const FPulseSaveSlotEntryId& EntryId, const FString& RootDirectory, FPulseSaveManagerProcessedCallback OnComplete, EPulseSaveSlotFlushMode FlushMode = Entry) |
| Load From Slot | bool LoadFromSlotByName(const FString& SlotName, const FPulseSaveSlotEntryId& EntryId, const FString& RootDirectory, FPulseSaveManagerProcessedCallback OnComplete, EPulseSaveModelRetentionPolicy ModelRetentionPolicy = Reset) |
Engine slot-based (UGameplayStatics::SaveDataToSlot/LoadDataFromSlot, single blob per slot + user index):
| Blueprint node | C++ function |
|---|---|
| Save To Engine Slot | bool SaveToEngineSlot(const FString& SlotName, int32 UserIndex, FPulseSaveManagerProcessedCallback OnComplete) |
| Load From Engine Slot | bool LoadFromEngineSlot(const FString& SlotName, int32 UserIndex, FPulseSaveManagerProcessedCallback OnComplete, EPulseSaveModelRetentionPolicy ModelRetentionPolicy = Reset) |
Async action nodes (PulseSaveAsyncActions.h)
Blueprint-only UBlueprintAsyncActionBase nodes with Succeeded/Failed exec pins, wrapping the functions above (see Save manager workflow):
| Blueprint node | Class | Wraps |
|---|---|---|
| Save (Async) | UPulseSaveProcessAsyncAction | Save() |
| Load (Async) | UPulseSaveProcessAsyncAction | Load() |
| Save Single Object (Async) | UPulseSaveSingleObjectAsyncAction | SaveSingleObject() |
| Load Single Object (Async) | UPulseSaveSingleObjectAsyncAction | LoadSingleObject() |
| Save To Slot (Async) | UPulseSaveSlotAsyncAction | SaveToSlotByName() |
| Load From Slot (Async) | UPulseSaveSlotAsyncAction | LoadFromSlotByName() |
| Save To Engine Slot (Async) | UPulseSaveEngineSlotAsyncAction | SaveToEngineSlot() |
| Load From Engine Slot (Async) | UPulseSaveEngineSlotAsyncAction | LoadFromEngineSlot() |
Static models
| Blueprint node | C++ function |
|---|---|
| Get Or Create Static Model | UPulseStaticSaveModelBase* GetOrCreateStaticModel(FName Identifier, TSubclassOf<UPulseStaticSaveModelBase> ModelClass) (also template<T> T* GetOrCreateStaticModel(FName Identifier)) |
| Save Static Model | bool SaveStaticModel(UPulseStaticSaveModelBase* Model) |
Delegates/events
| Native (C++) | Blueprint-assignable | Fired when |
|---|---|---|
OnProcessed() → FOnCompleteEvent(UPulseSaveManager*, bool bWasSuccessful) | OnProcessedEvent | Save()/Load() completes. |
OnProcessedSingle() → FPulseSaveManagerProcessedSingleSignature(UPulseSaveManager*, UObject*, bool) | OnProcessedSingleEvent | SaveSingleObject()/LoadSingleObject() completes. |
OnProcessedWithReport() → FPulseSaveManagerProcessedReportSignature(UPulseSaveManager*, const FPulseSaveProcessReport&, bool) | OnProcessedWithReportEvent | Save()/Load() completes, carries diagnostics (see Save manager workflow). |
OnChunkProcessed() → FPulseSaveManagerChunkProcessedSignature(UPulseSaveManager*, int32 ChunkIndex, int32 ChunkCount) | OnChunkProcessedEvent | A chunk finishes processing during Save()/Load() (see Save manager workflow). |
OnModelProcessed() → FPulseSaveManagerModelProcessedSignature(UPulseSaveManager*, FName Identifier, bool bWasSuccessful, bool bTimedOut) | OnModelProcessedEvent | An individual model finishes processing during Save()/Load(). |
FPulseSaveProcessReport / FPulseSaveProcessReportEntry
See the field table in Save manager workflow.
Enums
EPulseSaveManagerProcessType:Save,LoadEPulseSaveManagerStateType:Idle,Saving,Loading
UPulseSaveUtils
| Blueprint node | C++ function |
|---|---|
| Save Object To Byte Array | static bool SaveObjectToByteArray(UObject* InObject, TArray<uint8>& OutData, bool bSaveGameOnly = true, bool bCallInterface = true) |
| Load Object From Byte Array | static bool LoadObjectFromByteArray(const TArray<uint8>& InData, UObject* InObject, FLoadObjectVersionInfo& OutVersion, bool bSaveGameOnly = true, bool bCallInterface = true) |
| Is Valid Save Game | static bool IsValidSaveGame(const FPulseWeakSaveGame& InSaveGame) |
| Is Valid Strong Save Game | static bool IsValidStrongSaveGame(const FPulseStrongSaveGame& InSaveGame) |
| Pin (Save Game) | static FPulseSaveGame PinSaveGame(const FPulseWeakSaveGame& InSaveGame) |
| Strong (Pin Strong Save Game) | static FPulseStrongSaveGame PinStrongSaveGame(const FPulseWeakSaveGame& InSaveGame) |
| Pin (Save Game From Strong) | static FPulseSaveGame PinSaveGameFromStrong(const FPulseStrongSaveGame& InSaveGame) |
| Weak (Make Weak Save Game) | static FPulseWeakSaveGame MakeWeakSaveGame(const FPulseSaveGame& InSaveGame) |
| Weak (Make Weak Save Game From Strong) | static FPulseWeakSaveGame MakeWeakSaveGameFromStrong(const FPulseStrongSaveGame& InSaveGame) |
| Create Save Model | static UPulseSaveModelBase* CreateSaveModel(UObject* Outer, TSubclassOf<UPulseSaveModelBase> SaveModelClass) |
| Save Game To Slot | static bool SaveGameToSlot(const FPulseSaveGame& SaveGame, const FString& SlotName, int32 UserIndex = 0) |
| Load Game From Slot | static FPulseStrongSaveGame LoadGameFromSlot(const FString& SlotName, int32 UserIndex = 0) |
| Save Game To Byte Array | static bool SaveGameToByteArray(const FPulseSaveGame& InSaveGame, TArray<uint8>& OutData) |
| Load Game From Byte Array | static FPulseStrongSaveGame LoadGameFromByteArray(const TArray<uint8>& InData) |
| Load Static Model From Slot | static UPulseStaticSaveModelBase* LoadStaticModelFromSlot(const FString& SlotName, FName Identifier, TSubclassOf<UPulseStaticSaveModelBase> ModelClass, int32 UserIndex = 0) |
FPulseSaveSlotFile / FPulseSaveSlot
These are the direct, path-based file-persistence helpers for saving outside of UGameplayStatics save slots. For Blueprint, use UPulseSaveSlotBlueprintLibrary to list slots, check existence, delete slots, and save/load a slot’s metadata save game without writing custom C++ wrappers. Both native types are lightweight value types with purely synchronous methods, so callers own any threading (e.g. wrap calls in Async()/AsyncTask(), as done in DawnSaveGameSubsystem).
UPulseSaveSlotBlueprintLibrary
| Blueprint node | C++ function |
|---|---|
| Save Slot Save Game | static bool SaveSlotSaveGame(const FString& SlotName, const FPulseSaveGame& SaveGame, const FString& RootDirectory = FString()) |
| Load Slot Save Game | static FPulseStrongSaveGame LoadSlotSaveGame(const FString& SlotName, const FString& RootDirectory = FString()) |
| Save Slot Meta Game | static bool SaveSlotMetaGame(const FString& SlotName, const FPulseSaveGame& SaveGame, const FString& RootDirectory = FString()) |
| Load Slot Meta Game | static FPulseStrongSaveGame LoadSlotMetaGame(const FString& SlotName, const FString& RootDirectory = FString()) |
| Does Slot Exist | static bool DoesSlotExist(const FString& SlotName, const FString& RootDirectory = FString()) |
| Get Slot Directory | static FString GetSlotDirectory(const FString& SlotName, const FString& RootDirectory = FString()) |
| Get Default Slot Directory | static FString GetDefaultSlotDirectory() |
| List Slot Names | static TArray<FString> ListSlotNames(const FString& RootDirectory = FString()) |
| List Slots | static TArray<FPulseSaveSlotInfo> ListSlots(const FString& RootDirectory = FString()) |
| Delete Slot | static bool DeleteSlot(const FString& SlotName, const FString& RootDirectory = FString()) |
FPulseSaveSlotFile
Atomically reads/writes exactly one file at an absolute path, with a single rolling .bak backup generation. Writes go to a unique temp file first, rotate the previous valid file to .bak (if backups are enabled), then rename the temp file onto the final path - if any step fails, the previously valid file is left untouched.
FPulseSaveSlotFile file(TEXT("C:/MyGame/Saves/global.sav"));
file.SaveGameToDisk(mySaveGame); // atomic write + backup rotation
file.LoadGameFromDisk(outSaveGame); // tries primary, falls back to .bak automatically
file.SaveBytesToDisk(rawBytes); // low-level byte variants
file.LoadBytesFromDisk(outBytes); // no automatic backup fallback (caller decides)
file.Exists();
file.HasBackup();
file.DeleteSlot(/*bAlsoDeleteBackup=*/true);
Backups are optional
Whether writes rotate a .bak backup defaults to UPulseSaveSettings::bEnableSlotBackups (project setting, Config=Game, category “Slot”). Both classes let you override that default per-instance, e.g. to disable backups for high-churn data like per-chunk saves while keeping them for the global save:
// Uses UPulseSaveSettings::bEnableSlotBackups (project default).
FPulseSaveSlotFile globalFile(TEXT("C:/MyGame/Saves/global.sav"));
// Explicitly disabled for this instance, regardless of the project setting.
FPulseSaveSlotFile chunkFile(TEXT("C:/MyGame/Saves/chunk_3_-2.sav"), /*InBackupsEnabled=*/false);
// Can also be toggled after construction, or reset back to the project default.
chunkFile.SetBackupsEnabled(true);
chunkFile.SetBackupsEnabled(TOptional<bool>()); // revert to UPulseSaveSettings::bEnableSlotBackups
chunkFile.AreBackupsEnabled(); // resolved effective value
FPulseSaveSlot takes the same optional constructor parameter / SetBackupsEnabled(), and applies it to every entry’s underlying FPulseSaveSlotFile (staged and committed).
FPulseSaveSlot
A directory-based “slot” holding multiple, independently identified save game entries, optionally grouped into subfolder categories (e.g. all chunk saves under "Chunks"). Each entry goes through a staging step before being committed:
StageBytes/StageSaveGamewrite an entry into a.stagingsubfolder - durable, but not yet the entry’s authoritative data.DiscardStagedremoves one staged entry;DiscardAllStagedremoves every staged entry without changing committed data.LoadBytes/LoadSaveGameprefer a pending staged version over the committed one, so re-loading an entry shortly after staging (but before a flush) returns the most recent data.Flush/FlushEntrycommit staged entries to their final location (same atomic temp+rename+.bakguarantees asFPulseSaveSlotFile), one entry at a time; a failure on one entry does not prevent others from committing.
FPulseSaveSlot keeps no in-memory bookkeeping of staged/committed state - it is always derived by scanning the filesystem, so multiple instances pointed at the same root directory and slot name (e.g. from different threads/tasks) stay consistent without needing to synchronize with each other. Every slot writes exclusively to <root directory>/<slot name>/.
FPulseSaveSlot slot(TEXT("MySave"), TEXT("C:/MyGame/Saves"));
const FPulseSaveSlotEntryId chunkEntry(TEXT("Chunks"), TEXT("3_-2"));
// Chunk unloads (dirty): stage without touching the real, committed save data yet.
slot.StageSaveGame(chunkEntry, chunkSaveGame);
// Chunk (re-)loads: prefers the staged version if present, otherwise the committed version.
FPulseSaveGame outGame;
slot.LoadSaveGame(chunkEntry, outGame);
// Real save/checkpoint: commit everything staged so far, independently per entry.
slot.Flush();
slot.HasAnyStagedChanges();
slot.GetCommittedIdentifiers(TEXT("Chunks")); // list all committed chunk file identifiers
slot.DeleteEntry(chunkEntry, /*bAlsoDeleteBackup=*/true);
Category/Identifier are sanitized (FPulseSaveSlotEntryId::IsValid()) to reject empty identifiers and path-traversal segments (e.g. .., /, \) before being turned into a relative path.
Slot Discovery & Metadata (slot_meta.sav)
To support UI menus (such as “Load Game”) without having to scan or deserialize heavy world/chunk data, FPulseSaveSlot provides built-in discovery functions and first-class metadata handling:
FPulseSaveSlot::ListSlots()scans a save directory (default:Saved/SaveGames) and returns a sortedTArray<FPulseSaveSlotInfo>(newest first) with slot names, full directory paths, last modified timestamps, and flags (bHasMeta,bHasStagedChanges).FPulseSaveSlot::ListSlotNames()returns just the folder names.FPulseSaveSlot::DoesSlotExist()checks whether a slot folder exists.FPulseSaveSlot::DeleteEntireSlot()completely removes a slot directory (including all committed files, backups, and staging).SaveMetaGameDirect/LoadMetaGame(and byte overloads) operate on a reservedFPulseSaveSlot::MetaEntryId(slot_meta.savat the slot root) so game-level UI info (player level, playtime, seed, preset) can be read/written in isolation.
// --- Discovery for UI menus ---
const TArray<FPulseSaveSlotInfo> slots = FPulseSaveSlot::ListSlots();
for (const FPulseSaveSlotInfo& info : slots)
{
FPulseSaveSlot slot(info.SlotName, FPaths::GetPath(info.DirectoryPath));
if (info.bHasMeta)
{
FPulseSaveGame metaGame;
if (slot.LoadMetaGame(metaGame))
{
// Read UI headers (playtime, seed, screenshot, etc.) quickly
}
}
}
// Delete an entire slot
FPulseSaveSlot::DeleteEntireSlot(TEXT("OldSaveGame"));
Error handling
Every fallible method on both classes takes an optional EPulseSaveSlotError* OutError = nullptr out-parameter (see EPulseSaveSlotError in PulseSaveSlot.h), mirroring the enum-based failure reporting already used by EPulseSaveLoadFailureType. All failures are also logged via LogPulseSaveSlot, so OutError only needs to be inspected when the caller must react differently to specific failure kinds:
EPulseSaveSlotError error;
if (!slot.LoadSaveGame(chunkEntry, outGame, &error))
{
if (error == EPulseSaveSlotError::InvalidEntryId)
{
// Programmer error - fix the caller.
}
// Otherwise: missing/corrupt entry, already logged as a warning.
}
Flush() commits every staged entry independently; if one or more entries fail, Flush() returns false and OutError reports the last entry’s failure (each individual failure is still logged, so nothing is silently lost).
IPulseSaveInterface
All 12 functions are BlueprintNativeEvent with a default implementation — see Implementing saveable objects for which ones you actually need to override.
| Blueprint event/function | C++ declaration | Default |
|---|---|---|
| Get Unique Save Identifier | FName GetUniqueSaveIdentifier() const | NAME_None |
| Should Save | EPulseSaveChoice ShouldSave(UPulseSaveManager* SaveManager) const | Default (→ Yes) |
| On Save | void OnSave(UPulseSaveManager* SaveManager, UPulseSaveModel* SaveModel) | no-op |
| On Post Save | void OnPostSave(UPulseSaveManager* SaveManager, UPulseSaveModel* SaveModel) | no-op |
| Is Ready To Save | EPulseSaveChoice IsReadyToSave(UPulseSaveManager* SaveManager, const UPulseSaveModel* SaveModel) const | Default (→ Yes) |
| On Load | void OnLoad(UPulseSaveManager* SaveManager, UPulseSaveModel* SaveModel) | no-op |
| Is Ready To Load | EPulseSaveChoice IsReadyToLoad(UPulseSaveManager* SaveManager, const UPulseSaveModel* SaveModel) const | Default (→ Yes) |
| On Post Load | void OnPostLoad(UPulseSaveManager* SaveManager, UPulseSaveModel* SaveModel) | no-op |
| On Load Failed | void OnLoadFailed(UPulseSaveManager* SaveManager, const UPulseSaveModel* SaveModel, EPulseSaveLoadFailureType FailureType) | no-op |
| Get Load Priority | int32 GetLoadPriority() const | 0 |
| Get Save Model Class | TSubclassOf<UPulseSaveModel> GetSaveModelClass(UPulseSaveManager* SaveManager) const | nullptr |
| Is Persistent | bool IsPersistent() const | false |
Enums:
EPulseSaveChoice:Default,Yes,NoEPulseSaveLoadFailureType:Unknown,ObjectNotFound,PreLoadFailed,PostLoadFailed,LoadTimeout,MigrationFailed
UPulseSaveModelBase / UPulseSaveModel
See Models and collectors for the full description; quick reference:
| Function | Class | Notes |
|---|---|---|
InitializeNewModel() | UPulseSaveModelBase | Called when creating a fresh model (no record). |
InitializeFromRecord(const FPulseSaveModelRecord&) | UPulseSaveModelBase | Called when loading from an existing record. |
OnPreSave() / OnPostSave() | UPulseSaveModelBase | Save lifecycle hooks. |
OnPreLoad() / OnPostLoad() | UPulseSaveModelBase | Load lifecycle hooks. |
GetIdentifier() | UPulseSaveModelBase | Returns Identifier on UPulseSaveModel. On UPulseStaticSaveModelBase it must be provided: override it in C++ or implement the event “Get Identifier” in Blueprint. |
SetSaveObject(UObject*) | UPulseSaveModel | Binds a live object to this model. |
InitializeWithoutSaveObject() | UPulseSaveModel | Called on load when no live object matched. |
IsReadyToSave() / IsReadyToLoad() | UPulseSaveModelBase | Polled every tick. Base default false (the model calls ReadyToSave() / ReadyToLoad() itself). UPulseSaveModel delegates to the bound object’s IPulseSaveInterface + Blueprint event. |
HasSaveObject() | UPulseSaveModel | BlueprintPure. |
NotifyLoadFailed(EPulseSaveLoadFailureType) | UPulseSaveModel | Forwards to the bound object’s OnLoadFailed. |
GetTimeoutOverride(float& OutTimeout) | UPulseSaveModelBase | Return true + set OutTimeout to override UPulseSaveSettings::DefaultProcessTimeout. |
IsPersistent() / GetLoadPriority() | UPulseSaveModel | Override the base defaults: delegate to the bound object’s IPulseSaveInterface::IsPersistent, and the load priority cached during save from IPulseSaveInterface::GetLoadPriority. |
GetModelVersion() | UPulseSaveModelBase | Schema version stored in every record (default 0). Blueprint: implement the event “Get Model Version”. See Save migration. |
LogInfo(Message) / LogWarning(Message) / LogError(Message) | UPulseSaveModelBase | Write a message that appears with the model in the report. An error makes the model faulty in the report. Blueprint nodes. See Reports. |
GetRecordType() | UPulseSaveModelBase | Collected (default) or Static (UPulseStaticSaveModelBase). See EPulseSaveRecordType. |
IsPersistent() | UPulseSaveModelBase | Default true. UPulseSaveModel asks its object. Static models are always persistent. |
GetLoadPriority() | UPulseSaveModelBase | Default MIN_int32 (loads after all object models). |
PrepareLoadTarget() | UPulseSaveModelBase | Called by the load processor before OnPreLoad. |
GetObjectForModelClassResolution() | UPulseSaveModel | Object used to find the model class a record has to be migrated to. Default: the bound object. |
Properties: SaveObject (BlueprintReadOnly), Identifier (SaveGame), LoadPriority (SaveGame), bSerializeAllSaveGameProperties (EditAnywhere, default false).
UPulseSaveActorModel / UPulseSaveActorModelBase
| Property/function | Notes |
|---|---|
LoadType (EPulseSaveActorLoadType) | ExistingOnly, ExistingOrSpawn, AlwaysSpawn. |
TransformSaveFlags (EPulseActorTransformSaveFlags, bitmask) | Location, Rotation, Scale, LocationAndRotation, All. |
TeleportType (ETeleportType) | Applied when restoring location/rotation. |
HandleSpawnActor() / GetSpawnTransform() / BuildSpawnParameters(...) | Protected virtuals for custom spawn behavior (subclass UPulseSaveActorModelBase). |
Collector APIs
UPulseSaveCollectorBase
| Blueprint node | C++ function |
|---|---|
| Collect Save Objects | bool CollectSaveObjects(TSet<UObject*>& OutSaveObjects) |
| Collect Load Objects | bool CollectLoadObjects(TSet<UObject*>& OutLoadObjects) |
UPulseSaveActorCollector
| Blueprint node/event | C++ function |
|---|---|
| Collect Actor For Save | bool CollectActorForSave(AActor* InActor) (default true) |
| Collect Actor For Load | bool CollectActorForLoad(AActor* InActor) (default true) |
| — | virtual bool ShouldCollectActor(AActor* InActor) const (C++ only, additional filtering) |
UPulseSaveRegisterCollector
| Blueprint node | C++ function |
|---|---|
| Register Object | bool RegisterObject(UObject* Object, const FPulseSaveRegisterCollectorParams& Params) |
| Unregister Object | bool UnregisterObject(UObject* Object) |
FPulseSaveRegisterCollectorParams fields: bCollectForSave, bCollectForLoad, bLoadOnRegister, bRemoveIfDestroyed, OnLoadedOnRegister (native-only delegate, set via .OnLoadedOnRegisterDelegate(...)).
UPulseSaveSettings / UPulseSaveSettingsPrivate
Config section: Project Settings > Pulse > Save.
| Field | Class | Default |
|---|---|---|
DefaultModelClass | UPulseSaveSettings | none (must be set; used as last-resort factory fallback) |
DefaultProcessTimeout | UPulseSaveSettings | 60.0 seconds (-1 disables) |
MigrationFallback | UPulseSaveSettings | Fail (EPulseSaveMigrationFallback: Fail, ReinterpretByProperty, KeepOldModel) |
EditorReportMode | UPulseSaveSettings | Always (EPulseSaveReportMode: Disabled, OnFailure, Always) |
PackagedReportMode | UPulseSaveSettings | OnFailure |
MaxStoredReports | UPulseSaveSettings | 50 (0 keeps all) |
bEnableGlobalManagerPool | UPulseSaveSettings | false (when enabled, creates UPulseSaveManagerPoolSubsystem; restart required) |
DefaultModelFactory | UPulseSaveSettingsPrivate | none |
SaveModelFactories | UPulseSaveSettingsPrivate | empty |
Migrations | UPulseSaveSettingsPrivate | empty (UPulseSaveModelMigration classes) |
ClassRedirects | UPulseSaveSettingsPrivate | empty (old class path -> new class) |
See Model factories and settings for the factory resolution order and Save migration for migrations.
Report API
| Type / function | Notes |
|---|---|
FPulseSaveReport, FPulseSaveReportModelEntry, FPulseSaveModelMessage | The data of a report (PulseSaveReport.h). FPulseSaveReport::HasFailures(). |
EPulseSaveReportScope, EPulseSaveReportResult, EPulseSaveMessageSeverity | Process / SingleObject / StaticModel, Succeeded / Failed / TimedOut / Skipped, Info / Warning / Error. |
Pulse::Save::Report::* (PulseSaveReportStorage.h) | GetReportDirectory, GetActiveMode, ShouldWrite, WriteReport, FlushPendingWrites, EnumerateReportFiles, LoadReportFromFile. |
IPulseSave::OnReportWritten() | Multicast delegate (game thread): file path, whether the report has failures. |
See Reports.
Migration API
| Type | Notes |
|---|---|
UPulseSaveModelMigration | Base class of a migration step. Migrate(const FPulseSaveMigrationContext&) (BlueprintNativeEvent), SourceClass, SourceVersion, TargetClass, TargetVersion. |
FPulseSaveMigrationContext | Old/new model, save object, identifier, old class path and version. |
FPulseSaveMigrationRegister (IPulseSave::Get().GetMigrationRegister()) | RegisterMigration, UnregisterMigration, RegisterClassRedirect, UnregisterClassRedirect, BuildMigrationPath, MigrateRecordInto. |
EPulseSaveMigrationResult | NotNeeded, Migrated, FallbackReinterpreted, KeepOld, Failed. |
UPulseSaveMigrationLibrary | Blueprint nodes: Register Migration, Unregister Migration, Register Class Redirect, Unregister Class Redirect. |
UPulseSaveUnresolvedModel | Placeholder for a record whose model class no longer exists. |
FPulseSaveModelRecord | GetModelVersion(), GetModelClassPath(), IsCompatibleWith(Model), LoadModel(Model, bAllowClassMismatch). |