Contents
Lix Save System - Full Documentation
Author: SillyLix
Version: 2.1.0
License: License
Unity Version: 6000.0.61f1+
Download: itch.io
2. Videos
Usage Guide Video
How Lix Save System Works
1. Overview
The Lix Save System is a robust and modular data persistence solution for Unity. It has been completely rewritten to support dependency injection, modular encryption, and flexible serialization.
For beginners, you may want to look at Example Usage and the Tutorial.
Look at the Change Log for a list of updates and improvements in the latest version (2.1.0).
Supported Types
- All primitive types (e.g.,
int,float,bool,string, etc.) Vector2,Vector3,Vector4QuaterniondecimalList<T>(Note:Tmust be a supported type)Dictionary<TKey, TValue>(Note:TKeyandTValuemust be supported types)
Key Features
- Modular Architecture: Fully extensible via dependency injection interfaces.
- Type Safety: Validates that all saved types are supported; prevents type mismatches on load.
- AES Encryption: Built-in encryption support with configurable keys.
- Flexible Serialization: JSON by default; swap for custom serializers (XML, binary, etc.).
- Custom Handlers: Replace encryption, serialization, or file I/O with your own implementations.
- Null & Object Safety:
SaveSystem.Setskips null values and rejectsUnityEngine.Objectreferences to avoid recursion. - File Lifecycle Helpers: Check if files exist, delete saves, clear data in memory.
- Pretty Print Support: Generate human-readable JSON files for debugging.
- (new) webGL Support: you can change the file I/O handler to support webGL environments. (It uses the PlayerPrefs in the backed to save data)
Namespaces
using SillyLixStudio.SaveSystem;– required to useGameData,SaveSystem, and related classes.using SillyLixStudio.SaveSystem.Interfaces;– required if you implement custom handlers viaIFileIO,IGameSerializer, orISaveSystemEncryption.
2. Core Classes
GameData
GameData is the primary data container. It holds the dictionary of saved values
and the configuration settings (GameDataConf). You will create one instance of
GameData
per save file.
GameDataConf
GameDataConf manages all settings for a specific GameData instance,
including
file paths, encryption keys, and the specific logic handlers (Encryption, Serialization, File
I/O).
Defaults: file name LixSaveFile, encryption off, pretty print off, extension
.lixsave, handlers AESEncryption + JsonGameSerializer +
SaveFile. You can swap handlers via the interfaces below.
SaveSystem
SaveSystem is a static class that acts as the bridge between your game logic and the whole
backend of the save system.
It provides the main API for saving/loading data, checking keys, and managing save files. You will call
its methods directly in your game code to interact with the save system.
3. System & Helper Classes
Beyond the core classes, the system uses several helper classes located in the
Systems
folder to handle specific tasks. While you rarely need to touch these directly, understanding
them helps
when extending the system.
SavedValue
A wrapper class stored inside the GameData dictionary. It holds two things:
- Value: The actual data (e.g., the integer "100" for health).
- Type: The C# System Type of the data. This ensures that if you save an
int, you get an error if you try to load it as astring, preventing data corruption.
SaveFile (Implements IFileIO)
This is the default File I/O handler. It is responsible for:
- Taking the
GameDataobject. - Passing it to the Serializer to get a string/byte representation.
- Passing that result to the Encryption handler (if encryption is enabled).
- Writing the final result to the disk at the path specified in
GameDataConf.
SaveWebGL (Implements IFileIO)
This is the webGL-compatible File I/O handler. It is responsible for:
- Taking the
GameDataobject. - Passing it to the Serializer to get a string/byte representation.
- Passing that result to the Encryption handler (if encryption is enabled).
- Writing the final result to the PlayerPrefs. So the data is saved locally in the browser using Unity's PlayerPrefs. P.S. This is a great example of how you can implement your own
IFileIO handler to support.
I added this for one of my projects that needed webGL support.
JsonGameSerializer (Implements IGameSerializer)
The default serializer included with the asset. It uses JSON formatting to convert your C#
objects into
text. It supports "Pretty Print" (via GameDataConf) for human-readable save files,
which is
useful for debugging. You can extend support for additional types by supplying custom JSON
converters in
your own serializer implementation (see Custom Serialization below); keep UnityEngine's Object
references
out of converters to avoid recursion.
4. API Reference
● SaveSystem Class API
The primary static methods for managing data.
You call these methods directly on the class (e.g., SaveSystem.API_METHOD_NAME()).
To save
a value:
SaveSystem.Set(myGameData, "PlayerScore", 100);
| Method | Description |
|---|---|
|
Saves a value (primitives, string, decimal, Unity
Vector2/3/4, Quaternion) to the data object. Null or
unsupported
types are skipped with a log. Updates if key exists.
|
|
Retrieves a value of type T. Returns default(T) if not found or type mismatch. |
|
Returns true if the key exists in memory for the provided
GameData.
|
|
Permanently removes a key and its value from the data object. |
|
Wipes all saved keys/values from memory (does not delete the file on disk). |
|
Checks if a save file exists for the configured path/name. |
|
Deletes the save file on disk for the provided GameData configuration.
|
|
Serializes and writes the current data to the file system based on configuration. |
|
Reads from the file system and populates the provided GameData object.
|
● GameDataConf Class API
Methods to configure how data is saved. Call them on the gameData.gameDataConf
instance.
For example:
GameData gameData = new GameData();
gameData.gameDataConf.SetFileName("MySaveFile");
| Method | Description |
|---|---|
|
Set or Get the name of the save file (e.g., "SaveFile1"). |
|
Set a custom folder path. Defaults to Application.persistentDataPath.
|
|
Enable or disable file encryption. |
|
Set the secret key used for encryption. |
|
Set the Initialization Vector for AES encryption. |
|
Set custom file extension (e.g., ".sav"). Only used for encrypted files. |
|
Enable readable JSON formatting (increases file size). |
|
Inject a custom encryption logic (e.g., XOR, AES or custom). |
|
Inject a custom serializer (e.g., JSON or custom). |
|
Inject a custom file writer (e.g., System.IO or custom). |
5. Customization & Interfaces
The Lix Save System is designed to be modular. You can replace core components by implementing
the
following interfaces and injecting them into GameDataConf.
Custom Encryption (ISaveSystemEncryption)
To create your own encryption method (e.g., a simple Caesar Cipher or RSA), implement the
ISaveSystemEncryption interface.
using SillyLixStudio.SaveSystem.Interfaces;
public class MyCustomEncryption : ISaveSystemEncryption
{
public byte[] Encrypt(byte[] data, string key) { /* Your logic */ }
public byte[] Decrypt(byte[] data, string key) { /* Your logic */ }
}
// Usage:
gameData.gameDataConf.SetEncryptionHandler(new MyCustomEncryption());
Custom Serialization (IGameSerializer)
If you prefer BinaryFormatter, XML, or a different JSON library, implement
IGameSerializer.
using SillyLixStudio.SaveSystem.Interfaces;
public class XMLSerializer : IGameSerializer
{
public string Serialize(GameData data) { /* Convert object to XML string */ }
public GameData Deserialize(string rawData) { /* Convert XML string to object */ }
public bool CanSerialize(System.Type type) { /* Check if type can be serialized */ }
}
// Usage:
gameData.gameDataConf.SetSerializer(new XMLSerializer());
You can also register custom converters in your serializer to support additional types. Only add
types
that do not contain UnityEngine.Object references to avoid recursion and stack
overflows.
Custom Storage (IFileIO)
To change where files are stored (e.g., saving to Steam Cloud, PlayerPrefs, or a database),
implement
IFileIO.
using SillyLixStudio.SaveSystem.Interfaces;
public class CloudStorage : IFileIO
{
public void Write(GameData data) { /* Upload to cloud */ }
public GameData Read(GameData data) { /* Download from cloud */ }
public bool Exists(GameData data) { /* Check cloud for file */ }
public void Delete(GameData data) { /* Delete from cloud */ }
}
// Usage:
gameData.gameDataConf.SetFileIOHandler(new CloudStorage());
Using Save System with WebGL
FULL DISCOLER: The Lix Save System uses the PlayerPrefs as the backend to save data in webGL. So when you call theSaveSystem.SaveToDisk(myGameData) method, it will serialize and encrypt (if enabled)
the data and then save it to the PlayerPrefs. When you call
SaveSystem.LoadFromDisk(myGameData), it will read from the PlayerPrefs, decrypt (if enabled),
and deserialize the data back into your GameData object.
// For this you will need to use the following namespace:
using SillyLixStudio.SaveSystem.Interfaces;
// To use the webGL-compatible File I/O handler change the handler in your GameDataConf like this:
GameData gameData = new GameData();
IFileIO webGLFileIO = new SaveWebGL(gameData.gameDataConf.GetSerializer(), gameData.gameDataConf.GetEncryptionHandler());
gameData.gameDataConf.SetFileIOHandler(webGLFileIO);
// alternatively, you can directly set it like this:
GameData gameData = new GameData();
gameData.gameDataConf.SetFileIOHandler(new SaveWebGL(gameData.gameDataConf.GetSerializer(), gameData.gameDataConf.GetEncryptionHandler()));
That is all. Now when you call SaveSystem.SaveToDisk(playerData) or SaveSystem.LoadFromDisk(playerData), it will use the SaveWebGL handler which saves data to PlayerPrefs in webGL builds.
6. Example Usage
using UnityEngine;
using SillyLixStudio.SaveSystem;
public class SaveSystemExample : MonoBehaviour
{
private GameData mySaveData;
private string playerName;
private int highScore;
private Vector3 playerPosition;
private void Start()
{
// 1. Create GameData instance
mySaveData = new GameData();
mySaveData.gameDataConf.SetFileName("PlayerSave1");
mySaveData.gameDataConf.SetIsEncrypted(true);
mySaveData.gameDataConf.SetEncryptionKey("unique-key-12345");
mySaveData.gameDataConf.SetEncryptionIV("unique-iv-67890");
}
void SaveData()
{
// 2. Save some data
SaveSystem.Set(mySaveData, "PlayerName", "Hero");
SaveSystem.Set(mySaveData, "HighScore", 1500);
SaveSystem.Set(mySaveData, "PlayerPosition", new Vector3(10f, 0f, 5f));
// 3. Write to disk
SaveSystem.SaveToDisk(mySaveData);
}
void Load()
{
// 4. Load from disk
if (SaveSystem.SaveFileExists(mySaveData))
{
SaveSystem.LoadFromDisk(mySaveData);
// 5. Retrieve data
// check if keys exist before getting
if (SaveSystem.HasKey(mySaveData, "PlayerName"))
{
// get values
playerName = SaveSystem.Get(mySaveData, "PlayerName");
}
if (SaveSystem.HasKey(mySaveData, "HighScore"))
{
highScore = SaveSystem.Get(mySaveData, "HighScore");
}
if (SaveSystem.HasKey(mySaveData, "PlayerPosition"))
{
playerPosition = SaveSystem.Get(mySaveData, "PlayerPosition");
}
Debug.Log($"Player Name: {playerName}, High Score: {highScore}, Position: {playerPosition}");
}
else
{
Debug.Log("No save file found.");
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
SaveData();
}
if (Input.GetKeyDown(KeyCode.L))
{
Load();
}
}
}
Quick Notes:
- Namespaces: Add
using SillyLixStudio.SaveSystem;. For custom handlers (exampleSaveWebGL), also addusing SillyLixStudio.SaveSystem.Interfaces;. - Supported Types: All primitives,
string,decimal, andVector2/3/4,Quaternion. - Safety: Call
LoadFromDiskfirst, then check keys withSaveSystem.HasKey(data, key)beforeGet<T>. - Unsupported Types: Unsupported values are skipped and logged without crashing.
- Encryption: Use
SetIsEncrypted(true)in production and provide secure key/IV. - File Ops:
SaveFileExists,DeleteSaveFile,ClearAllDataare available for lifecycle management.
Third-Party Attributions
The Lix Save System uses the following third-party libraries:
- Newtonsoft.Json (Json.NET) - Used for JSON serialization and deserialization. Licensed under the MIT License. newtonsoft.com
Contributors
Special thanks to all contributors and supporters of the Lix Save System.
Visual designer: Zahra
9. License
Unity Asset Store License
The Lix Save System is licensed under the Unity Asset Store End User License Agreement (EULA) if downloaded from the Unity Asset Store. By downloading or using this asset, you agree to the terms of the EULA. For full license details, please refer to the official Unity Asset Store EULA: https://unity3d.com/legal/as_terms
Itch.IO License
Overview: This license governs use of the provided assets and the rights granted to the Licensee.
1. Definitions
Asset(s): The files, code, and other materials provided by the Licensor.
End Product: A game, application, or other finished product in which the Asset is incorporated and distributed to end users.
2. Grant of License
The Licensor grants the Licensee a worldwide, non-exclusive, non-transferable license to:
- Use, reproduce, and modify the Asset as part of an End Product.
- Sell, distribute, or monetize the End Product containing the Asset.
3. Restrictions
Licensee may not:
- Distribute, sell, license, or make the Asset available in standalone form (source files) outside of an End Product.
- Claim the Asset as the Licensee’s own original work.
- Remove any required attribution or credits where specified by the Licensor.
- Redistribute the Asset as part of another asset pack, template, or library for resale or re-distribution.
4. Attribution
Attribution is NOT required for this asset, but it is very much so appreciated.
5. Ownership
Ownership: The Licensor retains all copyright and moral rights in the Asset. The Licensee receives only the rights expressly granted in this license.
6. Termination
Violation of any term of this license automatically terminates the rights granted. Upon termination the Licensee must cease using the Asset and remove it from any End Product distribution.
7. Disclaimer
Assets are provided "as is" without warranty of any kind. The Licensor is not responsible for any damages arising from the use of the Asset.
