
Security News
OWASP 2025 Top 10 Adds Software Supply Chain Failures, Ranked Top Community Concern
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.
@colyseus/schema
Advanced tools
A binary schema-based serialization algorithm.
Although it was born to be used on Colyseus, this library can be used as standalone.
As Colyseus is written in TypeScript, the schema is defined as type annotations inside the state class. Additional server logic may be added to that class, but client-side generated (not implemented) files will consider only the schema itself.
import { Schema, type, ArraySchema, MapSchema } from '@colyseus/schema';
export class Player extends Schema {
@type("string")
name: string;
@type("number")
x: number;
@type("number")
y: number;
}
export class State extends Schema {
@type('string')
fieldString: string;
@type('number') // varint
fieldNumber: number;
@type(Player)
player: Player;
@type([ Player ])
arrayOfPlayers: ArraySchema<Player>;
@type({ map: Player })
mapOfPlayers: MapSchema<Player>;
}
See example.
| Type | Description | Limitation |
|---|---|---|
| string | utf8 strings | maximum byte size of 4294967295 |
| number | auto-detects int or float type. (extra byte on output) | 0 to 18446744073709551615 |
| boolean | true or false | 0 or 1 |
| int8 | signed 8-bit integer | -128 to 127 |
| uint8 | unsigned 8-bit integer | 0 to 255 |
| int16 | signed 16-bit integer | -32768 to 32767 |
| uint16 | unsigned 16-bit integer | 0 to 65535 |
| int32 | signed 32-bit integer | -2147483648 to 2147483647 |
| uint32 | unsigned 32-bit integer | 0 to 4294967295 |
| int64 | signed 64-bit integer | -9223372036854775808 to 9223372036854775807 |
| uint64 | unsigned 64-bit integer | 0 to 18446744073709551615 |
| float32 | single-precision floating-point number | -3.40282347e+38 to 3.40282347e+38 |
| float64 | double-precision floating-point number | -1.7976931348623157e+308 to 1.7976931348623157e+308 |
string, number, boolean, etc)@type("string")
name: string;
@type("int32")
name: number;
Schema type@type(Player)
player: Player;
Schema type@type([ Player ])
arrayOfPlayers: ArraySchema<Player>;
You can't mix types inside arrays.
@type([ "number" ])
arrayOfNumbers: ArraySchema<number>;
@type([ "string" ])
arrayOfStrings: ArraySchema<string>;
Schema type@type({ map: Player })
mapOfPlayers: MapSchema<Player>;
You can't mix types inside maps.
@type({ map: "number" })
mapOfNumbers: MapSchema<number>;
@type({ map: "string" })
mapOfStrings: MapSchema<string>;
The Schema definitions can encode itself through Reflection. You can have the
definition implementation in the server-side, and just send the encoded
reflection to the client-side, for example:
import { Schema, type, Reflection } from "@colyseus/schema";
class MyState extends Schema {
@type("string")
currentTurn: string;
// more definitions relating to more Schema types.
}
// send `encodedStateSchema` across the network
const encodedStateSchema = Reflection.encode(new MyState());
// instantiate `MyState` in the client-side, without having its definition:
const myState = Reflection.decode(encodedStateSchema);
When using with Colyseus 0.10, you may provide a @filter per field, to filter out what you don't want to serialize for a specific client.
On the example below, we are filtering entities which are close to the player entity.
import { Schema, type, filter } from "@colyseus/schema";
export class State extends Schema {
@filter(function(this: State, client: any, value: Entity) {
const currentPlayer = this.entities[client.sessionId]
var a = value.x - currentPlayer.x;
var b = value.y - currentPlayer.y;
return (Math.sqrt(a * a + b * b)) <= 10;
})
@type({ map: Entity })
entities = new MapSchema<Entity>();
}
@colyseus/schema encodes only field values in the specified order.
2 extra bytes for each index change. Example: If you have an array of 20 items, and remove the first item (through shift()) this means 38 extra bytes to be serialized.2 extra bytes per key move.TODO: describe how changes will arrive on array and map types
import { DataChange } from "@colyseus/schema";
import { State } from "./YourStateDefinition";
const decodedState = new State();
decodedState.onChange = function(changes: DataChange[]) {
assert.equal(changes.length, 1);
assert.equal(changes[0].field, "fieldNumber");
assert.equal(changes[0].value, 50);
assert.equal(changes[0].previousValue, undefined);
}
decodedState.decode(incomingData);
THIS HAS NOT BEEN IMPLEMENTED
Decoders for each target language are located at /decoders/. Usage should be as simple as dropping the decoder along with the schema files in your project, since they have no external dependencies.
# TypeScript
statefy ./schemas/State.ts --output ./ts-project/State.ts
# LUA/Defold
statefy ./schemas/State.ts --output ./lua-project/State.lua
# C/C++
statefy ./schemas/State.ts --output ./cpp-project/State.c
# C#/Unity
statefy ./schemas/State.ts --output ./unity-project/State.cs
# Haxe
statefy ./schemas/State.ts --output ./haxe-project/State.hx
| Scenario | @colyseus/schema | msgpack + fossil-delta |
|---|---|---|
| Initial state size (100 entities) | 2671 | 3283 |
| Updating x/y of 1 entity after initial state | 9 | 26 |
| Updating x/y of 50 entities after initial state | 342 | 684 |
| Updating x/y of 100 entities after initial state | 668 | 1529 |
Initial thoghts/assumptions, for Colyseus:
Practical Colyseus issues this should solve:
MIT
FAQs
Binary state serializer with delta encoding for games
The npm package @colyseus/schema receives a total of 12,130 weekly downloads. As such, @colyseus/schema popularity was classified as popular.
We found that @colyseus/schema demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.