About unity-data-persistence
unity-data-persistence is a Unity save/load system built around DTO data binding. It suits game developers who need entity state to stay linked to save data, with interchangeable serialization and storage services.
Key features
- 01Bind entities directly to DTOs
- 02Save and load GameData
- 03Use stable SerializableGuid identities
- 04Swap storage and serializer backends
- 05Bind lists of multiple entities
Use cases
- 01Saving player and inventory state
- 02Restoring scene entities from saved data
- 03Starting with flat GameData fields
- 04Changing local JSON storage to another backend
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ muharremtozan/ unity-agent-skills --skill unity-data-persistenceAfter installing, type/unity-data-persistencein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
assets/code/FileDataService.cs.txtPersistenceCore.cs.txtSaveLoadManager.cs.txtSaveLoadSystem.cs.txtreferences/guide.mdDetails
From the project READMEUnity Data Persistence
Implement a professional Save/Load system built around data binding: saveable objects hold a live reference to a DTO that is always up-to-date, making serialization near-instant and backend-agnostic.
Inspired by adammyhre/Unity-Inventory-System.
Core Architecture
SaveLoadSystem
├── IDataService (FileDataService by default)
│ └── ISerializer (JsonSerializer by default)
└── GameData (your root DTO)
├── PlayerData (ISaveable) ←─ Hero.Bind()
└── InventoryData (ISaveable) ←─ Inventory.Bind()
Core Features
- Data Binding Pattern: MonoBehaviours hold a reference to their own DTO, so saving is just serializing GameData — no polling, no property walking.
- IBind<T> / ISaveable: Two interfaces that wire scene entities to their save data at scene load time.
- SerializableGuid: Stable, fast GUID identity (int-based comparison) for matching saved data to spawned entities.
- Swappable Backend:
IDataService+ISerializerlet you change from local JSON to Cloud/Binary with a one-line change. - Multi-Entity Binding: List-based
Bind<T, TData>(List<TData>)handles many-entity scenarios (enemies, spawners).
Core Files (Max 3)
PersistenceCore.cs.txt—ISerializer,JsonSerializer,IDataService,ISaveable,IBind<T>,SerializableGuidFileDataService.cs.txt— Local disk implementation: Save, Load, Delete, DeleteAll, ListSavesSaveLoadSystem.cs.txt— Persistent MonoBehaviour orchestrator withBind<T,TData>()and public Save/Load/New API
Usage
Quick Start (Light Path — no binding needed)
// 1. Extend GameData with your fields
[Serializable] public class GameData {
public string Name;
public int Score;
}
// 2. Save / Load
SaveLoadSystem.Instance.gameData.Score = 100;
SaveLoadSystem.Instance.SaveGame();
SaveLoadSystem.Instance.LoadGame("MySave");
Full System (Pro Path — data binding)
// 1. Create a DTO
[Serializable] public class PlayerData : ISaveable {
[field: SerializeField] public SerializableGuid Id { get; set; }
public Vector3 position;
}
// 2. Implement IBind on your MonoBehaviour
public class PlayerEntity : MonoBehaviour, IBind<PlayerData> {
[SerializeField] SerializableGuid id;
PlayerData data;
public SerializableGuid Id { get => id; set => id = value; }
public void Bind (PlayerData d) { data = d; data.Id = id; transform.position = d.position; }
void Update () { data.position = transform.position; } // write-through
}
// 3. Register in SaveLoadSystem.OnSceneLoaded
Bind<PlayerEntity, PlayerData>(gameData.playerData);
See references/guide.md for complete examples including multi-entity binding and backend swapping.
Key Principle
Design your data model first. The DTO structure IS your save format. Start simple (GameData with flat fields) — add binding only when entities need independent, restorable state.