Persisted Player Data
Persisted Player Data was created for your game to save progress and data related to each unique player of your game that can be retrieved in the future even after they leave and rejoin your game. This is useful for things like player progression systems, lifetime stats tracking, player quest completion and unlocks, and so much more.
The Persisted Player Data system builds on top of the Persisted Data concepts and exposes a number of convenience methods for retrieving and updating player data.
Player Data Types
Any JSON compatible data can be stored for a player. Typically, the best practice is to use a single object with many arbitrary properties that reflect the data you want to track for a player for your game.
You can learn more about supported data type here: Supported Data Types
Retrieving Player Data
You can retrieve player data by using the player.getPersistedData()
method. Any instance of a player object has this available.
Here's an example of a common usage pattern of retrieving a player's data when they join a game.
startServer(world => {
world.on(PlayerEvent.JOINED_WORLD, async ({ player }) => {
// ... other common init code, like spawning an entity, etc
// get player data, {} is returned if no data is found.
// undefined is returned if data retrieval fails.
const playerData = await player.getPersistedData();
// do something with the playerData
});
// ... other code
});
Setting & Updating Player Data
Similar to retrieving player data, you can set or update player data, which utilizes Shallow Merging, using the player.setPersistedData()
method. Any instance of a player object has this available.
Here's an example of using this.
// other code..
await player.setPersistedData({ "someData": 123 });
Handling Errors & Edge Cases
Because data persistence relies on a HYTOPIA provided service, there are rare but possible situations where persisted data retrieval for a player may fail when they join your game. You can be certain your player's data has loaded, even if they are a new user, by checking ig (await player.getPersistedData()) !== undefined
.
It's recommended that your game logic properly handles this edge case. In these situations, you will manually want to call player.loadInitialPersistedData()
to attempt to retrieve the player's persisted data again if prior retrieval failed. If prior initial loading of persisted data succeeded, the player.loadInitialPersistedData()
method does nothing.
// Example of handling edge cases
// Attempt to get the persisted data.
let playerData = player.getPersistedData();
if (playerData === undefined) { // data failed to retrieve, let's retry..
let retries = 0;
while (retries < 3) { // retry getting the data...
await player.loadInitialPersistedData();
await new Promise(resolve => setTimeout(resolve, 1000));
playerData = await player.getPersistedData();
if (playerData !== undefined) {
break;
}
retries++;
}
}
if (playerData && Object.keys(playerData).length > 0) {
// Player has saved data
} else if (playerData !== undefined) {
// No saved data, retrieval succeeded, but we got a empty
// object back {} which is expected when a player has no saved
// data.
} else {
// If we hit this block, playerData is undefined which means
// the HYTOPIA persistence service may be experiencing an outage,
// our game logic should handle this accordingly based on our game's needs.
}
Last updated