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.
Design saved data before you script it, then test loading and overwriting carefully.
- List the exact values that should survive after the player leaves.
- Choose PlayerData for simple values or PlayerObjects for per-player objects.
- Test first visit, return visit, and reset behavior before public release.
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:
- Initialize safe defaults.
- Wait for VRChat's restored-data event before trusting saved values.
- Read the keys you need.
- Apply the values to UI, doors, score displays, or systems.
- 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
- VRChat Persistence
- VRChat PlayerData
- VRChat PlayerObject
- VRChat Udon Networking Performance Considerations
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.
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
- Name the data Write down the exact keys or synced fields you want to save before touching Udon.
- Choose PlayerData or PlayerObject Use PlayerData for simple per-player values and PlayerObjects when each player needs their own object with synced behavior.
- Wait for restored data Do not read or overwrite saved values before VRChat reports that player data has been restored.
Related VRCreators Guides
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.