Documentation

Cloud Code

Player and match persistence in CloudBehaviours

Understand what CloudBehaviours persists between invocations, and how to control it.
Read time 2 minutesLast updated 15 days ago

Important
This page describes an experimental feature that might change significantly before release. It's not recommended to use or rely on experimental features in production environments due to potential instability.
Whether a member reaches a client, and whether it survives between invocations, are two independent mechanisms. A member can synchronize without persisting, persist without synchronizing, or both.

What persists by default

A public member persists in the cloud between invocations by default. Two attributes override that default, and both apply to fields and properties:

Attribute

Effect

[CloudCodeSerializeProperty]
Persists a non-public member, so it survives invocations without reaching a client
[CloudCodeIgnoreProperty]
Keeps a public member out of persistence, while it still synchronizes
Persistence applies member by member inside a persisted object too. A private field in a persisted custom type needs its own
[CloudCodeSerializeProperty]
.
The following example applies both attributes:
[CloudCodeSerializeProperty]private string _correctAnswer; // Survives invocations, never sent to a client[CloudCodeIgnoreProperty]public int FramesSinceStart; // Synced for display, not worth persisting

Player scope compared with session scope

Scope.Player
gives you one CloudBehaviour instance per player, bound to their Unity Gaming Services identity. Use it for progression, inventory, and other state that outlives a single session.
Scope.MultiplayerSession
gives you one instance shared by everyone in a session. Use it for match state, such as turn order and shared scores, that only needs to last for the session.
Scopes and their lifetimes come from the underlying Stateful Cloud Code module. For the full serialization mechanics, refer to State serialization in Cloud Code.

Common mistakes

Only a serialized member is saved. A plain private field, without
[CloudCodeSerializeProperty]
, can keep its value for a while, but it resets whenever Cloud Code reloads your CloudBehaviour from saved state, which can happen between any two calls. If a value unexpectedly resets, confirm it's a public member, or explicitly marked for persistence.
A get-only or computed property that Cloud Code persists, such as
public int Total => A + B;
, causes a compile-time error, because Cloud Code can't restore a value into a property without a setter. Exclude it with
[CloudCodeIgnoreProperty]
, or give it a setter. A private setter is enough.

Additional resources