Skip to Content
文档TikTok 互动

从零制作一个 Combos TikTok 互动游戏

这篇教程带你做出 Gift Arena(礼物竞技场):主播攻击对手,观众通过礼物为主播充能、回血,或直接攻击对手。你会拿到完整项目、本地礼物测试台、Combos 发布步骤,以及真实 TikTok 接入所需的登记清单。适用 Combos SDK 1.1.0。

先玩一下示例 · 下载完整项目

目前没有可用的真实 TikTok 互动开通路径。你现在可以完成本地开发、礼物模拟和 Combos 发布;发布作品不会自动获得真实礼物。后面的接入材料和真实 LIVE 验收用于未来平台开放接入后的准备,不是现在就能申请完成的流程。

1. 先声明礼物,再设计游戏效果

先确定玩法,不急着连网络。这个示例中,主播初始生命 70、能量 40,对手生命 100。每次攻击消耗 10 能量,造成 10 伤害;对手存活时反击 8 点。观众用下面三种效果帮助主播:

游戏内礼物固定的 instructioncount = "1"count = "3"
电池gift_battery+20 能量+60 能量
治疗gift_heal+15 生命+45 生命
闪击gift_flash对手 −10 生命对手 −30 生命
// rules.js — this game's contract export const GIFT_CATALOG = Object.freeze({ gift_battery: { target: 'energy', perCount: 20, max: 100 }, gift_heal: { target: 'hp', perCount: 15, max: 100 }, gift_flash: { target: 'bossHp', perCount: -10, max: 100 }, });

这份声明写在你自己的游戏代码里。它不是 SDK 的注册调用,也不是 TikTok 礼物目录。电池、治疗、闪击只是示例里的效果名称,不代表真实 TikTok 礼物的名称或 ID;不能假定玫瑰或某个价格会自动对应其中一种效果。

接入前还要定清楚边界:本示例只接受 1–1000 的整数数量,生命和能量上限 100,对手生命下限 0;礼物不消耗玩家回合。到达上限时,效果即使没有进一步增加数值,也视为成功。胜利或失败之后的新指令返回 false,开始新一局才能继续接收。这些都是示例的玩法规则,不是平台限制。替换成自己的游戏时,要明确连发叠加、冷却、跨局处理和高成本效果,并把同一套规则交给礼物配置方。

2. 搞清楚平台和游戏各自负责什么

观众送礼 → TikTok 礼物映射 → Combos → SDK 的 onCommand → 游戏效果 → 布尔执行结果 → Combos → TikTok 回执。

谁负责要完成的工作
游戏开发者声明支持的指令,执行并保存游戏效果,去重,返回真实执行结果
Combos 宿主与 SDK登录和启动绑定、会话续期、指令传输、心跳、重连、结果回传
Combos / TikTok 接入方登记游戏入口和允许使用的账号,配置启动链路及真实礼物到指令的映射

例如,一次已配置的互动产生 instruction: "gift_flash", count: "3",游戏就扣除对手 30 点生命。count 是映射后的指令数量,不是金币价格,也不一定等于送礼件数。连击如何换算数量,需要在登记时确认。游戏本身不用读取 launchData、给 TikTok 请求签名、另建 WebSocket 或实现 webhook。

3. 再实现游戏收到的协议

type TTLiveCommand = { messageId: string; instruction: string; count: string; timestamp: string; };
字段游戏应该怎么处理
messageId当作不透明的去重键;同一条消息不能执行两次效果
instruction精确匹配自己声明的指令;不支持的指令明确拒绝
count十进制整数字符串;先校验并限制安全范围,再转成 Number
timestamp来源指令的时间字符串;不能当作身份、去重键或严格顺序保证

当前公开指令里没有观众 ID、昵称或真实礼物 ID,不能基于这些不存在的字段直接做“送礼观众排行榜”。

效果确认保存后返回 true;确定拒绝执行时返回 false;结果无法确认时抛错,例如存储失败。未知结果不会被确认,后续可能重投。不能一遇到异常就返回成功,也不能在效果可能已经部分生效时直接返回失败。

SDK 会在当前页面内重发待确认的结果,游戏还要处理刷新后的重复消息。示例把游戏状态和消息执行结果放在同一笔 IndexedDB 事务里保存,事务提交后才返回布尔值。重复消息读取原结果,不再施加效果;新一局保留旧回执。LIVE 存档按 Combos 账号和游戏隔离,也与演练存档隔离。

怎么看连接状态

