Migration

Behavior changes (no action needed)

  • Slot metas name the save they were written with. FPulseSaveSlotMeta has a new field Entry (FPulseSaveEntryStamp, read only in Blueprint): WriteEntryWithMeta (and Save To Slot With Meta) stamps the meta with the bytes of the entry; WriteSlotMeta keeps the stamp of the meta it replaces while that entry is unchanged, else it writes the meta without one. Metas of earlier builds load with an empty stamp and are read as before; earlier builds skip the field. LoadFromSlot now fills FPulseSaveCheckResult::Files (what it did with the entry’s files, one file stat per load); a save clears it.
  • The default load menu handler brings the slot meta in step after every load (also a failed one), with the new Pulse::Save::SyncSlotMetaAfterLoad (Blueprint Sync Slot Meta After Load): when the load put the entry’s backup back, the meta backup goes back too if it was written with that data; a staged meta whose save is gone is dropped; the play time comes from the meta written with the loaded data, else from the meta the old rule picks. Blueprint handlers can call the node after Load From Slot (Async); without it nothing changes for them.

  • Pulse Check reports save ids made from names as warnings (Name based): objects saved as bytes without a Save Identity, ids that contain the name of an actor spawned while playing, IPulseSaveInterface objects whose identifier is the name-based key, and automatic components without a Save Identity (Fixed identifiers and Pulse Check). Nothing changes in saves; the warnings only point at ids that renames or another spawn order would break.
  • Save ids of automatic components are the same in packaged games as in the editor (with the PulseFoundation version that names automatic components Pulse_<Class>_0 in every build). Records of earlier packaged sessions were never found again and stay so. No data moves, so nothing has to be migrated.

From 1.x to 2.0

Pulse Save 2.0 records its reports with the report system of the free base plugin PulseFoundation (1.0 or newer) and drops its own report types, files and editor tab. The save API and the save format stay the same: saves of 1.x load unchanged.

Coming from 1.0

Pulse Save needs PulseFoundation since 1.1:

  1. Put PulseFoundation into the project (or engine) plugins next to Pulse Save. It is enabled together with Pulse Save.
  2. Rebuild the project.
  3. Only if a game module uses PulseFoundation types itself, or the linker reports unresolved PulseFoundation symbols (e.g. in a C++ subclass of UPulseSaveManager): add PulseFoundation to the dependencies in that module’s Build.cs.

Records stay until their object is destroyed

PrepareForSave() no longer removes the collected records whose object said IsPersistent false. Records stay until their object is destroyed for good: placed actors leave a tombstone that removes them again when the save loads, spawned ones lose their record. Objects that were only unloaded (streaming, offline players) keep their state. A load that finds no object for a record no longer fails that record; it stays in the save game.

If your game relied on non-persistent records being dropped (temporary objects with new identifiers every session), call RemoveRecord(Identifier) for them, or destroy their actors so the tracker removes their records.

Reports

1.x 2.0
Editor tab Pulse Save Reports Reports page of Tools > Debug > Pulse Debugger (plugin Save). PulseSave.OpenReports opens it.
Files in Saved/PulseSave/Reports Files in Saved/Pulse/Reports/Save (PulseFoundation format). Old files are not read any more.
Settings EditorReportMode, PackagedReportMode, MaxStoredReports One setting ReportPolicy (EditorMode, PackagedMode, MaxStoredReports)
EPulseSaveReportMode EPulseReportMode (PulseFoundation, same values)
FPulseSaveReport, FPulseSaveReportModelEntry FPulseReport with one entry per model
EPulseSaveReportScope, EPulseSaveReportResult The report type (Save, Load, SingleObject.Load, …) and the entry severity
EPulseSaveMessageSeverity EPulseDebugSeverity (PulseFoundation)
IPulseSave::OnReportWritten() Pulse::Debug::OnReportSubmitted() (all plugins; check Report.Plugin == "Save")
Pulse::Save::Report::* (PulseSaveReportStorage.h) Pulse::Debug::Reports::* (EnumerateReportFiles("Save"), LoadReportFromFile, GetReportRoot)

What to do:

  1. Set the report settings again under Project Settings > Pulse > Save > Report. The old keys EditorReportMode, PackagedReportMode and MaxStoredReports in DefaultGame.ini are ignored; remove them. The defaults stay the same (Always in the editor, OnFailure in packaged builds, 50 files).
  2. Replace uses of the removed types listed above. OnProcessed() / OnProcessedWithReport() and FPulseSaveProcessReport are unchanged.
  3. Shipping builds no longer record reports (PulseFoundation’s debug tools are compiled out of shipping). Use a development or test build to get report files from a packaged game.

Nothing to do for the rest:

  • Model messages (LogInfo, LogWarning, LogError), report context and report slot work as before.
  • Save and load processes now also finish in the editor outside of PIE (Editor Utility Blueprints, automation specs). Before 2.0 they never completed there.
  • Save and load processes are events on the Timeline page of the Pulse Debugger.
  • Every save manager is a snapshot provider (category Save): its state shows on the Live page, in the gameplay debugger category Pulse and with PulseDebugDump Save (see Console).
  • BuildChunks keeps its signature. Since 2.0 a save runs synchronous models first and splits into two chunks when an asynchronous model captures AtEnd (null models are skipped). The plan is the pure Pulse::Save::PlanChunks, which an override can call.
  • SaveMetaGameDirect, SaveMetaBytesDirect and the Blueprint Save Slot Save Game / Save Slot Meta Game delete a staged meta (.staging/slot_meta.sav) after they wrote, so every reader sees the direct write; if that delete fails they return false with the new error StagedDiscardFailed. Commit a meta you staged yourself (FlushEntry(FPulseSaveSlot::MetaEntryId)) before a direct write.

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