Autosave
Debounce, ceiling, minimum interval, coalescing and pause flush — the numbers that decide when an autosave happens, and what it costs per frame.
Dirty tracking, not polling#
Autosave is driven by change, not by a timer. Something meaningful happens, the game says so, and the coordinator decides when the write is due:
var autosave = new AutosaveCoordinator(
options.Autosave,
new DelegateSaveStateSource((slot, reason, token) => Slots.SaveAsync(slot, model, request, token)),
context.Clock,
context.Sequences);
autosave.MarkDirty(AutosaveReason.Milestone); // when something meaningful changed
autosave.Tick(TimeSpan.FromSeconds(Time.unscaledDeltaTime)); // once per frame; it decidesTick does not capture, serialise or write. It accumulates time and decides. Measured cost for an idle game: 0.03 ms per frame, which is what makes calling it from Update reasonable. Verified
The four numbers#
| Setting | Default | What it means |
|---|---|---|
DebounceDelay | 2 s | How long the game must stay unchanged before a write starts. |
MaximumDelayBeforeSave | 60 s | The longest the oldest unsaved change may wait, however busy the game is. |
MinimumIntervalBetweenWrites | 10 s | Bounds how often storage is touched. |
SaveOnPauseRequested | true | Treat "the app is being paused" as a reason to write. |
AutosaveOptions.SlotId defaults to autosave, so autosaves never overwrite a player's manual save.
Why it does not stutter the game#
- One write at a time. A burst of changes coalesces into a single save; a second save while one is running is superseded rather than queued up behind it.
- Work off the main thread. Autosave asks the dispatcher for a capture on the main thread, then saves the snapshot on a worker. It never reads a Unity object from a worker thread.
- Failure is a result. A failed autosave does not throw into a frame; it is reported, and the game keeps running with its previous save intact.
Defining "meaningful" in your game#
AutosaveReason exists so a save can say why it happened, which shows up in metadata and diagnostics: Manual, Interval, ExitRequested, SceneBoundary, FocusLost, Milestone, Checkpoint, External.
class="tok-com">// A checkpoint reached, a boss defeated, a chapter closed — these are milestones.
autosave.MarkDirty(AutosaveReason.Milestone);Next#
- Checkpoints — deliberate recovery points, on the same pipeline.
- Configuration reference — every autosave setting with its cost.
- Performance — how the numbers above were measured.
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