Skip to content
Tuxedo CatSTUDIO
Menu

Persistence and Save Game Integration

Probability Director persistence preserves the approved deterministic state needed to continue supported Probability Director Streams across a save/load cycle.

Probability Director does not own your save slots, save files, autosave schedule, cloud storage, or encryption.

A simple way to think about it is:

Probability Director
|
+--> prepares/restores Probability Director state
|
v
Your SaveGame system
|
+--> stores that data
|
v
Save file / platform storage

This document explains:

  • What Probability Director persistence is for.
  • Which Streams are restored.
  • The difference between Ephemeral, PersistState, and RotateOnSave.
  • What CampaignId means.
  • What PersistenceGeneration means.
  • How save and restore workflows should be structured.
  • Why RotateOnSave uses a prepare/commit workflow.
  • What BeginNewCampaign does.
  • What Probability Director does not persist or encrypt.
  • How the optional DirectorBridge Probability.SaveGame adapter fits in.

Use Probability Director persistence when a saved game needs Probability Director to continue from the correct deterministic Runtime state after loading.

For example:

Player starts campaign
|
+--> Combat.Damage Sequential Stream advances
+--> Loot.DropTable Sequential Stream advances
|
+--> Game is saved
|
+--> Application closes
|
+--> Save is loaded later
|
+--> Probability Director restores approved state
|
+--> persisted Streams continue according to their persistence contract

Without persistence, a recreated Sequential Stream would normally begin from newly initialized state instead of continuing from the saved campaign state.


2. What Probability Director Persistence Does

Section titled “2. What Probability Director Persistence Does”

Probability Director persistence can preserve the approved internal deterministic state associated with Streams whose persistence policy requires it.

Its job is to maintain Probability Director continuity.

It can participate in workflows involving:

  • Saving a campaign.
  • Loading a campaign.
  • Continuing Sequential deterministic state.
  • Maintaining campaign identity.
  • Rotating persisted state on successful save.
  • Rejecting incompatible or stale restore data.

3. What Probability Director Persistence Does Not Do

Section titled “3. What Probability Director Persistence Does Not Do”

Probability Director does not decide:

  • Save slot names.
  • Save file paths.
  • Autosave timing.
  • Quick-save behavior.
  • Cloud synchronization.
  • User profile selection.
  • Which save slot should be loaded.
  • Whether the player is allowed to overwrite a save.
  • Save-file encryption.

Those responsibilities belong to your game’s save/storage system.


A Probability Director Stream can use a persistence policy appropriate to its gameplay role.

The important Version 1 policies are:

  • Ephemeral
  • PersistState
  • RotateOnSave

These policies describe what happens to Probability Director Stream state when your game saves and restores.


An Ephemeral Stream is Runtime-only.

Its state is not restored from Probability Director persistence.

Conceptually:

Create Ephemeral Stream
|
+--> use it during this Runtime session
|
+--> save game
|
+--> Stream state is not included for later restore

After loading a save, the Stream must exist again through the normal Stream creation/configuration workflow if gameplay still needs it.

Its prior Runtime progression is not restored.


Use Ephemeral when the Stream does not need save/load continuity.

Examples may include:

  • Temporary minigame randomness.
  • Session-only cosmetic variation.
  • Debug/test Streams.
  • Short-lived systems whose random progression should not survive loading.

Suppose:

Stream ID:
UI.RandomAnimation
Persistence Policy:
Ephemeral

The Stream may advance during gameplay.

If the player saves and later reloads:

UI.RandomAnimation

does not resume its previous Probability Director state.

That is expected.


PersistState preserves the approved Probability Director deterministic state needed to continue the Stream after restore.

Conceptually:

Runtime Stream state
|
+--> Save
|
+--> Probability Director persistence snapshot
|
+--> Host stores it

Later:

Host loads save
|
+--> provides Probability Director persistence data
|
+--> Probability Director validates and restores

Use PersistState when continued Stream progression across saves is part of the gameplay contract.


Suppose:

Stream ID:
Combat.Damage
Seed Source:
Fixed
Decision Mode:
Sequential
Persistence Policy:
PersistState

The Stream has already produced several gameplay results:

Roll 1
Roll 2
Roll 3
Roll 4

The player saves.

After restoring the save, the next result should continue from the restored approved Stream state.

Conceptually:

Before Save:
1 -> 2 -> 3 -> 4
After Restore:
-> 5

