Studio GuideWorld SDK Guide
Log In

Multiplay World DataStorage


The ZEPETO World Data Storage component is the ability to store data by client (player connected to the server).

It is commonly used to store data such as inventory items, skill points, and levels.

Data is stored on a ZEPETO account basis and must be added to the server logic (World.multiplay package → index.ts).

User data stored through DataStorage can be viewed and changed through World Data Management.


Please refer to the following guide. [World Data Management]

Defining Function

declare module 'ZEPETO.Multiplay.DataStorage' {   
    interface DataStorage {
        set<T>(key: string, value: T): Promise<boolean>;
        mset<T>(keyValueSet: { key: string; value: T; }[]): Promise<boolean>;
        get<T>(key: string): Promise<T>;
        mget<T>(keys: string[]): Promise<{ [key: string]: T }>;
        remove(key: string): Promise<boolean>;
    function loadDataStorage(userId: string): Promise<DataStorage>;

To use the ZEPETO.Multiplay.DataStorage module, you must complete the import statement as follows:

import { DataStorage } from 'ZEPETO.Multiplay.DataStorage';

DataStorage.set(key, value)

A set function is a function that stores data.
It is stored with key and value as parameters, and the key value can be freely defined and used.



  • On the local server in the Unity Editor environment, data is not preserved when the server is shut down and run again.
  • After World deployment, data is stored in ZEPETO DB and maintained.
  • If the rules below are not satisfied, data will not be saved normally.
    • If there is no value
    • When entering a value that cannot be stored in Value
  • Data Storage Constraints
    • Key length limit: 50 characters
      • Only alphabets, numbers, and underscore (_) are allowed in the key
    • Maximum number of keys: 1000 per User ID
    • Maximum Value data size: 500,000 characters
      • Please note that when value data is stored on the actual server, it is serialized along with an internal identifier. Consider this and use it with a margin for safety.
  • Data Storage API Call Restrictions
    • Get (per minute): 200 times
    • Set (per minute): 200 times
await playerStorage.set("level", 1);


The get function is a function that looks up data.
Enter key as a parameter to query the value. Returns null if a key that does not exist is queried.

let playerLevel = await playerStorage.get("level") as number;

▼ Example code using Save & Load to record user levels

import { DataStorage } from 'ZEPETO.Multiplay.DataStorage';
async onJoin(client: SandboxPlayer) {
    // Load current player's data storage
    const playerStorage: DataStorage = client.loadDataStorage();
    let playerLevel = await playerStorage.get("level") as number;
    if (playerLevel == null) {
        playerLevel = 1;
    await playerStorage.set("level", playerLevel);

DataStorage Multi-Get/Multi-Set

You can import or store multiple values at a time.



  • Features available in ZEPETO World Package 1.12.2 and later.


The mget function allows Data Storage to fetch multiple values at a time.



  • In mget(keys), keys must be an array.
  • Entering an empty value results in an error.
  • Be sure to add an exception handling code for whether the key value is valid by referring to the example code.

DataStorage.mset({key, value})

The mset function allows DataStorage to store multiple values at a time.
Enter and save a keyValueSet array in the format {key,value} as a parameter.



  • If you specify a generic type, only the same type of data can be stored.
  • If you do not specify it as generic, you can store each other's type of data.
  • If you enter an empty array value, false is returned.

▼ DataStorage Multi-Get/Multi-Set Use Example Code

  • Please use the error handling syntax.
this.onMessage<SaveValue>('save', async (client: SandboxPlayer, message: SaveValue) => {
        const storage = client.loadDataStorage();
        try {
            // mset (multi key-value) store
            const success = await storage.mset<number>([
                    key: 'key1',
                    value: 1
                    key: 'key2',
                    value: 2
            // If successful
            if (success) {
                // Get the values of key1 and key2 at once
                const keys = ['key1', 'key2'];
                const keyValeus = await storage.mget(keys);
                keys.forEach(key => {
                    const value = keyValeus[key];
                    if (key === 'key1' && value !== null && value !== undefined) {
                    } else if (key === 'key2' && value !== null && value !== undefined) {
        } catch(error) {
            let systemError = (error as SystemError);
            if (systemError.code === DataStorageError.Unknown || systemError.code === DataStorageError.NetworkError) { 
                // System error or network error
            } else if (systemError.code === DataStorageError.KeyConstraintViolated) { 
                // Key constraint violated
            } else if (systemError.code === DataStorageError.ValueConstraintViolated) { 
                // Value constraint violated

Manage DataStorage based on UserId

Read/Write/Delete Data Storage based on UserId.



  • Features available in ZEPETO World Package 1.9.0 and later.
  • Please fill out the server code index.ts Sandbox.


Previously, only the accessor's own Data Storage was accessible, and there was no way to get information such as other people's scores or abilities.

First, to get user information, we define Schema Types and Room State as follows:


▼ Example code for using UserId-based DataStorage

import { Sandbox, SandboxOptions, SandboxPlayer } from 'ZEPETO.Multiplay';
import { DataStorage, loadDataStorage } from 'ZEPETO.Multiplay.DataStorage';
import { UserInfo } from 'ZEPETO.Multiplay.Schema';
interface TargetData {
    lastJoinRoom: string;
    lastJoinTime: string;
export default class extends Sandbox {
    onCreate(options: SandboxOptions) {
        this.onMessage("TargetData", (client: SandboxPlayer, targetData: TargetData) => {
            this.saveTargetData(client, targetData);
        this.onMessage("GetTargetData", (client: SandboxPlayer, userId: string) => {
            this.loadTargetData(client, userId);
    onJoin(client: SandboxPlayer) {
        const user = new UserInfo();
        user.sessionId = client.sessionId;
        user.userId = client.userId;
        this.state.UserInfos.set(client.userId, user);
    onLeave(client: SandboxPlayer, consented?: boolean) {
    async saveTargetData(client: SandboxPlayer, targetData: TargetData) {
        console.log(`save target data (${client.userId})\n ${JSON.stringify(targetData)}`);
        const playerStorage: DataStorage = client.loadDataStorage();
        const result = await playerStorage.set("targetData", targetData);
        client.send("Log", `Save Result : ${result}`);
    async loadTargetData(client: SandboxPlayer, userId: string) {
        console.log(`load target data (${userId})`);
        const userStorage: DataStorage = await loadDataStorage(userId);
        const targetData = await userStorage.get<TargetData>("targetData");
        if (targetData) {
            client.send("TargetData", targetData);
        } else {
            const empty: TargetData = {
                lastJoinRoom: "",
                lastJoinTime: "",
            client.send("TargetData", empty);

In the example above, the key points are as follows:

this.state.UserInfos.set(client.userId, user);Stores data in DataStorage for a specific userID.
const userStorage: DataStorage = await loadDataStorage(userId);

const targetData = await userStorage.get("targetData");
Reads data from a specific user in asynchronous form.

It then imports data for a specific key value.
this.state.UserInfos.delete(client.userId);Deletes data to DataStorage for a specific userID.



  • If you use UserInfos.delete(), the target UserID's data will be deleted and it cannot be recovered, so please use it carefully.
  • The World developer is responsible for deleting data using the UserInfos.delete() script.

PlayerPrefs - Saving data to the device


Provides the ability to save players to the device they are connecting to.
It can be called from the client ZEPETO Script, and data will not be preserved if you delete the app or change the device.

It supports use in the same way as PlayerPrefs in Unity, and the storage capacity is limited to 10KB.

▼ Example code for checking the number of plays using the Save & Load function

import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { PlayerPrefs } from 'UnityEngine';
export default class ClientSaveLoad extends ZepetoScriptBehaviour {
    playCntKey: string = 'PlayCnt';
    Start() {
        if (PlayerPrefs.HasKey(this.playCntKey)) {
            PlayerPrefs.SetInt(this.playCntKey, PlayerPrefs.GetInt(this.playCntKey) + 1);
            console.log(`PlayCnt : ${ PlayerPrefs.GetInt(this.playCntKey) }`);
        } else {
            PlayerPrefs.SetInt(this.playCntKey, 1);
            console.log('PlayCnt : 1');


View Unity PlayerPrefs information