@colyseus/schema

中文文档
5.0.45发布于 2026/11/05MITTypeScriptESM + CJS零依赖近 30 天下载 79.2万

多人游戏的自动状态复制. 变相平原对象,每个客户端都会通过三角洲编码获得活的,打入的镜像.

中文使用文档
文档目录21 节
  1. Schema 定义
  2. 装饰者(仍在支持)
  3. 类型脚本支持
  4. 支持类型
  5. 初级类型
  6. 声明:
  7. 反思
  8. StateView 编号 : .view()
  9. 编码器
  10. 用视图编码
  11. 解码器
  12. 后向/ 前向兼容性
  13. 限制和最佳做法
  14. 生成客户端计划文件( 用于严格输入的语言)
  15. 代码生成选项
  16. 套装模式
  17. 基准:
  18. 其他语言的解码器执行
  19. 为什么
  20. 灵感:
  21. 许可证

多人游戏的自动状态复制.
做为 科利赛,但可以单独使用.

特征

  • 普通对象, 同步: 分配财产, push 到数组,或 set 在地图上。 改变跟踪,编码和解码都是发生在你的身上.
  • Delta 编码:只有更改的属性才以紧凑的二进制格式发送.
  • 解码时触发回调数字 : 带上你自己的 调用系统在解码时,或使用内置系统.
  • 案件查询:共享全州同一案例的参考文献.
  • 国家意见:每个客户的能见度. 决定每个客户获得哪些属性和实例 .
  • 反思: Encode/Decode schema定义.
  • Schema 生成: 生成严格输入语言的客户端-侧图文件.
  • 类型安全:严格地打入了计划定义.
  • 多语言支持:多种语言可用的解码器(C# (韩语), (中文(简体) ), 卢亚, (中文(简体) ), 哈克丝) (中文(简体) ).

Schema 定义

定义可同步结构 schema() 财务报告和审定财务报表 t.* 字段构建器 :

import { schema, t, type SchemaType } from '@colyseus/schema';

export const Player = schema({
  name: t.string(),
  x: t.number(),
  y: t.number(),
}, "Player");
export type Player = SchemaType<typeof Player>;

export const MyState = schema({
  fieldString: t.string(),
  fieldNumber: t.number(),
  player: Player,
  arrayOfPlayers: t.array(Player),
  mapOfPlayers: t.map(Player),
}, "MyState");
export type MyState = SchemaType<typeof MyState>;

schema() 返回一个真实的类( c)instanceof works)并运行在平版JavaScript和TypeScript相同,没有编译器配置. 这个 type 化名是TypeScript-只用糖-在普通JS中省略.

装饰者(仍在支持)

经典 @type() 装饰器样式仍然完全支持,两种样式都产生相同的线条格式:

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;
}

由于生态系统兼容性问题,我们正在远离装饰者:它们依赖于遗产 experimentalDecorators 执行进展情况 useDefineForClassFields: false,它与现代工具链默认(sbuilding, SWC, Vite)相冲突,与TC39的装饰器规格相去甚远,在平版JavaScript中不可用. 见 设计参考 用于设置和完整的装饰文件.

类型脚本支持

与类型脚本兼容 5.x 电话, (中文(简体) ), 6.x (单位:千美元) 财务报告和审定财务报表 7.x 电话。 。 。 .

这个 @type() 装饰者使用后遗症的装饰器——在您 tsconfig.json数字 :

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "useDefineForClassFields": false
  }
}

说明: schema-codegen 需要安装在您的脚本 5.x 或 6.x 中 项目 — TypeScript 7 的本地编译器不再载运 JS编译器 API 那个密码用于解析你的计划文件。 运行时间和你的建设是 不受此影响.

支持类型

初级类型

类型说明限制
字符串utf8 字符串最大字节大小 4294967295
编号自动检测 int 或者说 float 类型。 (输出时的字节外)0 改为 18446744073709551615
布尔true 或者说 false0 或者说 1
单位8签名 8- 位整数-128 改为 127
金图8未签名的 8- 位整数0 改为 255
单位16签名 16 位整数-32768 改为 32767
金特16号无符号 16- 位整数0 改为 65535
单位32签名 32 位整数-2147483648 改为 2147483647
金特32号未签名的32位整数0 改为 4294967295
单位64签名64位整数-9223372036854775808 改为 9223372036854775807
金特64号未签名的64位整数0 改为 18446744073709551615
浮点32单精度浮点数-3.40282347e+38 改为 3.40282347e+38
浮点64双精度浮点数-1.7976931348623157e+308 改为 1.7976931348623157e+308

声明:

每个原始类型都通过它的 t.* 工厂t.string(), (中文(简体) ), t.uint8()(中文(简体) ). 收藏元素采用类型 名称,不是建筑师: t.array("string")永远 t.array(t.string())。 。 。 .

