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]


DataStorage API


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

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

If you're interested in the ZEPETO.Multiplay.DataStorage API, refer to the documentation:

📘

Please refer to the following guide. [ZEPETO.Multiplay.DataStorage API]

❗️

Caution

  • Please fill out the server code index.ts Sandbox.
  • 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

▼ Example code using Save & Load to record user levels

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

export default class extends Sandbox {
  
  //...
 
  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.


DataStorage.mget(keys)

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

❗️

Caution

  • 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.

❗️

Caution

  • 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.
import { DataStorage } from 'ZEPETO.Multiplay.DataStorage';

export default class extends Sandbox {
  
  //...
 
  async onJoin(client: SandboxPlayer) {
      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) {
              console.log(value);
            } else if (key === 'key2' && value !== null && value !== undefined) {
              console.log(value);
            }
          });
        }
      } catch(error) {
        let systemError = (error as SystemError);

        if (systemError.code === DataStorageError.Unknown || systemError.code === DataStorageError.NetworkError) { 
          // System error or network error
          console.log(systemError.message);
        } else if (systemError.code === DataStorageError.KeyConstraintViolated) { 
          // Key constraint violated
          console.log(systemError.message);                   
        } else if (systemError.code === DataStorageError.ValueConstraintViolated) { 
          // Value constraint violated
          console.log(systemError.message);                   
        }
     }
  }
}

Manage DataStorage based on UserId

Read/Write/Delete Data Storage based on UserId.

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

469

▼ 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) {
        this.state.UserInfos.delete(client.userId);
    }
 
    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");
        console.log(JSON.stringify(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.
const userStorage: DataStorage = await loadDataStorage(userId);
userStorage.remove("targetData");
Deletes data to DataStorage for a specific userID.

❗️

Caution

  • 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

ClientStorage

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 {
 
    private playCntKey: string = 'KeyName';
 
    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

https://docs.unity3d.com/ScriptReference/PlayerPrefs.html