How to store game state between sessions?!

A lot of beginners becoming the first steps in gamedev industry reaching one problem – why the hell Unity doesn’t store points, money or something else which I gained? Every time you start the game each script will be initialized according to default or values from the gameobject’s inspector. What if we want to persist acquired goods after close the game? Unity built-in class – PlayerPrefs, can give us a hand.

I am PlayerPrefs and I am helping

PlayerPrefs Class allow us to store 3 simple data types:

  • float
  • int
  • string

On the one side it seems to be a small possibilities for us but it’s enough to do basic operations. Data is stored like in associative array – an abstract data type composed of a collection of pairs (key, value). What is important that each possible key appears at most once in the collection. Let’s do some practice!

Saving data
If you want to save the data using PlayerPrefs Class you will use one of static method below. Choose method according to data type which you want to save.

// C# Code
PlayerPrefs.SetInt(„PlayerGold”, 1000);  
PlayerPrefs.SetFloat(„PlayerHealth”, 123.0f);  
PlayerPrefs.SetString(„PlayerName”, „John”);  

Once you have set this data you should save it. Now, You can do it manually by method:

// C# Code
PlayerPrefs.Save();  

It is not recommended to use Save() method every time when you set a new data. It will cause game performance. Unity will automatically save PlayerPrefs during OnApplicationQuit() method by default. But sometimes when game crashed and OnApplicationQuit() didn’t executed we will lose our game data from last game session. I strongly recommend to manually save PlayerPrefs at sensible ‘checkpoints’ in your game.

Loading data
Loading is similar to saving – to load certain value simply use it unique key to find it:

// C# Code
float playerHealth = PlayerPrefs.GetFloat(„PlayerHealth”, 100.0f);

int playerGold = PlayerPrefs.GetInt(„PlayerGold”);

string playerName = PlayerPrefs.GetString(„PlayerName”);  

What is also important is to note that we optionally can set a second parameter with custom default value. This value will be loaded when unique key not exist. If we didn’t use this parameter - PlayerPrefs will load default value of selected type.
Sometimes we need to know if given key exists. There is a very helpful method – HasKey():

// C# Code
PlayerPrefs.HasKey(„PlayerGold”);  

This method returns true or false according to if we previously saved given key-value pair.

Removing data
The last of functionalities which PlayerPrefs class offers is removing entries from stored data. You can remove selected key-value pair by method:

// C# Code
PlayerPrefs.DeleteKey(„PlayerHealth”);  

Also, You can remove all entries by:

// C# Code
PlayerPrefs.DeleteAll();  

In this short description, I showed you how we use a PlayerPrefs class. Now, you know how to store data between the sessions ;)

Only float, int and string?! What if I want more?

Sometimes we want save more complex structures than 3 types of variables. What if I want to save bool value or more complex types like arrays or vectors? Of course you can code your PlayerPrefs extensions – for example - simple save and load of bool values.

// C# Code
bool myBool = true;

// saving
PlayerPrefs.SetInt(„myBool”, myBool == true ? 1 : 0);

// loading
myBool = PlayerPrefs.GetInt(„myBool”) == 1 ? true : false;  

I assume that 1 is true and 0 is false. Then by conversion I can receive bool value from int. But in instance of arrays and vectors it will be harder sure? Thanks to Eric Haines from awesome Unity community. He created ArrayPrefs2 – a extended class of PlayerPrefs. Here you can find this class and it documentation.

With ArrayPrefs2 we can store types:

  • types from PlayerPrefs
  • Vector2
  • Vector3
  • Quaternion
  • Color
  • bool
  • and arrays of all types above.

Saving and loading in ArrayPrefs2 is simple like in original PlayerPrefs:

// C# Code
// Save bool value
PlayerPrefsX.SetBool(„myBool”,true);

// Load bool value
bool myBool = PlayerPrefsX.GetBool(„myBool”);  

Is PlayerPrefs secure?

This is a good question. If data is stored between session it must be saved somewhere of device memory. Is normal user can access to this data and cheat by change some values within? Unfortunately the answer is yes – PlayerPrefs is totally insecure. As amateur „hacker” can access and manually edit certain values. For the instance in Windows these values are stored in Windows Registry.

I am the H@ckerman!

The question is: How can I secure my prefs? In University of Games we using data encryption. Again you can by yourself code encrypted PlayerPrefs class with MD5 encryption for example, but good example is using EncyptedPlayerPrefs class created by Sven Magnus.

In another hand, you could simply use one of awesome plugins from assetstore:

  • Secured PlayerPrefs by Studio ZERO
  • PlayerPrefs Elite by UnityPlugins EU
  • EcryptPrefs – PlayerPrefs editor/encroptor by AvoEx
  • Armada PlayerPrefs by Dan Miller-Shroeder
  • EpicPrefs – PlayerPrefs on Steroids by Hot Totem Assets .

In my opinion it’s worth to invest in packages like above. Beyond encryption often we get other benefits like extended types and visual editor of stored values.

Conlusion

PlayerPrefs is very useful tool, which can be used to store basic values in your game. Base tool have some disadvantages like lack of security and small amount of value types to store. Fortunately Unity community take care of this class improvement. It is worth pointing out that PlayerPrefs is not an only way to persist data. Also, You can use serialization, .xml files or database but maybe I could write about that another time ;)

I hope it’s useful for you. If you have any comments or questions, please write them here!

Mateusz Olszewski - Lead Programmer



Show Comments