Builda Online
更新于 2026-10-23 English
文档目录

Builda Online

Builda Online 为 Builda 游戏提供托管联机能力。游戏保留自己的客户端表现和玩法规则,平台负责玩家身份、 匹配、房间调度与联机传输;房间规则由你的 TypeScript 或 Rust Room 源码定义。

复制给 AI

请为当前项目接入 Builda Online:读取 https://ai.builda.game/online/setup.md,并严格按照其中的安装与工作流说明执行。

选择玩家体验

先决定玩家进入游戏、开始一局和结束后的体验。一个游戏可以同时提供多个入口,但每个入口都应属于一种明确模式。

玩家看到的体验 适合场景 联机方式
凑齐固定人数开一局,结束后回大厅重新找人 1v1、多人对战、合作闯关 单局匹配
玩家留在同一个房间连续开局,等待时可以加入 CF/CS 风格房间、桌游房 循环房
玩家进入一个已经运行的世界,新人可以随时加入 MMORPG 分线、影子世界、长期服务器 长期房
玩家直接开房,通过 Builda App 邀请好友或分享 Room ID 好友对战、私人合作 私有房

每种玩法用一个 matchKey 标识,对应 Room 程序、人数、队伍和运行配置。同一玩法可以提供两个独立入口:

两种入口可以单独开启、同时开启或同时关闭。私有房没有房主,创建者与成员平权;仍受队伍容量和房间生命周期 约束。公共 Pool/RankPool 对局已确定参与名单,知道 Room ID 也不能新增成员。 AI 会继续确认每个入口的人数、何时允许加入、断线后如何恢复,以及一局结束后玩家去哪里。

排位积分: 公共 mode 为 RankPool 时,平台按游戏提交的积分配对:入队时传 rankScore(Godot 为 rank_score,Unity 为 MatchJoinOptions.RankScore)。积分必须是 0 到 9007199254740991 的整数。平台只校验数值 范围,不核验积分是否真实;胜负、奖励或排名依赖该积分时,游戏需要自己设计防篡改方案。

支持范围

每个项目只安装一套客户端 SDK、一种 Room 语言和同语言的本地 Mock。

部分 当前支持
游戏客户端 Godot、H5、Cocos Creator 3.8 Web、Unity
Room 语言 TypeScript、Rust
玩法数据面 WebRTC DataChannel
房间入口 公开自动匹配、私有房创建与 Room ID 加入
玩家数据与支付发货 Room 内读写跨房间保留的玩家数据;grantBy 为 "room" 的内购订单由 Room 发货
Builda App 联机社交 Room 聊天群、房间邀请拉起(由 Builda App 提供,游戏不用自建)
本地联调 TypeScript 或 Rust 源码 Mock

客户端负责输入、界面和表现;Room 负责校验玩家行为、推进权威状态、广播结果、断线处理和结算。不要把需要 防篡改的胜负、伤害、资源或排名只放在客户端决定。

玩家数据

玩家数据(Player Data) 按游戏 + 玩家保存、跨房间保留,只能在 Room 里读写。客户端没有这套 API (privateKV 是另一套私域存档)。TypeScript Room 使用 cloudEnqueue / cloudRead* / cloudFlush / cloudLoadSnapshot,Rust Room 使用对应的 cloud_state_api。

语义或故障请反馈玩家数据维护方,不要当成客户端 SDK 问题。

支付发货

内购付费点在 builda.publish.json 的 payPoints 里用 grantBy 声明发货方:

Room 发货流程:

  1. 收到 orderId 后调用 doOrder / do_order,结果在后续 tick 进入回调,不要阻塞等待。
  2. 只在结果为 allowed 时,在同一回调内用 fulfill 给该玩家写玩家数据(例如增加金币)。商品以回调结果里的 payId 为准,不要信任客户端上传的商品 ID;发货对象始终是发来消息的已鉴权玩家。
  3. 支付回调里不要调用 cloudEnqueue / cloudFlush;平台会等 fulfill 的写入生效后再完成订单。
  4. already_delivered 表示已经发过,不要当成拒单;未完成的订单可以用同一 orderId 再次 doOrder 补发。

Builda App 自带的聊天与邀请

