Save System

This page covers how to add save/load support to your custom plugin.

Save Data Architecture

The Save plugin uses a registration pattern. Each plugin that needs persistence creates a save data class and registers it with the Save plugin. When a save is triggered, the Save plugin calls each registered provider to collect data. When loading, it distributes the saved data back.

Creating Save Data for Your Plugin

Step 1: Define the Save Data Class

Create a serializable class that holds your plugin's persistent state:

[System.Serializable]
public class FactionSaveData
{
    public List<FactionReputationData> reputations = new List<FactionReputationData>();
}

[System.Serializable]
public class FactionReputationData
{
    public string factionId;
    public int reputation;
}

Keep save data simple and serializable. Use primitive types, strings, lists, and simple nested classes. Avoid Unity object references (they can't be serialized to a save file).

Step 2: Implement Save Data Collection

Your plugin needs to collect its current state into the save data class and restore state from it:

Step 3: Register with the Save Plugin

Create a registration class that hooks into the Save plugin's lifecycle:

The save provider implements the collection and application methods and is called by the Save plugin when saving and loading.

Save Providers

A save provider wraps the collect/apply logic for the Save plugin to call:

Best Practices

  • Use a unique string key when registering your save provider (e.g., "factions"). This key identifies your data in the save file.

  • Handle missing data gracefully. If a player loads a save from before your plugin was installed, your data will be null.

  • Keep save data flat and simple. Complex object graphs are harder to serialize and more prone to versioning issues.

  • Test save/load with different scenarios: fresh start, mid-game save, save from older version without your plugin.

  • Guard against the Save plugin not being available (Spark.GetPlugin<ISavePlugin>() returns null). Your plugin should still work, it just won't persist data.

  • Don't store references to Unity objects in save data. Use entry IDs (strings) instead.

Last updated

Was this helpful?