初级类型(string, (中文(简体) ), number, (中文(简体) ), boolean页:1

name: t.string(),
health: t.int32(),

儿童 Schema 结构

player: Player,   // shorthand for t.ref(Player)

矩阵 Schema 结构

arrayOfPlayers: t.array(Player),

原始类型的阵列

不能在阵列内混合类型.

arrayOfNumbers: t.array("number"),
arrayOfStrings: t.array("string"),

地图 Schema 结构

mapOfPlayers: t.map(Player),

原始类型的地图

地图内部不能混合原始类型.

mapOfNumbers: t.map("number"),
mapOfStrings: t.map("string"),

反思

Schema 定义可以通过 Reflection你可以拥有 在服务器侧定义执行, 只要发送编码 向客户端反思,例如:

import { schema, t, Encoder, Reflection } from "@colyseus/schema";

const MyState = schema({
  currentTurn: t.string(),
  // ... more definitions
}, "MyState");

// server-side: encode the schema definition itself
const encoder = new Encoder(new MyState());
const encodedStateSchema = Reflection.encode(encoder);
// ... send `encodedStateSchema` across the network

// client-side: rebuild the state without having its definition
const decoder = Reflection.decode(encodedStateSchema);
const myState = decoder.state;

StateView 编号 : .view()

你可以用这个 .view() 字段修改器以过滤只应发送到的属性 StateView即能入会.

import { schema, t } from "@colyseus/schema";

const Player = schema({
  secret: t.string().view(),
  notSecret: t.string(),
}, "Player");

const MyState = schema({
  players: t.map(Player),
}, "MyState");

使用 StateView

const view = new StateView();
view.add(player);

编码器

共有3个主要特征: Encoder 类 :

  • 编码完整的状态
  • 编码状态变化
  • 有过滤器的编码状态( 标记为属性) .view()(中文(简体) )
import { Encoder } from "@colyseus/schema";

const state = new MyState();
const encoder = new Encoder(state);

新客户在第一次连接时必须获得完整状态:

const fullEncode = encoder.encodeAll();
// ... send "fullEncode" to client and decode it

必须发出进一步的状态变化,以便:

const changesBuffer = encoder.encode();
// ... send "changesBuffer" to client and decode it

用视图编码

使用时 .view() 财务报告和审定财务报表 StateView'',必须使用单一"完整编码"来进行多视图. 每个观点还必须加上自己的变化.

// shared buffer iterator
const it = { offset: 0 };

// shared full encode
encoder.encodeAll(it);
const sharedOffset = it.offset;

// view 1
const fullEncode1 = encoder.encodeAllView(view1, sharedOffset, it);
// ... send "fullEncode1" to client1 and decode it

// view 2
const fullEncode2 = encoder.encodeAllView(view2, sharedOffset, it);
// ... send "fullEncode" to client2 and decode it

每个视图编码更改 :

// shared buffer iterator
const it = { offset: 0 };

// shared changes encode
encoder.encode(it);
const sharedOffset = it.offset;

// view 1
const view1Encoded = this.encoder.encodeView(view1, sharedOffset, it);
// ... send "view1Encoded" to client1 and decode it

// view 2
const view2Encoded = this.encoder.encodeView(view2, sharedOffset, it);
// ... send "view2Encoded" to client2 and decode it

// discard all changes after encoding is done.
encoder.discardChanges();

解码器

这个 Decoder 类用于解码从服务器收到的二进制数据.

import { Decoder } from "@colyseus/schema";

const state = new MyState();
const decoder = new Decoder(state);
decoder.decode(encodedBytes);

后向/ 前向兼容性

后向/ 前向兼容性可以通过在 终止现有结构,并提前宣布不删除,但 标记 .deprecated() 需要的时候.

这对本地编译的目标特别有用,如 C#, C++, Haxe等 - 客户端不可能拥有最多 最新版本的"计划"定义.

限制和最佳做法

  • 每个 Schema 结构可以维持 64 字段。 如果需要更多田地,使用巢状结构.
  • 标记为 .view(), (中文(简体) ), .unreliable(),或 .fullStateOnly() 字段索引 ≥ 32 使用更慢的 per- mutation 分类路径( 线性扫描覆盖已标记的字段列表, 而不是单个位图 op) 。 对于超过32个字段的计程器,请提前声明频繁被标记的字段,这样它们就会掉入位图快道.
  • 带有 ≤ 8 字段以两个数字(没有分配每个实例)存储每个实地操作字节。 带有 > 8 字段分配小块 Uint8Array 用于操作存储。 这种差别只有在分配每滴数以千计的情况时才具有重大意义——在这一制度中更倾向于较窄的巢状结构.
  • NaN 或者说 null 数字编码为 0
  • null 字符串编码为 ""
  • Infinity 数字编码为 Number.MAX_SAFE_INTEGER
  • 多维数组不支持.
  • 阵列和地图中的项目必须全部为同类型实例 .
  • @colyseus/schema 编码仅以指定的顺序编码字段值.
    • 编码器(server)和解码器(client)都必须有相同的计划定义.
    • 田地之序须同.

生成客户端计划文件( 用于严格输入的语言)

如果使用JavaScript或LUA,就没有必要去烦了. 被解释的编程语言可以通过使用 Reflection。 。 。 .

您可以根据您的服务器侧图定义自动生成客户端侧图文件 schema() 和装饰样式得到支持.

schema-codegen 需要在您的工程中安装 typeScript 5. x 或 6. x (TypeScript 7+不再将JS编译器API用于解析).

# C#/Unity
schema-codegen ./schemas/State.ts --output ./unity-project/ --csharp

# C/C++
schema-codegen ./schemas/State.ts --output ./cpp-project/ --cpp

# Haxe
schema-codegen ./schemas/State.ts --output ./haxe-project/ --haxe

代码生成选项

选项说明
--output生成的客户端计划文件输出目录( 需要)
--bundle将所有生成的文件装入单个文件
--namespace生成输出代码上的命名空间/ 软件包
--decorator自定义名称 @type 要扫描的装饰器
--tsconfigtsconfig.json 来解析导入路径的别名( 默认: 最近的) tsconfig.json编号 :jsconfig.json 在每个源文件上方)