It should not silently restart from:

1

unless your gameplay intentionally created a new campaign/Stream identity.


RotateOnSave adds an important transactional rule:

A new persistence state is prepared for saving, but Probability Director commits the rotation only after the host confirms the save succeeded.

This avoids changing Runtime persistence state when the save file itself was not successfully stored.


9. Why RotateOnSave Uses Prepare and Commit

Section titled “9. Why RotateOnSave Uses Prepare and Commit”

Imagine Probability Director immediately changed its persisted state before the host finished writing the save.

Then this could happen:

Probability Director rotates state
|
v
Host begins writing save
|
v
Disk write fails

Now Runtime state may have moved forward even though the save file still contains the older state.

That can create an avoidable mismatch.

RotateOnSave prevents this by separating:

  1. Prepare.
  2. Host save.
  3. Commit only after success.

Conceptually:

Current Probability Director state
|
v
Prepare RotateOnSave candidate
|
v
Host writes complete SaveGame
|
+--> Save succeeded
|
v
Commit prepared rotation
|
v
New state becomes authoritative

The save operation and Probability Director rotation therefore remain coordinated.


If the host save fails:

Current Probability Director state
|
v
Prepare RotateOnSave candidate
|
v
Host attempts save
|
+--> Save failed
|
v
Do NOT commit candidate

Probability Director retains the correct pre-save Runtime state.

A failed or non-successful save must not be treated as a successful rotation.


Consider an ironman-style save workflow.

You may want each successfully stored save to move Probability Director to a fresh persistence generation.

But if the disk write fails, the game should not behave as though that save was successfully committed.

RotateOnSave provides that transactional boundary.


A prepared RotateOnSave candidate can become stale before commit.

For example:

Save A prepares generation candidate
Save B prepares/commits newer state
Save A later tries to commit

Save A’s prepared candidate is now stale.

Probability Director rejects the stale commit instead of silently overwriting newer persistence state.

Diagnostics may report:

StaleRotateOnSaveCommit

Typical causes include:

  • Two saves overlapping.
  • Another persistence generation committing first.
  • Save ownership not being coordinated.
  • An asynchronous save callback arriving later than expected.
  • More than one system attempting to manage Probability Director save state.

If you see:

StaleRotateOnSaveCommit

check:

  1. Which system owns save sequencing?
  2. Can two saves overlap?
  3. Did a later save commit first?
  4. Are prepare/commit callbacks matched to the correct save operation?
  5. Is an old asynchronous completion callback trying to commit stale state?

Do not bypass the stale check.

It protects persistence consistency.


CampaignId identifies the Probability Director probability campaign.

Think of it as:

Which playthrough/probability universe does this persisted state belong to?

A normal save/load within the same campaign keeps the campaign identity.


Suppose a player has:

Campaign A
Campaign B

Both campaigns may contain Streams named:

Combat.Damage
Loot.DropTable
World.Encounters

The Stream IDs alone do not mean their persisted random state should be interchangeable.

CampaignId helps identify which Probability Director campaign the persisted state belongs to.


If persistence data belongs to a different campaign than the one Probability Director expects, restore can be rejected.

That is safer than silently loading unrelated deterministic state.

Diagnostics may surface repeated restore rejection when this happens repeatedly.


BeginNewCampaign creates a new Probability Director campaign identity while preserving registered Stream configurations according to the native contract.

Conceptually:

Old Campaign
|
+--> BeginNewCampaign
|
+--> new CampaignId
+--> registered Stream configuration remains according to contract
+--> old campaign deterministic state is no longer treated as current

Use it when gameplay truly starts a new campaign/playthrough probability identity.


Good examples:

  • Player chooses New Game.
  • A new roguelike run begins.
  • The application intentionally creates a new probability campaign.

Do not call it merely because:

  • A level changed.
  • A checkpoint was reached.
  • A normal save completed.
  • The user opened a menu.
  • PIE ticked again.

Repeated unintended calls may produce:

RepeatedBeginNewCampaign

diagnostics.


A useful mental model is:

New Game
-> BeginNewCampaign
Save Game
-> capture/prepare current Probability Director persistence
Load Game
-> restore saved Probability Director state

A normal Load Game does not create a new campaign.

It restores the saved campaign identity/state.


PersistenceGeneration identifies the generation of Probability Director persisted Stream state.

