Skip to main content

Player Data

PlayerData is a key-value database for storing persistent data about players, such as their score in a game or their preferences in a world.

PlayerData does not rely on an UdonBehaviour's synchronization settings because it is not tied to any one specific UdonBehaviour. Setting a script to "None" instead of "Manual" or "Continuous" will not stop that script from being able to access and modify PlayerData, nor will it negatively affect the operation of PlayerData as a whole.

When an UdonBehaviour sets a value in PlayerData, PlayerData automatically synchronizes that value. Internally, PlayerData sends the value in a similar manner as manual synchronization with the RequestSerialization event. This means that an UdonBehaviour can set multiple PlayerData keys simultaneously and send them together. The UdonBehaviour won't need to send each key separately. Similarly, if an UdonBehaviour sets a key to one value and then immediately changes to something else, remote users don't receive the intermediate value. If data is changed too quickly, only the final state is received by remote users.

PlayerData has a similar bandwidth cost as one UdonBehaviour with synchronization set to "Manual."

All UdonBehaviours in your world share access to your world's PlayerData. When you set a PlayerData key, any UdonBehaviour in your world can access it. PlayerData is not 'separated' between different UdonBehaviours.

When you change any data for the local player, all of their PlayerData is sent, including data that hasn't changed. You are unlikely to run into Udon's bandwidth limits if you have a small amount of data that updates very frequently or a large amount of data that updates slowly. But if you use PlayerData to synchronize large amounts of data and also high-frequency data, you should consider moving one of those to a player object. You can use player objects to sync persistent variables, but each object is synced separately. This allows you to separate your fast data from your big data, reducing your world's networking bandwidth.

Events

EventOutputNotes
OnPlayerDataUpdatedVRCPlayerApi player, PlayerData.Info[] infosTriggered at the end of the frame if the PlayerData of any player has changed or been received.
Provides the VRCPlayerApi of the player associated with that data, along with an array of information on all the keys in that data. The information in the array includes both the keys used for the data and the state of that data, such as whether it was changed, added, or unchanged.
OnPlayerRestoredVRCPlayerApi playerTriggered after a VRChat player's persistent data has been loaded.
Watch out for timing issues

Wait for the OnPlayerRestored event before you read or write Player Data.

When a player joins, the OnPlayerJoined event is called. However, it may take some additional time before their Player Data is received. If you set Player Data too early, it may be overwritten when the persistent data is received.

PlayerData Info

The OnPlayerDataUpdated event provides a PlayerData.Info array. This array contains all the current PlayerData keys associated with that player. Each element contains the following information:

PropertyTypeNotes
KeyStringThe string associated with the PlayerData key, which can be used in queries and mutators.
StateEnumThe most recent state of the PlayerData Key at the point in which this OnPlayerDataUpdated has happened.

The State enum describes these possible states:

StateNotes
UnchangedIndicates that the data in this key has not changed since the last update.
ChangedIndicates that the data in this key has been changed since the last update.
AddedIndicates that this key has been added since the last update.
RemovedIndicates that this key has been removed since the last update. Keys which have been removed will only appear in this array once with this state, and the next time they will be gone.
RestoredIndicates that this key has been restored from persistent records. This only happens when you join the instance after having been there before.

Best Practices

  • When using OnPlayerDataUpdated, consider whether your script can be limited to trigger on changes for the local player, or if it needs to trigger for every remote player, as well.
    • For example - a user setting for video player volume can just update for the local player, but a co-op dog-petting game that tallies a "total dogs pet" score for the instance can react to the increase of any player's score to increment the global score.
  • Wait for the OnPlayerDataRestored event before using Player Data. OnPlayerRestored indicates that the player's saved data has been loaded and is safe to access with Udon.
  • Iterating through all Player Keys can be slow if you have many of them. As a general guideline, use the TryGet methods to directly check the values of specific keys if you're only checking a few keys or you have more than ten keys to check through.

Methods

Queries

Use these methods to retrieve more information about the value associated with a key. They are helpful to gather more information about what exists at a key before attempting to do something with it.