遵循进口发现相关计划,包括光谱仪 地图由 compilerOptions.paths编号 :baseUrl 和再导出的桶文件 他们。 未跟踪已安装软件包的导入 .

套装模式

默认情况下,代码生成器每个计划类创建一个文件. 使用 --bundle 选项,将所有生成的类合并为一个文件:

# Generate a single bundled file
schema-codegen ./schemas/State.ts --output ./unity-project/ --csharp --bundle

# With namespace
schema-codegen ./schemas/State.ts --output ./unity-project/ --csharp --bundle --namespace MyGame.Schema

Bundle 模式输出文件名 :

  • 类型脚本数字 : schema.ts (或 {namespace}.ts(中文(简体) )
  • Java 脚本数字 : schema.js (或 {namespace}.js(中文(简体) )
  • C# (韩语)数字 : Schema.cs (或 {namespace}.cs(中文(简体) )
  • C++ 组合数字 : schema.hpp (或 {namespace}.hpp(中文(简体) )
  • 哈克丝数字 : Schema.hx (或 {namespace}.hx(中文(简体) )
  • 爪哇语数字 : Schema.java
  • 卢亚数字 : schema.lua (或 {namespace}.lua(中文(简体) )
  • C级数字 : schema.h (或 {namespace}.h(中文(简体) )

基准:

假设@colyseus/schemamsgpack + 键 fossil-delta
初始状态规模( 100个实体)2671号3283 (英语)
初始状态后更新一个实体的 x/y第9条第 26 条
在初始状态后更新50个实体的 x/y342个684个
初始状态后更新100个实体的 x/y668个1529 (英语)

其他语言的解码器执行

每个Colyseus SDK都有自己的解码器执行 @colyseus/schema 协议 :

为什么

初步想法/设想:

  • 检测状态变化的瓶颈小到没有.
  • 在服务器和客户端上都有一个计划定义
  • 在静态类型语言(C#, C++)方面更好的经验
  • 变相应该很便宜.

实际的Colyseus问题应该解决:

  • 避免解码未补齐的大对象
  • 允许为每个客户端发送不同的补丁
  • 改善静态型语言的开发者经验

灵感:

许可证

麻省理工学院

版本与发布记录

@colyseus/schema 共发布 473 个版本,首次发布于 2019/01/29;过去 12 个月发布了 82 个版本。

版本发布日期距今
5.0.45latest2026/11/055 天前
5.0.442026/11/055 天前
5.0.432026/10/2911 天前
5.0.422026/10/2020 天前
5.0.412026/10/1823 天前
5.0.402026/10/1526 天前

其他发布通道:alpha → 3.0.0-alpha.50,legacy → 2.0.37,legacy-4 → 4.0.31,next → 5.0.19。

关于 @colyseus/schema 的常见问题

@colyseus/schema 是什么?

多人游戏的自动状态复制. 变相平原对象,每个客户端都会通过三角洲编码获得活的,打入的镜像.

如何安装 @colyseus/schema?

在项目目录运行 npm install @colyseus/schema,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 schema-debug、schema-codegen,可以用 npx schema-debug 直接运行。

@colyseus/schema 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@colyseus/schema 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@colyseus/schema 可以商用吗?

@colyseus/schema 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@colyseus/schema 的下载量有多少?

根据 npm 官方下载统计,@colyseus/schema 在 2026/10/11 – 2026/11/09 这 30 天内被下载 791,666 次,日均约 26,389 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@colyseus/schema 还在维护吗?

最新版本 5.0.45 发布于 2026/11/05(5 天前);至今共发布 473 个版本,其中过去 12 个月发布了 82 个;首次发布于 2019/01/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。