联机房间里的聊天和邀请好友不需要你自己做服务器或界面,Builda App 已经提供,SDK 负责在正确的时机把游戏 和它们接起来。

房间聊天

房间邀请与加入

聊天和邀请对公开房与私有房完全一样。AI 接入时会按你的玩法决定聊天入口放在哪里、team_id 如何划分, 以及启动时如何处理邀请。

从接入到上线

  1. 确认项目。 项目应已接入 Builda,并能识别唯一的客户端引擎。
  2. 交给 AI。 点击页面右上角的“复制给 AI”,把完整接入指令发给项目中的 AI。AI 会安装与项目匹配的 Skill、SDK 和 Mock。
  3. 确认方案。 用玩家语言确认匹配入口、房间人数、房间生命周期、Bot、断线和结算规则。
  4. 本地联调。 用两个不同的本地身份验证加入、状态、消息、断线和离开。
  5. 部署 Room。 只有你明确要求部署或上线时,AI 才会上传 Room 源码并激活线上版本。
  6. 真实验证。 使用两个真实身份验证匹配、进入 Room 和玩法消息,再决定是否公开客户端。

Room 部署可能立即影响相同兼容修订号下新创建的真实房间。纯客户端更新、兼容的 Room 更新和不兼容协议更新 有不同的发布顺序,交给安装后的 Skill 判断,不要用重复上传来试错。

本地与线上

本地 线上
身份 合成本地身份 Builda App 真实身份
Room 直接运行当前语言源码 平台重新构建并托管运行
传输 本地回环 WebSocket WebRTC DataChannel
聊天与邀请 不可用,SDK 返回不可用状态 由 Builda App 提供
玩家数据与支付发货 Mock 仿真玩家数据和假订单发货 真实玩家数据与 Builda 支付
能验证 Room 规则、消息、状态和基本生命周期 真实鉴权、匹配、WebRTC、聊天与邀请、托管运行
不能代表 生产容量、安全隔离、TURN、分布式恢复 本地快速迭代环境

TypeScript / Rust 本地 Mock 可以仿真玩家数据和假订单的 doOrder / fulfill,不上线就能跑通发货闭环;但它不代表 生产存储和真实支付,完整验收仍需在线上完成。

页面地址、localhost 或 127.0.0.1 不能用来判断游戏是否连接本地 Mock。Builda App 也可能从设备本地地址加载 真实游戏 Bundle;客户端只使用安装记录和 Builda 本地开发外壳提供的明确配置。

使用限制

下面是每个 Room 和每次部署的当前硬上限,不是建议填满的目标。超过结构或运行上限时,请求可能被拒绝, 严重超限的 Room 可能被保护性关闭;日志超限只会丢弃日志,不会阻塞玩法逻辑。

Room 运行资源 当前上限
单个 Room 玩家数 50 人
单个 Room 内存 64 MiB
单个完整玩法消息帧 65535 字节
单个恢复 checkpoint 4 MiB
单次生命周期回调提交给平台的命令 256 条
单次回调 / 每 Room 每秒输出 1 MiB / 4 MiB

游戏数据带宽

线上所有 Room 都同时执行用户和房间两层带宽限制。上行指客户端发给 Room,下行指 Room 发给客户端, 1 KB = 1024 字节。额度包含完整玩法消息帧和协议开销,不只是业务正文。

范围 上行基础速率 下行基础速率
每个用户 10 KB/s 30 KB/s
每个 Room 10 × 有效人数 KB/s 30 × 有效人数 KB/s

有效人数为 min(当前已连接的去重用户数 + 1, 房间最大人数)。例如最大 5 人的房间,1 人在线时房间按 2 人额度计算,满员时按 5 人计算;每个用户仍受个人额度限制。同一用户的多条连接共享个人额度, 线上传输方式切换或重连不会立即重置额度。广播按实际接收连接数累计,定向发送只计目标连接。

每个范围、每个方向都必须同时满足:过去 5 秒累计不超过基础速率 × 5 秒,过去 1 秒累计不超过基础速率 × 2 秒。例如单用户上行在额度充足时可集中发送 20 KB,但任意 5 秒最多累计 50 KB,不能持续每秒发送 20 KB。统计按 100ms 分桶,窗口边界最多保守延后 100ms;恢复取决于历史用量何时过期,不保证等一秒就恢复。

