AirConsole Games Features
Improving your game engage

Persisting Player Data

17min

What is the Persistent Storage API?

The Persistent Storage API enables your game to store data on behalf of your players to continue anywhere, anytime.

You can think of the Persistent Storage API as AirConsoles version of a save game system that stores the data for players but with additional possibilities towards unique game designs that go well beyond traditional savegame capabilities.

Before you get started

There are different ways to implement persistent data storage for your game depending on your game design.

This gives you unique possibilities to use persistent data as a gameplay feature in your game design.

1. Which players need to store and request part of the game state

  • You can store and request data for every player in the game and selectively decide what to apply when and where (see Working with data from multiple connected players below).
  • You can store and request data for the player driving the session (see Persisting data only for the controlling player below).
When working with the Persistent Storage API, keep in mind that the storage limit is 1MB per UID per game!

2. How do you want to use and persist the data in your game

  • Decide at what points you want to store the persistent data.
  • Decide what happens when the owner of the persistent data leaves: - Will future updates to the persistent data be stored for the leaving owner of the current game state? - If not, will the players be able to continue but the general game state progress will no longer be persisteted, only player specific personal progress? - Or do you use the flexible capabilities to offer a unique approach?
  • Remember the players uids for which persistent data was requested for the lifetime of the usage of this game state to persist it for the correct player again.

Working with data from multiple connected players

AirConsoles Persistent Storage API nature as key - value based store gives you unique flexibility in deciding which controller contributes what information to the game worlds state This allows you to request and store data for multiple players in the same game and enable an optimal experience by combining the data in ways providing the best game experience.

Example

  • Level unlocks are taken from the device with the most advanced state and to this device this part of the state is persisted.
    • example key: level_progress
  • But every player can have their own unlocks (characters, gadgets, skins, abilities, features, ...) which are stored based on their uid.
    • example key: player_progress

In this example, the game requests and stores the progress of the world state, global quests or content unlocks in level_progress while storing personalized player progress information in player_progress.

When the players connect the game would request level_progress for all players and select the most advanced state. The game would also request player_progressfor all players and apply it to the corresponding player to unlock player specific aspects.

Such a hybrid achives the best results, if the corresponding game experiennce and game progression is optimized for AirConsole early in the game design and playtesting process, allowing you to create an experience your players want to come back to often and increasing your income.

Persisting data only for the controlling player

If you are working with the controlling player (using GetMasterControllerDeviceId()) to load the game state, then you need to consider the different cases arising from this Id changing as players join or leave the game.

GetMasterControllerDeviceId() can change during the runtime of the game due to connects / disconnects and you don't want to (re)load or store the data for the wrong player.

Examples

  • If a premium user connects to a game with non-premium users only, then the master device will change to the premium device.
  • If the master device disconnects a different connected device will become master. Simply storing the persistent data to the now current master device would duplicate the state of the original players data to the new player while not updating the progress for the original player! The game needs to remember the UID of the device for which the game state has been requested and used.

Important considerations when not providing a UID to storePersistentData / requestPersistentData

From AirConsole API 1.9.0 and Unity Plugin 2.5.0 onwards, the possibility to call StorePersistentData / RequestPersistentData without providing a UID will be removed.

If you are not providing a UID to StorePersistentData / RequestPersistentData, then the data will be stored for the device that calls the function.

This is a convenience functionality when using it the Persistent Storage API on your controller. You must not rely on this convencience when using it on the screen!

The screen does not have a persistent uid (incognito mode, security features, plugins). Due to this, the screen commonly is unable to restore persistent data reliably (browser and car in particular)!

Persisting data in web games

The web examples assume that you have already set up your game similar to the pong example and have an object like var airconsole = new AirConsole();.

Storing Persistent Data

  • Implement function `handlePersistentDataStored` that does something based on the UID, for example a visual confirmation.
  • Register an event listener to airconsole.onPersistentDataStored = handlePersistentDataStored; Alternatively you can also directly declare the functionairconsole.onPersistentDataStored = function(uid) { // do something based on the uid };
  • After onReady was invoked, call
string uid = airconsole.getUID(airconsole.getDeviceId()); if(uid) { airconsole.storePersistentData("dataKey", { keyA: "data a", keyB: "data b" }, uid); } else { console.error("master controller has no UID yet, was onReady really invoked?"); }

Retrieving Persistent Data

  • Implement function `handlePersistentDataLoaded` that processes the loaded persistent data.
  • Register an event listener to airconsole.onPersistentDataLoaded = handlePersistentDataLoaded; Alternatively you can also directly declare the functionairconsole.onPersistentDataLoaded = function(data) { // do something now with the data };
  • After onReady was invoked, call something like
var controllers = airconsole.getControllerDeviceIds(); var uids = controllers.map(it => airconsole.getUID(it)) || []; if(uids.length > 0) { airconsole.requestPersistentData(uids); }

Persisting data in Unity games

Please see ExampleBasicLogic.cs for an example implementation.

Storing Persistent Data

  • Implement an event handler `HandlePersistentDataStored` that processes the received persistent data.
  • Register an event listener to AirConsole.instance.onPersistentDataStored += HandlePersistentDataStored;
  • After onReady was invoked, call
string uuid = AirConsole.instance.GetUID(AirConsole.instance.GetDeviceId()); if(!string.IsNullOrEmpty(uuid)) { JObject exampleData = new JObject(); exampleData.Add ("test", "data"); AirConsole.instance.StorePersistentData("example_data", exampleData, uid); } else { Debug.Error("MasterController has no UID yet, was onReady really invoked?"); }

Retrieving Persistent Data

  • Implement an event handler `HandlePersistentDataLoaded` that processes the received persistent data.
  • Register an event listener to AirConsole.instance.onPersistentDataLoaded += HandlePersistentDataLoaded;
  • After onReady was invoked, call something like
List<string> uids = new List<string>(AirConsole.instance.GetControllerDeviceIds() .Select(id => AirConsole.instance.GetUID(id)) .Where(id => !string.IsNullOrEmpty(id))); if(uids.Count > 0) { AirConsole.instance.RequestPersistentData(uids); }

Persisting data does not work, I have the following problem:

When reopening the game after storing the state, I can not get the stored state