We've covered how to save and load game statistics, but what if you need to store values that aren't integers? Perhaps you need more complex data types like strings, floats or even objects. In this case you can use the player data functions.
As with stats, data is saved to the cloud storage associated with the current player. There is a hard limit of 1MB per player, which is the total size of all the data combined. So, be careful how much you store, because once the limit is reached save requests begin to fail.
Saving Data
Phaser 3 has a built-in system called the Data Manager. All Game Objects have access to this and it's widely used through-out Phaser. It therefore made sense to integrate it with the Instant Games player data, and provides some useful features as you'll see in the examples below.
First, let's carry on the theme of our mock RPG game and imagine that you've just prompted the player to enter a name for their character and choose a pet, so we wish to store these for both the game to display, and to storage, so they persist across play sessions. We achieve this by setting them as values in the data manager:
this.facebook.on('savedata', function (data) {
// Handle what the game should do when the data saves
});
this.facebook.on('savedatafail', function (error) {
// Handle what the game should do if the data fails to save
});
this.facebook.data.set('name', 'Strix Skizziks');
this.facebook.data.set('pet', 'Owlbear');
Here we've created two new properties in the data manager, name
and pet
. These values are automatically synced with Facebook and you can listen for the savedata
event if you require confirmation of exactly when this happens.
Once set, you can access the values from anywhere in your game by getting them from the data manager:
var name = this.facebook.data.get('name');
If you need to save a large quantity of data at once then you can use the saveData
method directly:
var playerData = {
'class': 'Mage',
'gender': 'Woman',
'race': 'Tolkien Elf',
'racialAbility': 'Communion with Nature',
'sign': 'The Sign of the Great Feast',
'majorSkill': 'Ice Magic',
'minorSkill': 'Cooking',
'god': 'Pertinax, The Pig-Headed God',
'favouredStatistic': 'Sanity',
'combatBonus': 'Thac0 + (1/8 x (2/5 - 5/16))',
'beneficialTrait': 'Self-disciplined',
'disadvantageousTrait': 'Poor spatial awareness',
'home': 'A Mountain village'
};
this.facebook.saveData(playerData);
For example, you could use this if you need to populate a bunch of player data because they are new to your game.
It's also important to mention that while you can store objects as data values, they must be serializable. If you try to save an object that contains any non-serializable values then the entire save will be rejected.
Auto-Updating Values
Another feature of the plugin is that changes made to data store values are automatically saved. If we were to create a value holding the amount of gold a player has, we can then modify it at any point:
// We start the player off with zero gold
// (this is only done if the player data doesn't already exist)
this.facebook.data.set('gold', 0);
// Later in the game, they earn 10 gold:
this.facebook.data.values.gold += 10;
// Oh, a treasure chest!
this.facebook.data.values.gold += 250;
// Damn thieves ...
this.facebook.data.values.gold -= 30;
Because of the integration between the plugin and the SDK all of the above commands are perfectly valid, and will save the updated amounts to the cloud storage each time.
As with stats, at the time of writing, in version 6.2 of the Facebook SDK, there's no way to remove a data entry once saved. You can reset the value to null
or similar, but it doesn't get removed from data storage.
Getting Data
To get the player data from cloud storage you need to use the getData
method. This requires an array of keys which map to the data to be returned. Unlike with game stats, passing no arguments to this method will result in no data coming back. You have to specify one, or more keys.
this.facebook.on('getdata', function (data) {
// Handle what the game should do when the data is returned
});
this.facebook.on('getdatafail', function (error) {
// Handle what the game should do if the data fails to get
});
this.facebook.getData([ 'name', 'pet', 'combatBonus' ]);
As with all SDK calls, it's asynchronous, so you need to wait for the getdata
event before you can act upon it. The request data is set to your event handler in the passed object. It's also automatically entered into the data manager. Which means you can do the following:
this.facebook.on('getdata', function () {
this.characterName = this.facebook.data.get('name');
this.characterPet = this.facebook.data.get('pet');
}, this);
this.facebook.getData([ 'name', 'pet' ]);