VRChat Persistence, PlayerData, And PlayerObjects

Persistence lets a VRChat world remember player-specific data across visits. That can make worlds feel more complete: saved settings, game progress, high scores, unlocks, inventories, and preferences can still exist when a player returns later.

Use persistence only when the saved value matters after the session ends. For temporary actions inside one instance, normal local logic, network events, or synced variables are usually better.

Recommended Setup

Design saved data before you script it, then test loading and overwriting carefully.

  1. List the exact values that should survive after the player leaves.
  2. Choose PlayerData for simple values or PlayerObjects for per-player objects.
  3. Test first visit, return visit, and reset behavior before public release.
VRChat note

Persistence data is connected to the player's VRChat account and the world. It should be treated as a small, intentional save system, not a dumping ground for every variable in the scene.

What Persistence Is Good For

Good persistence candidates include:

  • saved volume or comfort settings
  • high scores
  • unlocked doors, levels, or cosmetic choices
  • inventory progress
  • player class or loadout choice
  • return-spawn preference
  • completed tutorial state

Avoid saving data that is only useful during the current instance, such as a temporary particle effect, short animation trigger, or one-off button press.

PlayerData Vs PlayerObjects

Need Better fit Why
Save a player preference PlayerData A simple key-value value is enough.
Save a high score PlayerData The data belongs to the player and can be read by Udon.
Save a small set of unlock flags PlayerData Keys are easier than building objects for simple flags.
Give each player a persistent item object PlayerObject Each player needs their own spawned object.
Give each player an owned object with saved fields PlayerObject VRChat spawns one PlayerObject per player, and synced fields can persist when configured for persistence.

PlayerData is the easier starting point for most simple save systems. PlayerObjects become useful when the player needs an actual GameObject with synced variables or child objects.

Design The Keys First

Before scripting PlayerData, write the data plan:

Key Type Purpose Default
tutorial_done bool Hide onboarding after completion false
music_volume float Restore local audio preference 0.7
best_time float Store best run result 0
unlocked_room_02 bool Keep progression false

This makes it easier to avoid vague names, duplicated keys, and accidental type changes.

Loading And Overwriting Saved Data

Do not assume saved data is ready during the first frame.

Implementation checklist:

  1. Initialize safe defaults.
  2. Wait for VRChat's restored-data event before trusting saved values.
  3. Read the keys you need.
  4. Apply the values to UI, doors, score displays, or systems.
  5. Save only when the player actually changes something.

This prevents a common mistake: reading a default value too early and then overwriting real saved data.

Storage And Bandwidth Discipline

Official VRChat documentation describes persistence as limited storage per player per world. Treat it like a compact save slot.

Good habits:

  • keep keys short and meaningful
  • avoid saving rapidly changing values every frame
  • save after meaningful changes, not constant polling
  • separate high-frequency synced state from larger saved data
  • test storage warnings before expanding a save system

If you need lots of fast-changing multiplayer state, revisit the Udon Networking Decision Guide before turning everything into persistent data.

Common Problems

Help! My saved value resets every time.

Check whether the key name and type match, whether you are reading data before it has restored, and whether another script overwrites the value with a default.

Help! I need to save a remote player's data.

Design around the local player's own data. If the world needs shared state, use networking or a game-state owner instead of trying to write another player's saved data directly.

Help! My persistent system works alone but fails in multiplayer.

Separate saved data from current instance state. Persistence remembers values across visits; synced variables and ownership decide what everyone sees right now.

Official References

One earlier wording implied PlayerObjects were automatically a networking optimization compared with PlayerData. That has been narrowed to the behavior VRChat documents: PlayerObjects are per-player objects, can contain Udon behavior, and can persist synced data when configured correctly.

Related Reading

Final Advice

Start with one saved preference or one high score before building a large save system. Persistence is most reliable when it is small, named clearly, restored carefully, and tested through return visits.

Saved World State

Save Data Only When The Player Actually Needs It Later

Persistence is powerful, but it should be designed intentionally. Save preferences, progress, and player-specific state, not every temporary moment in the instance.

Suggested Order

  1. Name the data Write down the exact keys or synced fields you want to save before touching Udon.
  2. Choose PlayerData or PlayerObject Use PlayerData for simple per-player values and PlayerObjects when each player needs their own object with synced behavior.
  3. Wait for restored data Do not read or overwrite saved values before VRChat reports that player data has been restored.

Common Questions

Should I use PlayerData or PlayerObjects?

Use PlayerData for simple key-value player data. Use PlayerObjects when each player needs an instantiated object with synced or persisted behavior.

Can persistence replace normal networking?

No. Persistence saves data across visits. Networking still handles what players see and share inside the current instance.