It is persistence metadata.

It is not:

  • Number of random calls.
  • Sequential RNG position.
  • Number of rolls.
  • Keyed occurrence.
  • Game session number.
  • Lifecycle epoch.

Suppose successful RotateOnSave operations advance persistence generations:

Generation 1
|
Save succeeds
|
Generation 2
|
Save succeeds
|
Generation 3

The number refers to persisted state generations.

It does not tell you how many random numbers were generated between them.


24. Persistence Generation in the Runtime Inspector

Section titled “24. Persistence Generation in the Runtime Inspector”

The Probability Director Runtime Inspector may display:

Persistence Generation

When no persisted Stream-state generation applies, such as an Ephemeral Stream, it shows:

N/A

Do not use this field to infer Sequential RNG advancement.

Use diagnostic Sequential Effect to understand whether an individual retained operation advanced Sequential state.


A Save As operation normally represents:

Store the same current campaign under a different save-slot/file identity.

It does not automatically mean:

Start a new Probability Director campaign.

Where the native workflow specifies campaign identity preservation, Save As keeps the same CampaignId.

The host save system owns the slot/file name.

Probability Director owns the probability campaign identity.

Those are different concepts.


Suppose:

CampaignId:
Campaign-ABC

The player has:

SaveSlot_A

and chooses Save As:

SaveSlot_B

Both save files may still represent:

Campaign-ABC

because changing the storage filename/slot is not the same as starting a new campaign.


Restore accepts Probability Director persistence data from the host save workflow.

Probability Director validates the restore before applying it.

Possible rejection causes include:

  • Campaign mismatch.
  • Persistent Stream mismatch.
  • Malformed data.
  • Incompatible data.
  • Unexpected persistent configuration.
  • Invalid generation state.

A rejected restore must not be silently treated as successful.


Conceptually:

Host loads SaveGame
|
v
Read Probability Director persistence payload
|
v
Give payload to Probability Director restore API
|
v
Probability Director validates
|
+--> Valid
| |
| v
| Restore state
|
+--> Invalid
|
v
Reject restore

Restore should be treated as one persistence operation.

Do not partially apply pieces of saved deterministic state manually.

Use the approved Probability Director restore API so validation and state application remain coordinated.


Diagnostics may report:

RepeatedRestoreRejection

when restore failures occur repeatedly.

Check:

  1. Is this the expected campaign?
  2. Are the expected persistent Streams configured?
  3. Does the save belong to this plugin/runtime contract?
  4. Is the save malformed or incomplete?
  5. Is caller code repeatedly retrying the same invalid restore?

Do not expose raw persistence secret contents in logs while investigating.


Ephemeral Streams are not restored from saved Probability Director state.

Example:

Persistent:
Combat.Damage
Ephemeral:
UI.RandomAnimation

After restore:

Combat.Damage
-> restored according to persistence contract
UI.RandomAnimation
-> not restored

The game may recreate the Ephemeral Stream normally if it still needs one in the new Runtime session.


Restore is not a substitute for correct Runtime Stream configuration.

The host/game should establish the expected Probability Director environment according to the native persistence workflow.

If persistent Stream configuration does not match the saved state, Probability Director can reject the restore rather than guess.


Persistence policy and Seed Source are separate concepts.

A Stream can be:

Fixed + Ephemeral
Fixed + PersistState
Secure + Ephemeral
Secure + persisted policy

where supported by the native configuration contract.

Do not assume:

Fixed = persistent

or:

Secure = ephemeral

They answer different questions.


Decision Mode is also separate from persistence.

A Stream may be:

  • Sequential.
  • Keyed.

Persistence exists to preserve the approved Runtime state required by the native contract.

Keyed requests still use explicit Decision Keys and Occurrence.

Persistence does not create a hidden Keyed occurrence counter.


Your host save system should coordinate the overall save.

Conceptually:

Game Save Data
Player Data
World Data
Quest Data
Probability Director Data
Other Systems
|
v
USaveGame / Save Framework
|
v
Save Slot / Storage

Probability Director contributes its own persistence data.

It does not replace the rest of your SaveGame architecture.


For a normal persisted-state workflow:

1. Game decides to save
2. Gather normal game data
3. Gather Probability Director persistence state
4. Store all data through host SaveGame system
5. Confirm save succeeded
6. Complete any required Probability Director post-save commit

