# Save System

The **Save System** allows persistent saving and loading of component state across scenes.

## Components

### [ISaveable](https://github.com/MeshMap/com.meshmap.sdk.bb/blob/main/Runtime/SaveSystem/ISaveable.cs)

* Interface to make a behaviour's state persistent.
* Must define a `SaveId` (string) and state serialization logic.

### [SaveableMonoBehaviour](https://github.com/MeshMap/com.meshmap.sdk.bb/blob/main/Runtime/SaveSystem/SaveableMonoBehaviour.cs)

* Base `MonoBehaviour` implementing `ISaveable` for convenience.
* Override save/load methods to store component-specific data.

### [SaveManager](https://github.com/MeshMap/com.meshmap.sdk.bb/blob/main/Runtime/SaveSystem/SaveManager.cs)

* Central controller that manages all `ISaveable` components in the scene.
* Assigns unique IDs and coordinates save/load operations.
* Editor inspector includes:
  * **Assign SaveIds to All Saveables** – Generates IDs for unassigned components.
  * **Clear and Reassign** – Resets IDs and clears stored preferences.

### [SaveManagerUI](https://github.com/MeshMap/com.meshmap.sdk.bb/blob/main/Runtime/SaveSystem/SaveManagerUI.cs)

* Optional UI component to expose save/load/reset actions to the player.

### [SavePrefs](https://github.com/MeshMap/com.meshmap.sdk.bb/blob/main/Runtime/SaveSystem/SavePrefs.cs)

* Static helper for storing save data in `PlayerPrefs`.
* Includes `ResetAll()` to clear all stored state.

## Example Workflow

1. Add `SaveManager` to your scene.
2. Implement `ISaveable` on components whose state should persist.
   1. Tip: inherit from `SaveableMonoBehaviour` for clean integration with Unity callbacks.
3. Auto-assign unique `SaveId`s to each object using the `SaveManager` Inspector component.
4. Call `SavePrefs` methods or use `SaveManager` to save/load.
5. Add an optional button to your in-app UI to call `SaveManager.ResetAllSaveables()`.

## Example Code

```csharp
// Example implmentation of the Save System for a collectable object, like a pickup item in a game.
public class Collectable : SaveableMonoBehaviour<CollectableState>
{
    protected override CollectableState DefaultState => CollectableState.NotCollected;

    protected override void Awake()
    {
        base.Awake();
        
        // Deactive the collectable GameObject if it was already collected during a previous session
        if (_currentState == CollectableStatus.Collected && DeactivateOnComplete)
        {
             gameObject.SetActive(false);
        }
    }

    // Update the save status of the collectable GameObject so it is not active in the next session
    public void GetCollected()
    {
        State = CollectableState.Collected;
        SetSaveStatus();
        if (DeactivateOnComplete)
        {
            gameObject.SetActive(false);
        }
    }
}
```
