Reports

Pulse Save can write a report for every save and load. A report says which models were processed, how it went for each of them, how long it took, and what the models wrote about it. You look at the reports in the editor tab Pulse Save Reports.

Settings

Project Settings > Pulse > Save > Report

Setting Default Meaning
EditorReportMode Always When reports are written in the editor. This covers every build that has the editor: PIE and standalone games started from the editor.
PackagedReportMode OnFailure When reports are written in a packaged game (a build without the editor).
MaxStoredReports 50 How many report files are kept. The oldest are deleted when a new one is written. 0 keeps all.

The mode is EPulseSaveReportMode:

Value Behavior
Disabled Nothing is recorded or written. Models do not even store their messages.
OnFailure A report is written only if something failed (see below).
Always A report is written for every process.

A report counts as failed if the process did not succeed, a model failed or timed out, or a model wrote an error message (see Messages of a model). Note that FPulseSaveProcessReport::bWasSuccessful only reflects the last chunk of a process, so the report looks at every model.

What is reported

Kind (EPulseSaveReportScope) Written when
Process Once for every Save() / Load() of a save manager. Static models that take part are listed with it.
SingleObject For SaveSingleObject / LoadSingleObject. Including calls that fail right away, e.g. because the object has no record.
StaticModel For operations on static models outside of a process: GetOrCreateStaticModel (only if it actually loads or creates a model), SaveStaticModel and UPulseSaveUtils::LoadStaticModelFromSlot.

Single-object and static-model operations are often numerous (think of actors that load themselves when they spawn). They are collected and written as one report after one second without a new operation. They are also written when the manager is destroyed or when you call UPulseSaveManager::FlushReports().

Every model of a report has an entry with:

  • identifier, record type (Collected / Static), model class,
  • result: Succeeded, Failed, TimedOut or Skipped (identifier missing or duplicated), the reason, and the duration,
  • whether its record was migrated, and from which class and version (see Save migration),
  • the messages the model wrote.

A report never contains the saved data itself.

Save slot

A report also carries the context of its manager: a free text that tells managers apart, because their object names are generated. Call UPulseSaveManager::SetReportContext("Player profile") (Blueprint: Set Report Context), or create the manager with Pulse::Save::CreateManager(Context). The context is shown in the Manager column, in the details and in the search of the editor tab. Unlike the slot it is kept when the save game is replaced, and it applies to reports that start afterwards.

A report also names the save slot the manager worked with (SlotName, and SlotEntry for slots with entries). It is shown in the list, in the details and in the search of the editor tab.

  • SaveToSlot, LoadFromSlot, the ...ByName variants and SaveToEngineSlot / LoadFromEngineSlot set it automatically.
  • If you handle slots yourself and call Save() / Load() directly, call UPulseSaveManager::SetReportSlot(SlotName, EntryId) (Blueprint: Set Report Slot). GetReportSlotName() returns it.
  • The slot belongs to the save game: SetSaveGame and ClearSaveGame forget it, so call SetReportSlot after SetSaveGame. This keeps a report from showing the slot of a save game that is no longer loaded.
  • Single-object and static-model reports carry the slot that was set when they were collected. If the slot changes, what was collected before is written first.
  • UPulseSaveUtils::LoadStaticModelFromSlot has no manager, so its report names the slot it read from.
  • The slot is empty if nothing set it.

Messages of a model

A model can write messages into the list that goes into the report. This is also possible for models that succeed.

C++ / Blueprint Meaning
LogInfo(Message) Information that helps to understand what happened.
LogWarning(Message) Something unexpected that did not stop the model.
LogError(Message) Something went wrong.

They are available on every model (UPulseSaveModelBase). Call them from the hooks of a model, from IPulseSaveInterface::OnSave / OnPostLoad (they receive the model as a parameter), or from a migration (Context.NewModel). In Blueprint they are normal nodes (“Log Info”, “Log Warning”, “Log Error”).

  • The messages are also written to the log (LogPulseSave).
  • A model that wrote at least one error counts as faulty in the report and makes the report count as failed. It does not change the result of the process: bWasSuccessful and the completion callbacks stay as they are.
  • Infos and warnings never make a model faulty.
  • A model stores at most 100 messages per operation. The rest is counted (DroppedMessageCount).
  • Messages are only stored if reports are not Disabled in the current build.

The editor tab

Open it with the console command PulseSave.OpenReports, or from the editor menu that lists the tabs, where it is registered in the Developer Tools group as Pulse Save Reports.

  • Left: the list of reports, newest first, with result, time, kind, manager, number of models and number of faulty models. Search, “Only failed” and a filter by kind narrow it down.
  • Right, top: the details of the selected report: result, kind, time, manager, world, build, duration, and the counters (records, static models, migrations, skipped, timeouts).
  • Right, bottom: the models, split into two views:
    • Faulty models: models that failed, timed out or wrote an error.
    • Succeeded models: all others, including skipped ones.

    Every model is one row with type, result, class, duration and number of messages. Expand it to see the reason of a failure, its details (record type, class, duration, migration) and the messages it wrote, colored by severity. Models that failed or wrote messages start expanded. Search and the Info / Warnings / Errors switches filter the models and messages. The context menu copies a row or all messages of a model.

  • Toolbar: Refresh, Open Folder, Open File…, Delete, Delete All.
  • The tab updates by itself when a report is written in the running editor (PIE). Reports written by another process appear after Refresh.

Reports of a packaged game

In a packaged game reports are written to <Project>/Saved/PulseSave/Reports of the installed game (by default only for failures). To look at one in the editor, copy the file to your machine and use Open File…. Reports of another plugin version (the file has a reportVersion) are not opened.

Files

Reports are JSON files in <Project>/Saved/PulseSave/Reports, named yyyyMMdd-HHmmss-fff-####_<Kind>_<Save|Load>_<Manager>_<Ok|Failed>.json. They are written in the background. The directory can be found with Pulse::Save::Report::GetReportDirectory(). To react to a new report in code, bind IPulseSave::Get().OnReportWritten() (file path, whether the report has failures). Pulse::Save::Report::EnumerateReportFiles and LoadReportFromFile read them again.


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