getTTLiveClient() 在每个游戏页面中返回同一个客户端。getLiveStatus() 查询状态;onStatusChange() 先立即通知当前状态,再通知变化。状态包括 state、reason、action 和 confirmedAtMs,最后一个字段是最近确认启动或心跳的毫秒时间,0 表示未知。

  • connecting:正在建立连接。connected:互动会话已确认。
  • recovering:让 SDK 自动重连。unknown:暂时无法确认状态,不等于主播下播。
  • ended:这次游戏互动会话结束。按 action 的 wait、none 或 relaunch_game 处理。需要 relaunch_game 时,让主播从 LIVE Studio 重新打开这个游戏,不要因连接异常要求重启直播。

4. 运行完整 demo

准备与启动

下载 ZIP 并解压。准备一个较新的浏览器和 Python 3,用它启动本地静态服务器;不需要 Node 或 npm。保留解压出的 tiktok-arena 文件夹结构:

cd tiktok-arena python3 -m http.server 8080 --bind 127.0.0.1

打开 http://127.0.0.1:8080/,点击开始演练。不要双击 index.html,JavaScript 模块需要通过 HTTP 加载。直接玩在线示例则不用安装任何东西。游戏内语言切换支持与本站相同的十种语言。

文件需要修改或了解的内容
rules.js礼物声明、战斗规则、数量校验、消息去重
storage.js原子保存游戏状态与回执
connection.jsSDK 能力检查、登录、连接、取消
game.jsLIVE 与演练共用的处理函数及界面
index.html、style.css、draw.js、i18n.js布局、画布绘制、十语言文案

三个可以照着复现的 demo

前两行测试各自开始前先点“新一局”;第三行接着第二行做,不重置。初始数值为生命 70、能量 40、对手生命 100。每次点礼物生成新消息;重复上一条消息沿用原来的 ID。

场景操作应该看到什么
单次礼物数量填 1,依次点电池、治疗、闪击能量 60、生命 85、对手生命 90,三次结果都是 true
连发与重投数量填 3,点闪击,再点重复两次投递后对手生命都为 70;第二次 true、duplicate: true
刷新恢复与拒绝接着刷新页面,开始演练,再点重复;然后点未知指令对手生命仍为 70;未知指令返回 false,状态不变

还可以把数量改成 0、1.5、1001、9007199254740993:都应没有效果且返回 false。新一局用闪击 ×10 获胜后,再送一条新礼物,应被拒绝,直到开始下一局。用攻击和充能按钮体验普通战斗。“最近一次投递”展示输入、结果和最终数值。这些都是本地合成指令,不会购买礼物或向 TikTok 发送 ACK。

5. 在 Combos 里连接同一个游戏

发布时保留项目中的 connection.js 与 game.js。Combos 宿主注入 window.combos,不需要安装一个额外的 npm SDK,也不要重复加载 SDK 脚本。连接 Combos LIVE 按钮已经实现以下流程:

  1. 调用 init(),检查 getTTLiveSession 能力和客户端 getter。这个能力名称不是让游戏直接调用的公开方法。
  2. 从按钮点击发起 checkSession(),未登录则调用 login()。取消登录就结束;登录成功继续原来的操作。
  3. 用 getUserInfo() 为本地存档分区。这些 ID 不等于凭据,也不能作为服务端鉴权证明。
  4. 订阅状态,再调用 getTTLiveClient().connect({ onCommand }),使用与演练相同的处理函数。
  5. 连接重试期间仍可断开 / 取消;取消或离开页面时取消订阅并调用 disconnect()。

下面的核心处理函数已经包含在下载项目中,完整版还会刷新界面。store.update() 是 storage.js 提供的事务方法,不是 SDK API:

import { executeCommand } from './rules.js'; // `store` is the account/game-scoped store opened by prepareStore(). function commandHandler(store) { return async (command) => { const { result } = await store.update((saved) => executeCommand(saved, command), ); return result; // State + receipt committed; no catch-and-return-false. }; }

connect() 重试时可能一直等待;它返回成功也不证明真实礼物已经生效。LIVE 模式会隐藏模拟礼物按钮,实际联调要同时核对游戏效果和执行结果。

6. 把这个项目发布到 Combos

安装官方 Combos CLI 。在 demo 中点击保存 PNG 封面,把下载的 cover.png 放在 tiktok-arena 文件夹旁边,然后在这个父目录执行:

combos --version combos account login combos post create --dir ./tiktok-arena --title 'Gift Arena' --cover ./cover.png --platform pc --screen-orientation landscape --allow-recommend=false combos post get

