Saving and Loading¶
Game Creator comes with a flexible mechanism to keep track of changes made at runtime and store these by calling a simple Save()
method. Likewise, restoring any previously saved game can be done executing a Load()
method from the class responsible for managing this functionality.
Storage Location¶
Game Creator makes it very easy to choose how data is saved. By default it uses the Player Prefs system from Unity, which stores all the data in a file which varies its location depending on the runtime platform. See the Unity documentation for Player Prefs for more information.
Storage Encryption¶
Game Creator also makes it very easy to encrypt your game saves using various encryption algorithms, which you can choose from the dropdown button above the storage location.
The default algorithms are very simple ones that prioritize speed over security.
- None: No encryption is applied. This is the default value.
- XOR: A symmetric algorithm that obfuscates the data by performing a logic XOR operation with a pass-phrase.
- Caesar: Another symmetric algorithm that obfuscates the data by shifting each alphanumeric value by a number specified.
What can be saved and loaded¶
The Save/Load system can save any primitive serializable field: integers, booleans, strings, positions, rotations or any managed instance type marked with the [System.Serializable]
attribute.
However, it does not serialize objects inheriting or fields referencing objects that inherit from Unity.Object
. For example: Game Objects, Transforms, MonoBehaviours, ...
Save Slots¶
Most games allow to store multiple saves and allow the user to choose which one to restore when loading a previous saved play. With Game Creator, each one of these save spaces are called slots and they are represented by an integer number ranging from 1 up to 999.
Note
Notice that you can have up to 998 slots. The number 0 is reserved for shared settings.
Saving¶
To save a game, it's as easy as calling the Save(slot: integer)
method through the SaveLoadManager
singleton class. This class is responsible for tracking all objects in the scene and silently collects their state in a background process. Saving a game can be done using the following line, passing a constant save slot number 1 as a parameter:
SaveLoadManager.Instance.Save(1);
By default, the saving system uses Unity's PlayerPrefs system, which blocks the main thread until al data is written. However, Game Creator provides tools that allow to customize how data is saved. You could even have an online database where you dump the player's save files.
Because we can't assume the saving will be done synchronously, the Save(slot: int)
method returns a Task
that can be awaited. This is very useful if you plan on synchronizing the game save with an external database, such as Steam, Firebase or any other online data warehouse service.
To handle these cases, all that needs to be done is use an async method and await the result. Like so:
public async Task MySaveFunction()
{
Debug.Log("Start saving game");
await SaveLoadManager.Instance.Save(1);
Debug.Log("Game has been saved");
}
However, if you are using the default PlayerPrefs save system or your custom one does block the main thread when saving, you can either await the task or use a discard operator:
public void MySaveFunction()
{
Debug.Log("Start saving game");
_ = SaveLoadManager.Instance.Save(1);
Debug.Log("Game has been saved");
}
Loading¶
Loading a previously saved game is very similar to saving one.
It is important to highlight that loading a game forces to unload the current scene and loads the saved one afterwards. Even if they are the same.
SaveLoadmManager.Instance.Load(1);
The Load(slot: int)
method returns a Task
object, just like the Save(slot: int)
. You can choose to either await the load or, in most cases, use the discard operator:
public void MyLoadFunction()
{
_ = SaveLoadManager.Instance.Load(1);
}
Deleting¶
A user may want to delete all the information associated to a save slot. This can be done using the following line:
SaveLoadManager.Instance.Delete(1);
The Delete(slot: int)
method also returns a Task
object. However, in this case, it may be more interesting knowing when a delete operation has finished.
Events¶
The saving and loading system contains 6 events that programmers can hook onto to detect when a saving and a loading process has started.
public event Action<int> EventBeforeSave;
public event Action<int> EventAfterSave;
public event Action<int> EventBeforeLoad;
public event Action<int> EventAfterLoad;
public event Action<int> EventBeforeDelete;
public event Action<int> EventAfterDelete;
For example, doing something when a save operation is about to start can be achieved subscribing to the EventBeforeSave
event:
void Start()
{
SaveLoadManager.Instance.EventBeforeStart += this.OnBeforeSave;
}
public void OnBeforeSave(int slot)
{
Debug.Log("About to save game in slot " + slot);
}
You can subscribe to as many methods as you need in each event. However, make sure to remove the subscription when the class that is doing subscribing is destroyed. For example, following the excerpt from above, it would also be optimal to do:
void OnDestroy()
{
SaveLoadManager.Instance.EventBeforeStart -= this.OnBeforeSave;
}
Customize¶
As mentioned before, Game Creator doesn't assume a specific save or load procedure. In fact, it provides with tools to customize how data is collected and stored in order for the developer to customize it and tailor it to its needs.
In the following sections we'll see how to: