Your first load
LoadAsync, why a missing save is an outcome rather than an error, and how migration and recovery reports arrive.
Reading a save back#
var loaded = await NexusForgePersistence.Slots.LoadAsync<MySaveModel>(
new SaveSlotId(class="tok-str">"default"),
new LoadRequestOptions { TargetSchemaVersion = new SchemaVersion(1) });
if (loaded.IsSuccess && loaded.Value.Loaded)
{
mySaveModel = loaded.Value.Data;
}
else if (!loaded.IsSuccess)
{
class="tok-com"> // The read itself failed: a damaged file, a missing key, a migration gap.
Report(loaded.Error);
}loaded.IsSuccess is about the operation. loaded.Value.Loaded is about the content: a slot that was never written comes back with Loaded == false and an outcome of LoadOutcome.NotFound.
"There is no save yet" is not an error#
A first run is a normal condition, not a failure. Branching on the outcome is the difference between a title screen that starts a new game and one that shows the player a scary error:
switch (loaded.Value.Outcome)
{
case LoadOutcome.Loaded: StartFrom(loaded.Value.Data); break;
case LoadOutcome.NotFound: StartNewGame(); break; // a normal first run
}What comes back with the data#
SaveLoadResult<T> carries more than the payload, and each part is there because a game needs it:
| Member | What it is for |
|---|---|
Data | Your model, projected back onto the same shape it was captured from. |
Metadata | Schema version, timestamps, playtime, revision, game/build/platform identity. |
Descriptor | The cheap header information a slot listing uses. |
MigrationReport | Which schema steps ran, in order, and what each one did. |
RecoveryReport | Whether a damaged primary was quarantined and a backup used instead. |
CarryOver | Members this build does not know about, preserved for the next one. |
Warnings | Things worth telling you that are not failures. |
When the save is older than the build#
Set TargetSchemaVersion to the version your build understands and the framework runs the registered migration chain to get there. A missing step is reported as NF.PERSIST.MIGRATION.PATH_MISSING rather than guessed at, and the Editor's validation catches the gap before a player does. Details in Migration.
When the save is newer than the build#
By default the framework refuses a save whose schema is newer than the build understands, because reading it would mean guessing at a shape the build has never seen. If you ship a launcher or a beta channel that must read forward, LoadRequestOptions lets you opt in per call, and Configuration → Versioning can allow it globally if that matches your release model.
Next#
- Save and load — the full API, including listing, export and import.
- Restore — applying a loaded document back onto live Unity objects.
- Troubleshooting — the load error codes in the order people meet them.
Something wrong on this page? Every page here describes behaviour that is checked in the repository. If a page and the package disagree, the package wins.
Report a documentation problem · Frequently asked questions · Troubleshooting