超限时拒绝相应玩法消息,并报告 ROOM_BANDWIDTH_LIMIT_EXCEEDED。带宽超限本身不关闭 Room,额度恢复后可继续 处理新消息,但已拒绝的消息不会自动补发。可靠信道也不能保证超额消息被接受;关键操作需要业务确认和有界、 幂等的重试,不能立即反复重发。超限通知、进离房确认和迁移通知不占玩法额度。

上表的 1 MiB / 4 MiB 是 Room 回调向平台提交输出的运行时预算,不是玩家可用网络带宽;一次广播在运行时 按一条输出计算,实际发送时还要按接收连接累计字节,并同时满足网络限额。单帧未超过 65535 字节也不意味着 当前带宽一定允许发送,分块不能绕过累计限制。

设计同步时,用“编码后单条大小 × 每秒发送次数 × 实际接收连接数”估算最坏输出。优先使用紧凑二进制、 增量同步、合并限频和按队伍或可见范围定向发送;完整快照与重连补发也应纳入预算。

源码、配置与日志

源码与配置 当前上限
matchKeys 64 项
TypeScript 单文件 / 源码压缩包 16 MiB
Workspace 文件数 / 展开后总大小 2048 个 / 64 MiB
匹配确认超时 1..60 秒
快照结构版本 1..65535
Room 日志 当前上限
单条正文 2048 字节
每 Room 每秒 20 条、16 KiB 正文
内存缓冲 / 单次查询 256 KiB / 200 条
最长保留 7 天

大状态应拆成摘要、增量或分页;不要保留无界集合、逐对象调用平台能力,或在每个 tick 广播完整世界状态。 业务状态、重试和结算也不能依赖日志成功写入。本地 Mock 只执行部分消息与日志限制,不模拟线上 WASM 内存、 checkpoint、输出预算、线上双窗口带宽限制或真实容量,因此本地通过不能证明线上容量满足要求。

当前交付信息

本文档更新于 2026-10-23。页面、Skill、SDK 和 Mock 会随同一 CDN 快照验收和切换。

组件 版本
联机开发 Skill 0.36.0
日志诊断 Skill 0.5.0
Godot / H5 / Cocos / Unity 客户端 SDK 0.20.0 / 0.18.0 / 0.11.0 / 0.19.0
TypeScript / Rust Room SDK 0.14.11 / 0.14.11
TypeScript / Rust 本地 Mock 0.6.18 / 0.5.19
Room 公开合同 0.12.0

联机交付物随 Builda SDK 同版本发布,项目按 .builda-agent/sdk-version 锁定唯一版本,不会因为开始新的联机功能 而自动升级。只有你让 AI 运行 builda sdk upgrade 推进版本后,builda-online upgrade 才把联机 Skill、客户端 SDK、 Room SDK 与本地 Mock 一起更新到同一版本,而不是只替换单个文件。

常见问题

需要自己学习全部 API 吗?

不需要。先确认玩家体验和规则,把安装入口交给项目 AI。AI 应根据当前引擎和 Room 语言只读取相关公开资料, 完成客户端、Room、配置和本地验证的闭环。

本地测试通过就能上线吗?

不能。本地 Mock 适合验证业务规则,但不模拟真实鉴权、匹配算法、WebRTC/TURN、容量或安全隔离。上线前仍需用 真实身份创建新 Ticket 和 Room 验证当前线上 Artifact。

可以同时使用 TypeScript 和 Rust Room 吗?

一个项目应选择一种 Room 语言。已有源码时沿用项目证据;新项目无法判断时,由作者选择。客户端引擎和 Room 语言彼此独立,例如 Unity 客户端可以配 TypeScript Room。

聊天和邀请好友需要自己开发吗?

不需要。房间聊天群和房间邀请由 Builda App 提供,SDK 在进房、离房和启动时自动衔接。游戏只需决定聊天入口的 位置和队伍划分,并在启动时处理一次邀请。本地 Mock 不模拟这两项,需要在 Builda App 里用真实身份验证。

如何查看线上 Room 问题?

安装包包含独立的日志诊断 Skill。让项目 AI 查询 Room 日志、丢弃统计或退出原因时,它会使用只读诊断流程, 并避免输出玩家隐私、凭据或完整敏感负载。