A simple, extensible save system for Unity built on top of Newtonsoft JSON, under the Widwickyy.SaveSystem namespace.
- Easy to use - Static facade for quick access
- Extensible - Swappable serialization and storage backends
- Versioned saves - Built-in version field for future migrations
- Optional AES encryption - Encrypt save payloads with a user-provided key
- Type-safe - Generic methods with compile-time type checking
- JSON based - Human-readable save files
- Open your Unity project
- Navigate to
Window > Package Manager - Click the
+button in the top-left corner - Select
Add package from git URL - Enter:
https://github.com/widwickyy/UnityPackage-Save-System.git#1.0.0
- Download or clone this repository
- Open your Unity project
- Navigate to
Window > Package Manager - Click the
+button - Select
Add package from disk - Navigate to the folder containing
package.json
For development purposes, add this repository as a subfolder in your Assets folder.
using UnityEngine;
using Widwickyy.SaveSystem;
// Initialize the save system (call once at app start)
SaveManager.Initialize();
// Optional: initialize with AES encryption key
// SaveManager.Initialize(version: 1, encryptionKey: "your-secret-key");
public class PlayerData
{
public string playerName;
public int level;
public float health;
}
public class GameManager : MonoBehaviour
{
private void Start()
{
// Save data
var playerData = new PlayerData
{
playerName = "Hero",
level = 5,
health = 100f
};
SaveManager.Save("player", playerData);
// Load data
var loadedData = SaveManager.Load<PlayerData>("player");
if (loadedData == null)
return;
Debug.Log($"Welcome back, {loadedData.playerName}!");
}
}┌─────────────────────────────────────────────────────────────────┐
│ SaveManager │
│ (Static Facade) │
└───────────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SaveSystem │
│ (ISaveSystem Implementation) │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SaveWrapper<T> │ │
│ │ - version (int) │ │
│ │ - data (T) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ ISerializer │ │ IStorage │ │
└──┼──────────────────┼─────────┼──────────────────┼──────────────┘
▼ ▼ ▼ ▼
┌─────────────────────┐ ┌──────────────────┐
│ NewtonsoftSerializer│ │ FileStorage │
└─────────────────────┘ └──────────────────┘
Static facade providing global access to the save system.
// Initialize the save system (call once at startup)
SaveManager.Initialize();
// Initialize with AES encryption key
SaveManager.Initialize(version: 1, encryptionKey: "your-secret-key");
// Save data
SaveManager.Save<T>(string key, T data);
// Load data (returns default(T) if not found)
T result = SaveManager.Load<T>(string key);
// Check if a save exists
bool exists = SaveManager.Exists(string key);
// Delete a save
SaveManager.Delete(string key);For dependency injection and custom implementations:
using Widwickyy.SaveSystem;
public interface ISaveSystem
{
void Save<T>(string key, T data);
T Load<T>(string key);
bool Exists(string key);
void Delete(string key);
}Implement your own serializer:
using Widwickyy.SaveSystem;
public interface ISerializer
{
string Serialize<T>(T data);
T Deserialize<T>(string json);
}Implement your own storage backend:
using Widwickyy.SaveSystem;
public interface IStorage
{
void Write(string key, string data);
string Read(string key);
bool Exists(string key);
void Delete(string key);
}using Newtonsoft.Json;
using UnityEngine;
using Widwickyy.SaveSystem;
public class CustomSerializer : ISerializer
{
public string Serialize<T>(T data)
{
return JsonConvert.SerializeObject(data, Formatting.Indented);
}
public T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
}Enable encryption by passing an encryptionKey during initialization:
SaveManager.Initialize(version: 1, encryptionKey: "my-strong-key");Notes:
- Encrypted files are stored as Base64 text containing IV + ciphertext.
- Keep the same key between sessions or decryption will fail.
- Existing plain JSON saves are not auto-migrated when encryption is enabled.
using UnityEngine;
using Widwickyy.SaveSystem;
public class PlayerPrefsStorage : IStorage
{
public void Write(string key, string data)
{
PlayerPrefs.SetString(key, data);
PlayerPrefs.Save();
}
public string Read(string key)
{
return PlayerPrefs.GetString(key, null);
}
public bool Exists(string key)
{
return PlayerPrefs.HasKey(key);
}
public void Delete(string key)
{
PlayerPrefs.DeleteKey(key);
}
}using UnityEngine;
using Widwickyy.SaveSystem;
public class CustomSaveManager : MonoBehaviour
{
private ISaveSystem _saveSystem;
private void Start()
{
// Use a custom serializer and storage
var serializer = new CustomSerializer();
var storage = new PlayerPrefsStorage();
_saveSystem = new SaveSystem(serializer, storage, version: 1);
// Now use _saveSystem directly
_saveSystem.Save("player", new PlayerData { playerName = "Hero" });
}
}The system internally wraps saved data in SaveWrapper<T> and includes a version field for forward compatibility.
Current behavior:
SaveManager.Load<T>()returns only yourTdata (not the wrapper).- Version metadata is written to disk automatically.
- Automatic migration hooks are not exposed yet in the public API.
If you need migration logic today, use a custom ISaveSystem implementation or read/write raw save payloads through a custom IStorage strategy.
FileStorage saves to Unity's Application.persistentDataPath:
| Platform | Location |
|---|---|
| Windows | %APPDATA%/../Local/Unity/[CompanyName]/[ProductName]/ |
| macOS | ~/Library/Application Support/Unity/[CompanyName]/[ProductName]/ |
| Linux | ~/.config/unity3d/[CompanyName]/[ProductName]/ |
| iOS | /Documents/ |
| Android | /data/data/[PackageName]/files/ |
Files are saved with .json extension.
A demo script is included in Runtime/Demo/SaveSystemDemo.cs demonstrating:
- Initializing
SaveManagerwith optional AES encryption - Saving and loading example player data
- Logging loaded data to verify round-trip serialization
To try it, add SaveSystemDemo to any GameObject in a scene and press Play.
An editor window is included at Tools > Save System > Save File Inspector (Editor/SaveFileInspectorWindow.cs) to:
- List JSON save files in
Application.persistentDataPath - Inspect formatted payload content
- Optionally decrypt AES-encrypted payloads using your key
- Unity 2022.0 or later
- Newtonsoft.JSON (via Unity Package Manager:
com.unity.nuget.newtonsoft-json)
MIT License - feel free to use this in any project.