在浏览器里用准备发布游戏的账号完成登录。打开命令返回的分享链接,在 Combos 播放器内测试游戏。保留生成的 combos.json 绑定文件,以后仍在该目录更新同一个作品:

combos post update --dir ./tiktok-arena --platform pc

这个示例是 PC 横屏静态游戏。上传目录的顶层必须有 index.html,所有相对路径资源也要包含进去。发布不会自动开通 TT;普通分享链接如果没有已登记的 LIVE Studio 启动上下文,可以演练,但不能自行生成真实互动会话。完整发布说明见 H5 接入。

7. 准备未来接入所需的材料

目前没有可用的真实 TikTok 互动开通入口,也没有已确认的申请流程。游戏与账号登记、真实礼物映射方式需要等待平台提供接入说明;SDK 和 CLI 都不提供公开的自助注册 API。可以先准备下面的材料,供未来开放接入时使用。这是准备清单,不是正在开放的申请流程:

提供什么写清楚哪些内容
游戏信息已发布的 Combos 分享链接、绑定的 Post / 项目 ID、游戏名、PC 横屏
联调账号通过接入方指定渠道提供测试 / 主播账号;不提供密码或会话 token
效果声明三个固定指令、每个 count 对应的效果、1–1000 数量范围、数值上限和局末行为
映射需求从获准使用的真实 TikTok 礼物中选择,逐项对应指令,明确数量 / 连击换算与预期效果
验收场景下文的单礼物、连发、重投 / 恢复、会话结束测试

开始测试前,请接入方确认具体的已登记启动入口、游戏及账号资格、礼物映射已经生效。真实礼物 ID、名称、价格要来自已配置的礼物目录。假设约定一次互动产生闪击 ×3,游戏应收到:

{ "instruction": "gift_flash", "count": "3" }

不要把 TikTok 密钥、CAS token 或手工拼接的 launchData 放进游戏,这些由平台处理。登记未完成时,成果是“已发布的 Combos 游戏 + 可运行的模拟器”,真实 TikTok 验收仍待完成。

8. 开通后的真实 LIVE 验收

只有在平台提供开通方式,并确认游戏入口、可用账号和礼物映射之后,才能执行下面的真实验收。目前可以先完成上面的本地模拟与 Combos 发布检查;这些检查不能代替真实 LIVE 验收。

  1. 使用获准账号,从 TikTok LIVE Studio 打开已登记的游戏入口;在游戏中连接 Combos LIVE,确认 connected。
  2. 在测试参与者知情同意的前提下,触发一次已配置的测试互动。记录 messageId、指令 / 数量、效果前后的数值及返回结果,并请接入方确认平台收到对应 ACK。记录中不放凭据或观众个人信息。
  3. 测试约定的连发数量,核对“数量 × 效果”、上限及重复投递不重复生效,与上面的本地 demo 对照。
  4. 模拟短暂断网再恢复,同一已执行指令不能再生效一次。在宿主支持的启动流程内刷新,核对状态与回执恢复;如宿主要求重新拉起,按提示操作。
  5. 结束互动,检查 ended / relaunch_game;测试连接中取消和退出游戏。旧消息不得再造成额外效果。

浏览器存档只覆盖这个示例在同一浏览器、来源、账号和游戏内的恢复,不提供跨设备恢复或可信的经济系统。LIVE 期间不要清除它。累计 10,000 条回执后,示例停止接受新指令,不会擅自淘汰旧结果。有持久奖励或正式规模需求时,应把效果和回执一起提交到自己的可信后端,并按已确认结果制定保留策略。

卡住时从哪里查

现象下一步
unsupported_host在支持的 Combos 播放器内打开,检查 init() 能力和 SDK 是否可用
login_cancelled / missing_profile用正确账号完成登录,再发起连接
tt_not_launched、ended 或 relaunch_game核实登记和账号资格,从 LIVE Studio 重新打开已登记的游戏
已连接但没有效果核对真实礼物映射、精确指令 / 数量及当前是否已结局,请接入方按消息 ID 排查
返回 false检查未知指令、非法数量或已结束的对局;这是游戏的明确拒绝
invalid_save、receipt_capacity、storage_blocked 或 operation_failed暂停 LIVE 联调,在本地检查存储是否可用和控制台错误;保留回执、定位后再恢复,不能把未知结果改成成功 ACK

SDK 参考 · 账号与多语言

Last updated on