# Save and Load

`SaveLoadManager` is the static entry point to the save system. Use it to run the same save, load, and profile operations available through Instructions.

## Read manager state

Read these properties when your UI or gameplay needs to react to the current load state:

| Member | Reports |
| :--- | :--- |
| `IsLoading` | Whether a load is in progress. |
| `IsLoaded` | Whether a save has been loaded this session. |
| `CurrentProfile` | The profile currently loaded. |

## Run save operations

Choose the operation based on whether you're writing state, restoring a profile, or starting a new game:

| Method | Does |
| :--- | :--- |
| `Save(int profile)` | Collects profile-scoped data and writes it. |
| `SaveShared()` | Writes shared data only. |
| `Load(int profile)` | Restores a profile. Asynchronous. |
| `Delete(int profile)` | Erases a profile. |
| `Unload(int sceneIndex)` | Resets to a fresh state and loads a scene. Asynchronous. |

## Query saved profiles

These methods identify saved profiles before you load or display them:

| Method | Returns |
| :--- | :--- |
| `HasAnyProfileSaved()` | Whether any profile holds a save. |
| `HasProfileSaved(int profile)` | Whether a specific one does. |
| `GetProfileDate(int profile)` | The date it was written. |
| `GetLastSavedProfile()` | The most recently written profile, or `-1`. |

This sequence loads the most recently saved profile when one exists:

```cs
if (SaveLoadManager.HasAnyProfileSaved())
{
    int profile = SaveLoadManager.GetLastSavedProfile();
    await SaveLoadManager.Load(profile);
}
```

The existence check prevents `GetLastSavedProfile` from returning `-1` to `Load`.

## Subscribing

Objects implementing [`ISaveLoad`](../extending/save/isaveload.md) register themselves:

```cs
private void Awake()     => SaveLoadManager.Subscribe(this);
private void OnDestroy() => SaveLoadManager.Unsubscribe(this);
```

The matching `Awake` and `OnDestroy` methods keep the subscriber registered for exactly its component lifetime.

!!! warning "Unsubscribe in OnDestroy"
    A subscriber that's destroyed without unsubscribing stays in the list. The next save calls `OnSave` on the destroyed component.

## Events

The manager raises events before and after each operation:

| Event | Fires |
| :--- | :--- |
| `EventBeforeSaveProfile` / `EventAfterSaveProfile` | Around a profile save, with the profile number. |
| `EventBeforeSaveShared` / `EventAfterSaveShared` | Around a shared save. |
| `EventBeforeLoad` / `EventAfterLoad` | Around a load, with the profile number. |
| `EventBeforeDelete` / `EventAfterDelete` | Around a delete. |
| `EventBeforeReset` / `EventAfterReset` | Around a reset to a fresh state. |

For example, a save indicator can subscribe while its component is enabled:

```cs
private void OnEnable()
{
    SaveLoadManager.EventBeforeSaveProfile += this.OnBeforeSave;
    SaveLoadManager.EventAfterSaveProfile  += this.OnAfterSave;
}

private void OnDisable()
{
    SaveLoadManager.EventBeforeSaveProfile -= this.OnBeforeSave;
    SaveLoadManager.EventAfterSaveProfile  -= this.OnAfterSave;
}
```

`OnBeforeSave` and `OnAfterSave` receive profile-save notifications only while the component is enabled. You can also use manager events to gather state before a save or apply settings after a load.

!!! warning "Don't save from inside a save event"
    Calling `Save` from a save callback re-enters the system while it's iterating its subscribers. If you need to write something during a save, do it in the *before* event so it's captured by the save already in progress.

## Loading is asynchronous

`Load` and `Unload` return `Awaitable` because they load scenes:

```cs
await SaveLoadManager.Load(0);
```

Anything after the await runs in the new scene, which means the object that started the load may no longer exist. Either drive loads from an object that survives scene changes, or don't rely on continuing afterward.

`Load` does nothing if the profile holds no save or a load is already in progress. This prevents a double-clicked load button from starting two concurrent loads.

## Order of restoration

The manager restores state in this order:

1. Read the snapshot.
2. Restore persistent subscribers in priority order.
3. Load recorded scenes.
4. Restore scene-bound subscribers as their objects initialize.

`ISaveLoad.IsPersistent` selects which side of the scene load restores the object.

## Where to go next

- **[ISaveLoad](../extending/save/isaveload.md)** — make your own types participate in saving.
- **[Extending the save system](../extending/save/index.md)** — replace storage, serialization, or encryption.
- **[Save & Load](../../manual/save-load/index.md)** — inspect the designer-facing lifecycle.
