Save system (870022)

If you have no experience, it might be best to first use a prebuilt solution like something from the Asset Store, just to learn those concepts and see the limitations in action. Then you can always write your own.

At the same time, you can follow a few tutorials. Just a random one that I remember doing: Persisting Objects

But, don’t just take any single thing for an answer. Look at multiple approaches, make your own experiments and then apply what you’ve learned to your own project. Maybe at this point you want to implement a custom save system, maybe you no longer feel the need or found something perfect along the way.

My dev studio used different practices in the past:

Key-Value Storage
Something like PlayerPrefs, but custom. You can build things like GetInt(string key), but also more complex: GetVector, GetArray etc. Everything is stored in dictionaries and serialized to a file. All components go through this global system and save/load their individual state or some managers manage the process for sub-objects. It’s all spaghetti and might become too confusing, but it’s very flexible. You can turn this system into something designer-driven, e.g. let developers add keys and values directly in the inspector and assign them to prefabs, which on certain actions saves other values (e.g. a quest system or inventory collect thingy). Some topics like versioning the save file can become difficult with this approach, because everything is scattered, or you would have to add additional features from other approaches to make this possible.

Save Game As Single Source Of Truth
There’s a single class called GameState and it contains everything that needs to be saved, nested in a completely serializable hierarchy. All systems have a reference to this single class or parts of it, but there’s only one copy (a singleton potentially). This means, once loaded, all systems simply use this state and write to it, then somebody can save the structure to a file at any point. This system is very easy to understand, because nothing is copied and everyone has the most recent state of things etc. It’s also probably one of the fastest approaches performance-wise because there’s only a single step involved. However, it tightly couples all components to this big model or parts of it, which reduces flexibility. But things like versioning become easy, because now version 1 is just a single file and model, version 2 a different one and you can add upgraders in between and just pass the new data to the rest of the game.

Serializer Passed To Subsystems
Combine both approaches. Somewhere, a serializer loads a file and the reference to this class is passed to all implementers of ISaveable. Each class takes the data it needs or stores it. If its key/value based, the order doesn’t matter. If its binary, the ordering is important and probably impossible to implement. Some commercial products work by making the ordering deterministic via GUID keys or manually maintaining an orderer list of saveable components. In any case, you may be able to split the big monolith into multiple parts to make different systems more flexible.

File Format
I recommend pretty-printed JSON because its a good balance between performance and editing/debugging. You can even use a ScriptableObject as the data model and then serialize it to JSON. This makes it possible to store save games as assets in the project (maybe as starting points or for cheating/testing). You can see and edit values directly in the inspector. Unity’s JsonUtility is extremely fast and supports all types which show in the inspector (but this means its bound to the same limitations, no dictionaries for example). Other serializers handle more complex data types, but are slower, e.g. Json.Net.
For maximum performance, a custom binary solution is best. Nothing beats a handcrafted serializer which is hardcoded to every property in the game and writes out the minimum number of required bytes to represent the data. However, its also very maintenance heavy. Some libraries build on top of this idea. A search for “serializer” turns up many good results. To name a random one: MessagePack. Keep in mind, you can beat even the best serializer library performance-wise, but probably not in regards to time spent on implementing and maintenance.

Representing Game State
The most difficult task: how to represent Unity GameObject state with any system? Everything else is easy: score values, player progress data, inventory, achievements, all can usually be stored as some strings and ints. But scene state (position of GameObjects, active state, animations) are more difficult because the data needs to be converted and the internal Unity state recreated somehow. The most common and practical solution is to build systems for every part of your game. E.g. if the board spawner spawns board game tokens, it can also represent each token position in the save file and load it to spawn it from saved positions). A PlayerController can keep track of its position and rotation and write it to file and load that. You see, it becomes a nightmare for big games, but it works. Some things will give you headaches, like recreating animation state, coroutines, etc. All of these have solutions, but they are involved.
Some systems attempt to generalize the process. For example, they walk the entire GameObject hierarchy and store the Transform data of each object. Each known component type has some sort of Handler that knows how to serializer/deserializer its state. However, this also breaks down easily in a fight between tradeoffs. If you save everything you waste massive amounts of space and time. But to optimize the system you will need to mark things as saveable or not, or even individual properties, and now you’re building an entire editor system to configure the previously hardcoded save/load systems. If anyone (or Unity) introduces new components, you also need to add new specific handlers. This is probably the most complex way of doing things and only yields benefits if both game and team are large.

