Save and recover a protected balance
Keep recovery identities stable and test a load in a new process.
Prepare the native session
Portable persistence needs application-owned bootstrap. Blueprint or AI alone does not provision recovery secrets.
- Obtain the owner’s existing key ID and random 32-byte recovery secret through your protected account/recovery system. Generate a key with
FScientificNumberRecoveryKeys::Generateonly for a genuinely new owner. - Retain a shared
FScientificNumberRecoveryKeysring. Add the key with its stable nonzero ID. Preserve old keys while their records remain supported; erase temporary buffers after use. - Choose
FScientificNumberFileSaveStorefor local Win64 storage, or implementIScientificNumberSaveStorefor trusted storage. CompareExchange must atomically enforce the expected revision. - Create and retain a
UScientificNumberSaveSession. Initialize it once with profile, stable game-domain GUID, authenticated owner, key ring and store. Inspect the initialization result and error. The initialized session cannot be rebound.
Never generate a replacement key to hide a load failure. Losing the original recovery secret makes its records unrecoverable. Do not place production secrets in Blueprint defaults, public assets or a file beside the saved data.
Save from Blueprint
Expose the initialized session to gameplay with proper Unreal ownership. Create a Safe value of 12345, then call the session’s Save with Slot TutorialWallet and Expected Revision 0 for a new slot. Branch on success, retain Out Revision and inspect Out Error on failure.
For later writes, use the revision you actually read or committed. On conflict, load and re-evaluate the gameplay operation; do not repeatedly write a stale balance with guessed revisions.
Close and recover
- Close the complete game process after a successful save.
- Start a new process and bootstrap with the same key IDs/secrets, domain, owner and slot.
- Call Load. Minimum Revision can enforce an independently trusted lower bound; zero accepts the available authenticated revision.
- On success, authenticate the returned Safe value with Try Get Safe Number.
The new process recovers 12345. A wrong key, wrong identity or altered record is rejected rather than loaded as zero.
Context and authority
Use SaveContextBound and LoadContextBound when the in-memory value is context-bound. Memory context and save identity are distinct inputs. Do not serialize opaque AI handles or raw in-memory Safe bytes as a save format.
LocalPortable detects authenticated tampering and cooperating-writer conflicts. It cannot prevent the machine owner restoring an old complete snapshot. TrustedServer requires genuinely trusted identity, storage and revision state; selecting that enum does not create a backend.
Storage calls are synchronous. Schedule slow backend work deliberately and retain the session and dependencies for the operation. See the shipped Documentation/PortableSafePersistence.md for the native contract and legacy provider boundary.