Client-side Schema Callbacks
When applying state changes coming from the server, the client-side is going to trigger callbacks on local instances according to the changes being applied.
In order to register callbacks to Schema instances, you must access the instances through a “callbacks handler”.
Overview
Get the callback handler
import { Client, getStateCallbacks } from "colyseus.js";
// initialize SDK
const client = new Client("ws://localhost:2567");
// join room
const room = await client.joinOrCreate("my_room");
// get state callbacks handler
const $ = getStateCallbacks(room);
Register the callbacks
$(room.state).listen("currentTurn", (currentValue, previousValue) => {
// ...
});
// when an entity was added (ArraySchema or MapSchema)
$(room.state).entities.onAdd((entity, sessionId) => {
// ...
console.log("entity added", entity);
$(entity).listen("hp", (currentHp, previousHp) => {
console.log("entity", sessionId, "changed hp to", currentHp);
})
});
// when an entity was removed (ArraySchema or MapSchema)
$(room.state).entities.onRemove((entity, sessionId) => {
// ...
console.log("entity removed", entity);
});
C#, C++, Haxe - When using statically typed languages, you need to generate the client-side schema files based on your TypeScript schema definitions. See generating schema on the client-side.
How to use
On Schema
instances
Listen
Listens for a single property change within a Schema
instance.
$(room.state).listen("currentTurn", (currentValue, previousValue) => {
console.log(`currentTurn is now ${currentValue}`);
console.log(`previous value was: ${previousValue}`);
});
Removing the callback: The .listen()
method returns a function that, when called, removes the attached callback:
const unbindCallback = $(room.state).listen("currentTurn", (currentValue, previousValue) => {
// ...
});
// stop listening for `"currentTurn"` changes.
unbindCallback();
Bind To
Bind properties directly to targetObject
, whenever the client receives an update from the server.
Parameters:
targetObject
: the object that will receive updatesproperties
: (optional) list of properties that will be assigned totargetObject
. By default, every@type()
’d property will be used.
$(room.state).players.onAdd((player, sessionId) => {
const playerVisual = PIXI.Sprite.from('player');
$(player).bindTo(playerVisual);
});
On Change
The On Change callback is invoked whenever a direct property of a Schema
instance is modified.
- Triggers only for direct property changes: It does not cascade or propagate changes from nested properties within the Schema.
- The callback fires after the changes have been applied to the Schema instance. This means you’re dealing with the updated instance when the callback executes.
$(room.state).entities.onAdd((entity, sessionId) => {
// ...
$(entity).onChange(() => {
// some property changed inside `entity`
})
});
On Maps or Arrays
On Add
Register the onAdd
callback is called whenever a new instance is added to a collection.
By default, the callback is called immediately for existing items in the collection.
$(room.state).players.onAdd((player, sessionId) => {
console.log(player, "has been added at", sessionId);
// add your player entity to the game world!
// detecting changes on object properties
$(player).listen("field_name", (value, previousValue) => {
console.log(value);
console.log(previousValue);
});
});
On Remove
The onRemove
callback is called with the removed item and its key on holder object as argument.
$(room.state).players.onRemove((player, sessionId) => {
console.log(player, "has been removed at", sessionId);
// remove your player entity from the game world!
});
Client-side Schema Generation
Not required when using JavaScript SDK or Defold SDK - The following section is only required when using statically typed languages in your front-end, such as C#, Haxe, etc.
The schema-codegen
is a command-line tool designed to convert your server-side schema definitions into compatible client-side schemas.
To decode the state on the client side, its local schema definitions must be compatible with those on the server.
Usage:
To see the usage, From your terminal, cd
into your server’s directory and run the following command:
npx schema-codegen --help
Output:
schema-codegen [path/to/Schema.ts]
Usage (C#/Unity)
schema-codegen src/Schema.ts --output client-side/ --csharp --namespace MyGame.Schema
Valid options:
--output: fhe output directory for generated client-side schema files
--csharp: generate for C#/Unity
--cpp: generate for C++
--haxe: generate for Haxe
--ts: generate for TypeScript
--js: generate for JavaScript
--java: generate for Java
Optional:
--namespace: generate namespace on output code
Example: Unity / C#
Below is a real example to generate the C# schema files from the demo Unity project.
npx schema-codegen src/rooms/schema/* --csharp --output ../Assets/Scripts/States/"
generated: Player.cs
generated: State.cs
Using npm
scripts:
For short, it is recommended to have your schema-codegen
arguments configured under a npm
script in your package.json
:
"scripts": {
"schema-codegen": "schema-codegen src/rooms/schema/* --csharp --output ../Assets/Scripts/States/"
}
This way you can run npm run schema-codegen
rather than the full command:
npm run schema-codegen
generated: Player.cs
generated: State.cs