Synchronized state in CloudBehaviours
Declare synchronized state, read it in your game, and control when Cloud Code pushes updates.
Read time 4 minutesLast updated 15 days ago
A public field or property on a CloudBehaviour is synchronized state. Its value lives in the cloud, and the client bindings keep a copy of it up to date. In a scope, every member of the session receives updates. Private members never reach a client, so secrets such as a card deck or a dice seed stay in the cloud.
MultiplayerSessionDeclare synchronized state
A public, non-static field synchronizes, and so does a public, non-static property with a public setter:
[StateScope(Scope.MultiplayerSession)]public class MatchState : CloudBehaviour{ public int Round; // Synchronizes public List<int> Scores; // Synchronizes public int TurnNumber { get; set; } // Synchronizes public int Seed { get; private set; } // Doesn't synchronize: no public setter private List<string> _deck; // Stays in the cloud}
A read-only member, such as a field or a property without a public setter, doesn't synchronize, and the build reports a warning for it. Synchronization and persistence follow different rules. For more information about persistence, refer to Player and match persistence in CloudBehaviours.
readonlyValues serialize as JSON. Classes and enums that you define in the cloud assembly are automatically available to the client bindings, carrying only their public fields and properties.
Read synchronized state in your game
The generated client bindings expose each synchronized field as a read-only property. Subscribe to the event to react to updates:
Synchronizedprotected virtual void OnEnable(){ EnableClient(); Synchronized.AddListener(() => turnLabel.text = $"Round {matchStateClient.Round}");}
SynchronizedControl synchronization manually
AutoSynchronizeAutoSynchronizeSynchronizeAsync()public async Task ResolveRound(){ AutoSynchronize = false; Round++; Scores[0] += 10; await SynchronizeAsync();}
AutoSynchronizefalsetrueThe calling client always receives current state in the RPC return, regardless of .
AutoSynchronizeModel types crossing the client boundary
When a synchronized field, an RPC, or an event uses a class, struct, or enum that you define in your cloud assembly, Cloud Code generates a type with the same name in the client bindings, so your game can work with the same data. The generated type is a data-only copy: it keeps the public fields and properties, and drops everything else.
For example, an inventory CloudBehaviour stores a list of items:
public class Item{ public string Name; public int Quantity = 1; private string _dropTable; // Server-only data public bool IsStackable() => Quantity > 1; // Server-only logic}[StateScope(Scope.Player)]public class Inventory : CloudBehaviour{ public List<Item> Items = new(); public void Add(Item item) => Items.Add(item);}
In your game, on the client bindings is a list of this generated type:
ItemsItempublic class Item{ public string Name { get; set; } public int Quantity { get; set; }}
In practice, this means:
- Your game reads and
Namedirectly, for example to display the inventory.Quantity - doesn't exist in your game. To use the same rule on both sides, put it in a shared rules library, or work out the answer on the server and synchronize it.
IsStackable() - never reaches your game.
_dropTable - Default values such as aren't copied. An
= 1that your game creates, for example to pass toItem, starts withAddatQuantityunless you set it.0
A public property that can be read but not publicly assigned, such as a computed property or one with a private setter, causes a compile-time error, and so does a public field. For where to put real game logic instead, refer to Game organization in CloudBehaviours.
readonlyUse , an array, or for a collection field. Don't use a custom collection type: Cloud Code can't serialize it to JSON and deserialize it back. As an RPC parameter or return value, or when it derives from a .NET collection type, it causes a compile-time error.
List<T>Dictionary<TKey, TValue>To share a single value differently per player, refer to Per-player state views in CloudBehaviours.