跳到主要内容
SDK 如何工作

本页尚未翻译,当前显示英文版本。

核心概念

其余页面直接使用、不再解释的术语。 每个术语都有一段简短定义,并附上链接,指向讲解其背后机制的页面。

有三个主题篇幅太大,放不进一个词条,各自有单独的页面:由谁决策——调用方是谁,以及仅凭这一点就能决定什么;SDK 的构成——SDK 由什么组成;继承与组合——模块之间如何层层构建。

four primitivesentityrooms · matchmaking · leaderboards · commerceeventsRPCdatagroups assembled intobuilt on
四个原语组装成实体,模块构建在实体之上

四种使用方式

每个模块都恰好提供四种使用方式(surface),每个模块页面也都围绕这四种方式组织。这就是编程模型:

使用方式含义
声明(declaration)存在什么、如何运作;在代码或管理面板中编写,两种方式下是同一个模型
Hook你的规则,平台在具名步骤调用它们;以云函数形式部署
事件(event)平台告诉你已经发生的事——订阅,不要轮询
操作(operation)你从函数或客户端发出的请求或命令

主体

主体(actor)是发起调用的一方。一次调用能做什么,由它背后的主体决定,与代码编译进哪个 build 无关——理由见 由谁决策,机制(原子权限、组合而成的角色、InterfaceGrant)见 Access & Roles。

本文档中的主体名称来自平台自带的预设。项目可以为自己的主体另行命名;预设包括:

player · backend-service · operator · host · moderator · schema-author · architect · bot-brain · room-owner · room-visitor · entry-validator · spectator · match-organizer · warehouse-keeper · seller——页面泛指所有主体时写作 any。

运行位置

代码运行的位置。每张操作表都使用这四个标签:

标签运行位置
fn云函数(C# · TypeScript · Python · Go)。服务器权威;你的规则主要放在这里
cl游戏客户端(Unreal C++ / Unity C#)。API 对称;角色解锁的能力更少
mc房间主机所在的位置:主客户端(master-client),即拥有房间的客户端;或持有主机密钥的 Unreal 专用服务器
adm管理面板 / CLI / MCP——SDK 与运营平面在这里共用同一个模型

代码在哪里运行,不等于它以谁的身份运行

代码在哪里运行、持有哪个主体接口,是两个独立的问题。同一段代码放在哪里,权限都一样;不同的只有授权(grant)。

项目与环境

项目(project)是一款游戏的后端,它的 schema 和数据存放在相互隔离的环境中(dev、prod)。每次调用都在某个项目 + 环境(environment)中运行。

实体

核心名词。实体(entity)是一条 schema 声明加上它的实时 aspect:数据 0..*、状态 0..*、RPC 0..*、事件 0..*、hook 以及变更历史。 坦克、门、属性条和任务都是实体,区别只在于各自带有哪些 aspect。常见组合以预设(preset)形式提供(GameObject、Stat、Character、Interactable、Projectile)。参见 Entity。

预期状态

状态转换请求可以指明它预期的状态,这时结果只有两种:正是这个状态,或者请求遭到拒绝。未指明预期状态的请求,按平台处理它时状态机所处的状态判断,而不是按请求发出那一刻的状态。

回复描述的是那一刻,对之后不作任何保证:回复还在传输途中时,别人的状态转换生效了,回复依然属实,也不会因此失效。

结果取决于先前状态时,指明预期状态

如果结果取决于之前的状态,就指明预期状态。否则,不要把回复当成调用结束后仍然有效的快照。

房间

房间(room)是一局游戏会话,而不是运行你代码的地方。平台不关心由什么托管它:专用服务器、主客户端,还是后端本身。房间内部由我们负责;你通过声明、hook、事件和操作,从外部——从云函数和客户端——驱动房间。参见 Rooms。

通道与流

所有功能底层的异步原语。通道(channel)是可寻址的发布/订阅主题:房间、群组、实体,或者你自己定义的主题。流(stream)是双向均可的分块数据流:文件边到达边消费,查询可以流式返回,一个 RPC 可以扇出到一个群组并收集各方的回复。参见 Core。

原语

每个模块都由四块积木组装而成,原语(primitive)就是其中之一:事件(声明、发出、订阅)、RPC(跨网络调用)、数据与订阅(同步机制)以及 群组(一个列表,多个监听者)。房间、聊天和匹配池,都是同一个群组(group)原语,只是规则不同。

Hook 契约

处处都是同一份契约:before hook 在校验之前运行,接收带类型的 payload,可以修改它,也可以拒绝请求;after hook 在操作提交之后运行,接收请求和结果,只能追加副作用——它永远无法让操作失败。hook 按顺序执行;平台每个已注册的步骤都可以挂载 hook。参见 Extensibility。

增量与修订号

客户端以增量形式接收状态:只包含变化的字段,并基于接收方最近确认的状态编码。每条记录都带有修订号(revision);条件写入遇到修订号不匹配就会拒绝。同步、并发和历史共用这一个版本概念。参见 Data & Subscriptions。(Unreal 所说的复制(replication)——哪个客户端看到哪些状态、多久看到一次——在这里以及 Visibility 和 Prediction & Lag Comp 中介绍。主机失联后还剩什么 讲的是另一回事:哪台机器拥有某个实体,接下来又由哪台机器接手。)

Tick

房间以固定步长模拟。每次状态变化都标记所属的 tick;同步、预测、延迟补偿和历史都按 tick 计数,而不是按挂钟时间。数据携带真实的事件时间,因此回溯和校正(reconciliation)都能做到精确。参见 Prediction & Lag Comp。