The exact native function names depend on the selected persistence policy/workflow.


1. Host loads save data
2. Recreate/prepare the expected game Runtime context
3. Provide saved Probability Director state to restore API
4. Check restore result
5. Continue gameplay only after successful required restoration

Do not ignore a restore rejection and continue as if persisted random state was restored correctly.


A RotateOnSave host workflow is more explicitly transactional:

1. Begin save
2. Ask Probability Director to prepare save/rotation candidate
3. Put prepared persistence data into host SaveGame
4. Save host SaveGame
5. If host save succeeds:
commit prepared Probability Director rotation
6. If host save fails:
discard/do not commit prepared rotation

The important rule is:

Host save success controls whether the prepared rotation is committed.


Incorrect:

Prepare
-> Commit Probability Director
-> Try to write save
-> Save fails

Preferred:

Prepare
-> Write save
-> Confirm success
-> Commit

This is the central reason RotateOnSave is transactional.


SaveGame Director is optional, and Probability Director persistence works independently of it.

For projects using both owners, DirectorBridge provides the optional adapter identified as Probability.SaveGame.

The owners retain these responsibilities:

  • Probability Director owns RNG algorithms, streams, decision keys, stream state, probability mechanics, and persistence payload semantics for its state.
  • SaveGame Director owns save/restore orchestration, contributor lifecycle, and required/optional contributor policy.
  • DirectorBridge owns registration and adaptation between the owners.

Pairwise SaveGame integration is not supported in current releases. Probability Director remains standalone, and DirectorBridge is not a required Probability Director dependency.

See SaveGame Director Integration and Migration.


You can integrate Probability Director persistence with:

  • Standard Unreal USaveGame.
  • Your own save manager.
  • Another storage system.
  • A project-specific serialization layer.

Your save system simply owns storage/orchestration.

Probability Director owns validation and its approved persisted deterministic state.


Low-level persistence snapshots and restore operations are native APIs.

Persistence internals are intentionally not exposed as editable Blueprint data.

This prevents gameplay graphs from directly manipulating sensitive deterministic state.

Blueprint gameplay can still use the normal Probability Director Stream/random APIs.

The host persistence layer should call the approved native integration path.


43. Persistence Data Is Not a User-Editable Format

Section titled “43. Persistence Data Is Not a User-Editable Format”

Do not treat raw Probability Director persistence data as:

  • Designer configuration.
  • Console-variable data.
  • Human-editable JSON.
  • A gameplay scripting format.
  • A public RNG seed file.

Use the native serialization/restore contract.


Probability Director persistence is plaintext unless the host application encrypts its storage.

This means:

Probability Director protects API boundaries, but it does not claim that the save file is confidential merely because some Runtime internals are not exposed through Blueprint or the Inspector.

If save confidentiality matters, the host storage system must provide encryption/security.


Normal public tooling does not expose raw persistence secrets.

The Probability Director Runtime Inspector intentionally omits:

  • Raw persistence bytes.
  • Secure root material.
  • Keys/nonces.
  • Raw RNG state.
  • Numeric Sequential cursor.

Persistence serialization may contain internal data needed to restore deterministic state.

Treat that data as implementation state, not as public editable configuration.


Persistence and diagnostics solve different problems.

Persistence Diagnostics
Continue Runtime state Observe Runtime behavior
Used across save/load Bounded recent history
Contains approved restore state Sanitized/redacted
Can affect future deterministic behavior Must not affect gameplay
Not a debugging log Not a save format

Never attempt to restore Probability Director state from an Inspector export.


A Fixed Seed identifies how a deterministic Stream begins.

Persistence preserves where supported Runtime state has progressed to.

Example:

Fixed Seed = 12345

and:

Persisted Sequential state after 10,000 operations

are not the same thing.

Recreating a Stream from the original Fixed Seed may restart the sequence.

Restoring the persisted Stream continues from the saved deterministic state.


Keyed decisions are designed around explicit semantic identity.

Example:

Namespace
Stable Subject ID
Decision
Occurrence

The caller should not rely on persistence to create a hidden Keyed cursor.

Persistence and Keyed identity remain separate concepts.


“Ephemeral means the Stream cannot be used normally.”

Section titled ““Ephemeral means the Stream cannot be used normally.””

Incorrect.

It can be used normally during the Runtime session.

It simply is not restored from Probability Director persistence.