FunctionInputOutputNotes
HasKeyVRCPlayerApi player, string keybool valueReturns true if a value exists in PlayerData at that key
GetTypeVRCPlayerApi player, string keyTypeGets the type of the value contained in PlayerData at that key
TryGetTypeVRCPlayerApi player, string keyout Type t, bool successGets the type of the value contained in PlayerData at that key. Returns false if that key does not exist

Mutators

Use these methods to save PlayerData for the local player. It is not possible to set a remote player's data.

Values can be overwritten, even if they previously had a different type. Keys cannot be deleted after being written.

FunctionInput
SetStringstring key, string value
SetBoolstring key, bool value
SetSBytestring key, sbyte value
SetBytestring key, byte value
SetBytesstring key, byte[] value
SetShortstring key, short value
SetUShortstring key, ushort value
SetIntstring key, int value
SetUIntstring key, uint value
SetLongstring key, long value
SetULongstring key, ulong value
SetFloatstring key, float value
SetDoublestring key, double value
SetQuaternionstring key, Quaternion value
SetVector4string key, Vector4 value
SetVector3string key, Vector3 value
SetVector2string key, Vector2 value
SetColorstring key, Color value
SetColor32string key, Color value

Accessors

Use these methods to get Player Data for any player in the instance.

If a key does not exist, the default value for that type is returned. For example, calling PlayerData.GetInt() would return 0.

Default values are also returned when using the wrong accessor type, such as using GetInt on a key which contains a string.

If default values are undesirable, use TryGet or Queries to distinguish default values from missing keys.

FunctionInputOutput
GetStringVRCPlayerApi player, string keystring value
TryGetStringVRCPlayerApi player, string keystring value, bool success
GetBoolVRCPlayerApi player, string keybool value
TryGetBoolVRCPlayerApi player, string keybool value, bool success
GetSByteVRCPlayerApi player, string keysbyte value
TryGetSByteVRCPlayerApi player, string keysbyte value, bool success
GetByteVRCPlayerApi player, string keybyte value
TryGetByteVRCPlayerApi player, string keybyte value, bool success
GetBytesVRCPlayerApi player, string keybyte[] value
TryGetBytesVRCPlayerApi player, string keybyte[] value, bool value
GetShortVRCPlayerApi player, string keyshort value
TryGetShortVRCPlayerApi player, string keybool value
GetUShortVRCPlayerApi player, string keyushort value
TryGetUShortVRCPlayerApi player, string keyushort value, bool success
GetIntVRCPlayerApi player, string keyint value
TryGetIntVRCPlayerApi player, string keyint value, bool success
GetUIntVRCPlayerApi player, string keyuint value
TryGetUIntVRCPlayerApi player, string keyuint value, bool success
GetLongVRCPlayerApi player, string keylong
TryGetLongVRCPlayerApi player, string keylong value, bool success
GetULongVRCPlayerApi player, string keyulong
TryGetULongVRCPlayerApi player, string keyulong value, bool success
GetFloatVRCPlayerApi player, string keyfloat
TryGetFloatVRCPlayerApi player, string keyfloat value, bool success
GetDoubleVRCPlayerApi player, string keydouble
TryGetFloatVRCPlayerApi player, string keyfloat value, bool success
GetQuaternionVRCPlayerApi player, string keyQuaternion
TryGetQuaternionVRCPlayerApi player, string keyQuaternion value, bool success
GetVector4VRCPlayerApi player, string keyVector4
TryGetVector4VRCPlayerApi player, string keyVector4 value, bool success
GetVector3VRCPlayerApi player, string keyVector3
TryGetVector3VRCPlayerApi player, string keyVector3 value, bool success
GetVector2VRCPlayerApi player, string keyVector2
TryGetVector2VRCPlayerApi player, string keyVector2 value, bool success
GetColorVRCPlayerApi player, string keyColor
TryGetColorVRCPlayerApi player, string keyColor value, bool success
GetColor32VRCPlayerApi player, string keyColor32
TryGetColor32VRCPlayerApi player, string keyColor32 value, bool success

Examples

Persistent Jumps Counter

The persistent jump counter example script in the Udon Graph.