Skip to content

Latest commit

 

History

History
194 lines (100 loc) · 7.05 KB

File metadata and controls

194 lines (100 loc) · 7.05 KB
source

Note: Some scripts may present an error at compile due to a casting mismatch. To resolve, cast the return value for getPlayerVariable as a number and recompile your script.

Meta Horizon Worlds object type persistent variables enable you to save structured variable information between user sessions. The advantage of object type persistent variables is that they support JSON (JavaScript Object Notation), allowing you to save more complicated structured data as a single JSON object, instead of having to save multiple number-type persistent variables.

In the past, number-type persistent variables were only capable of using simple numbers. However, object type persistent variables allow you to store more complex and detailed variable types, such as strings, booleans, and lists. Having this additional functionality will enhance your world building experience.

  • Each object type variable has a size limit of 10 KB. If you reach this size limit, create multiple variables instead.

You can find persistent variables by looking under Variable Groups in the Systems menu of the CUI tool. When you create a new variable within a variable group, you’ll see an option to choose the Number, or the Object type.

  1. Access Persistent Variables in a Variables Group .
  2. To configure a variable, specify either Object or Number:

To interact with the variable(s) created in the previous step, you’ll need TypeScript logic that calls the Persistent Variable APIs. You can find these APIs in the world component in the horizon/core module. To add this definition to your TypeScript code, add the following import to the top of your component:

import * as hz from 'horizon/core';

When your script is configured, you’ll now see a persistentStorage object in your this.world definition. This object includes the getPlayerVariable function returning a type extending PersistentSerializableState, which is a composition of several base supported types such as number, boolean, string, and arrays of these base types.

If a player variable hasn’t yet been set (initialized), the getPlayerVariable method returns either 0 for number type variables, or null for object type variables. This allows you to handle cases where the variable might not have been set yet. You should include typeof checks to confirm the value received and assert the correct type.

const num_var_name = 'my_var_group:user_level'; // Set as a number type.

this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnPlayerEnterWorld, (playerhz.Player) => {

  let playerLevel = this.world.persistentStorage.getPlayerVariable<number>(

      player,

      num_var_name,

    );



    console.log('User level: ' + playerLevel);

  });
const obj_var_name = 'my_var_group:user_info'; // Set as an object type.

type Perk = {

  idnumber;

  namestring;

}



type Stats = {

  victoriesnumber;

  has_completed_introboolean;

}





type User = {

  unlocked_perksPerk[];

  statsStats;

}



this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnPlayerEnterWorld, (playerhz.Player) => {

  let userInfoUser \| null = this.world.persistentStorage.getPlayerVariable<User>(

    player,

    obj_var_name

  );



  if (userInfo == null) {

    // Uninitialized state

    console.log('Player does not yet have data initialized for ' + obj_var_name);

  } else {

    console.log('Player victories count ' + userInfo.stats.victories);

  }

});

You can save persistent variables for the player using the setPlayerVariable function in the persistentStorage object. All data previously saved under the specified variable group and variable name is overwritten with the data passed into the method.

// On a level update event, save the new user level.

this.connectEntityEvent(this.entity, LevelUpEvt, (data{playerPlayer}) => {

  playerLevel += 1;

  this.world.persistentStorage.setPlayerVariable(

    data.player,

    num_var_name,

    playerLevel,

  );

});
// On a perk unlock event,

// save the new perk to the UserInfo store.

this.connectEntityEvent(this.entity, PerkUnlockEvt, (data{playerPlayer; perkPerk}) => {

    userInfo.unlocked_perks.push(perk);

    this.world.persistentStorage.setPlayerVariable(

      data.player,

      obj_var_name,

      userInfo,

    );

  });

Variable names are often used to retrieve and update values in the persistent variables store. If you change a persistent variable name, or the name of the variable group that it’s in, then you must modify all call sites to reference the updated name. Instead of hard-coding these values at call sites, Meta recommends that you save variable names in a module that you can easily import with your world’s scripts. See the following code for an example.

// Module: StructuredData

export const OBJECT_VAR = 'my_var_group:object_var';

export const NUMBER_VAR = 'my_var_group:number_var';