“PersistState means Probability Director writes my .sav file.”

Section titled ““PersistState means Probability Director writes my .sav file.””

Incorrect.

Your host save system stores the data.


“RotateOnSave should commit as soon as Save begins.”

Section titled ““RotateOnSave should commit as soon as Save begins.””

Incorrect.

Commit only after the host confirms successful storage.


“PersistenceGeneration is the number of random calls.”

Section titled ““PersistenceGeneration is the number of random calls.””

Incorrect.

It identifies persistence-state generation.


“Save As should create a new CampaignId.”

Section titled ““Save As should create a new CampaignId.””

Not normally.

Changing the storage slot/file does not inherently mean starting a new probability campaign.


“BeginNewCampaign should run every level.”

Section titled ““BeginNewCampaign should run every level.””

Incorrect.

Use it when starting a genuinely new campaign/playthrough probability identity.


“Probability Director encrypts its saved state.”

Section titled ““Probability Director encrypts its saved state.””

It does not.

Encryption belongs to the host storage/security layer.


“I can manually edit persistence bytes to change RNG state.”

Section titled ““I can manually edit persistence bytes to change RNG state.””

Do not do this.

Use the approved native persistence API.


Check:

  1. Campaign identity.
  2. Expected persistent Stream configuration.
  3. Save compatibility.
  4. Whether data is malformed/incomplete.
  5. Native restore status.
  6. Diagnostics warnings.

Check:

  1. Was the Stream Ephemeral?
  2. Was Probability Director state actually stored in the save?
  3. Did restore succeed?
  4. Was the correct campaign loaded?
  5. Was the Stream recreated/restored through the intended workflow?

Check:

  1. Are saves overlapping?
  2. Did another save commit first?
  3. Are asynchronous callbacks matched to the correct prepared candidate?
  4. Is more than one save manager calling Probability Director persistence?

Check whether the New Game workflow actually called:

BeginNewCampaign

and whether the host accidentally restored state from the previous campaign.


Need Use
Runtime-only Stream Ephemeral
Continue Stream state through normal save/load PersistState
Advance persisted state only after successful save RotateOnSave
Start a genuinely new playthrough identity BeginNewCampaign
Store/load the actual save file Host SaveGame system
Transactional SaveGame Director integration Optional DirectorBridge Probability.SaveGame
Encrypt save contents Host storage/security layer
Inspect persistence warnings Probability Director Runtime Inspector / Diagnostics

A simple project architecture is:

Gameplay Systems
|
v
Probability Director Runtime
|
+--> persistence snapshot / transaction
|
v
Game Save Manager
|
+--> Player state
+--> World state
+--> Quest state
+--> Probability Director state
|
v
USaveGame / platform storage

This keeps responsibilities clear.


Player chooses New Game
|
v
Create new gameplay campaign
|
v
Probability Director BeginNewCampaign
|
v
Create/register expected Streams
|
v
Begin gameplay

Use the exact ordering required by your native integration, but keep the semantic responsibility clear:

New Game creates a new probability campaign identity.


Player chooses Load
|
v
Load host SaveGame
|
v
Prepare expected Runtime context
|
v
Restore Probability Director state
|
+--> Success
| |
| v
| Continue gameplay
|
+--> Failure
|
v
Handle load failure / compatibility issue

Do not hide a Probability Director restore rejection behind an apparently successful load.


Ephemeral
= Runtime only
= not restored
PersistState
= preserve approved deterministic state
RotateOnSave
= prepare state
= save through host
= commit only after save success
CampaignId
= which probability campaign/playthrough
PersistenceGeneration
= which persisted state generation
= NOT RNG position
BeginNewCampaign
= create new probability campaign identity
Save As
= normally same campaign, different host storage identity
Encryption
= host responsibility
SaveGame Director
= optional

Probability Director persistence preserves the deterministic state needed to continue a probability campaign, while your game’s SaveGame system remains responsible for actually storing, loading, and protecting the save data.


  • API Overview — Stream lifecycle, GameInstance ownership, and API responsibility boundaries.
  • Probability Director Runtime Inspector — Persistence Policy, Persistence Generation, Events, and warning inspection.
  • Diagnostics and Warnings — StaleRotateOnSaveCommit, restore rejection, and campaign-reset warnings.
  • Installation — standalone Probability setup and optional integrations.
  • Known Limitations — persistence internals and encryption limitations.