22 Likes
Saving/Reading Prefab Data Unity 3D
Saving and loading an array (JSON)
need help with bool saving
Save system & permanent upgrades during development.
How to save current scene play
How can I save and load progress bar?
Unity freezing everytime i try to save a tilemap.
Storing Instantiated Buildings
What's the best way to build Stats system and Save/Load your Stats?
How to have multiple values in dictionary
Each scene with different saved data?
Vector3 export to WriteAllText
how to forbid start and awake
Button Destroy
Unity Button not marked as serializable?
can i save a unity scene during runtime?
Saving player position and scene
"Save Game Free" how to use??
Which is the best method to use for creating Save/Load game functionality
Can't Deserialize Sprite
Help with my SaveSystem?
How to get a prefab from code
Append Highscore and display results
Does C# support a wrapper class to make all members unchangable?
How can I save an object as is?
I need a "simple" save system for my game
What is the correct way to deserialise your save file?
How could I save enemies' positions and hp with PlayerPrefs
Saving player data between scenes
How can i save a gameobject in unity?
I don't know how to save/load my inventory
Does this saving system have any major flaws?
Save & Load System
What is the best way to save the state of world objects in Unity
How to create a save system for a sandbox survival game?
How do i save data in Unity?
Saving/Loading Dynamic Scriptable Objects
Creating passive items that assign effects and subscribe to events
Best Solutions to Backup Game Settings
Keeping Items when changing between scenes
Line Renderer Save (902728)
Unable to save games on mobile(both iOS and Android), works fine in editor. Using Odin Serializer.
How can I transfer a list of game objects between two scenes using GameManager?
Players all time stats
The best way to save data
Error on saving and loading due to clone of game object
Trouble with Loading Json Files
How to modify a game scene using a script?
Disabling objects forever
How do I save my instantiated object?
Saving Tilemap
[Resolved] save system help needed
Save arrays by Binary?
Can't access one class from another
Saving inventory between scenes in 2D game.
How to save a GameObject and its randomly generated sprite ?
should I save levels as json or in a script?
memorize objects or actions at scene change
Saving position from multiple scenes
No Save!
How to make a Multiplayer Save System to JSON No servers
Designing Dynamic Spell Unlocking and Progression System with ScriptableObject
Saving objects in the scene along with their components and the components' variables' values?
Saving and Loading Reference to Material/Asset (using Addressables?)
JsonUtility.ToJson() not serializing everything
Scene Progress Saving (through c#) Unclear
i need help... i try to load my game that i saved but i get a error.
SaveGame, it's not saving the player's status it just resets the values in the loader
Scriptable Object and Data Base
Save/Load gameobjects with references to prefabs/Scriptable objects
How can I make a save&load for chat messages from ChatGPT API?
Importing lists of custom objects from JSON
How to implement checkpoints
How can i save 2 numbers at once in playerprefs?
How do I write custom classes to a JSON file?
Does not find information to add to the list
Help to find best save system solution please
How would i make it so that dialogue appears once forever
How to Track Player Progress in a Deep Dungeon?
constructor gives null error
need help for saving highscore for different scenes
What is the best pattern for saving references to prefabs/scriptable objects
Save/Load System considerations
Which is the best way to save in-game world environment
Using scriptable objects in the other half of the game project
Good code for data saving
Save/Load Error
Saving multiple gameObjects in the Index of a list
Struggling with complex data
A Read File Text Problem when i build Game
Save and load system detail questions
saving drawings drawn in unity
custom .bin file location
Should I use scriptable object or just normal script to save my settings
How to save an Instantiated prefab as a child?
Player position issue on load save
How to save an int array to a JSON file for saving and loading
How to make the level selection screen?
Explain like I'm 5. How to save a players progress
How to make level saves
Saving Multiple Objects
Save data, each scene?
Why i cant destroy an object?
Need help with saving inventory
How do i save my map to json?
I want to save my grid of tiles which are different colour so it can be reloaded later acting as a level saver. Not sure how to do it though
Save/Load System Not Working
How to save and restore level state correctly?
How would you architect a game with a generated map like path of exile?
How can I update the database information in a installed App when the player pays for an upgrade
Handling Scenes and Data Persistence in Large-Scale Platformer Games
Saving object positions between scene loads (super amateur question)
Can anyone take a look at my scripts and help me out
Save & Load System on SceneUnloaded, SceneLoaded, and OnApplicationQuit Broke on Android Build
(Trying to learn)Saving player data/unlocks? No clue where to start
Reference Error, but I am unsure why
Saving and accessing sprites during runtime
Loading .json wont work in build
How to explicitly write changes into serialized fields manually during runtime?
I have a problem with my saving & loading system
Persistent player data management - design patterns and architecture
Problem with Asset: Simple and Powerful Inventory System by Jax's Studio
Need help deciding how to save
Need your help on my 2d Space rocket game
How to know if player has been in scene
Getting Adressables adress of an asset at runtime
Handle house interiors and customization Unity 2D
How do I build a save system for a complex 3D game?
How do you serialize a scene in json and references then load it all back?
Saving/Loading groups and lists of variable length?
How to store multiple values inside a gameobject
How to save object's position and make it return
3D array is referenced by two separate game objects