主题
Skip to content
埋点接入
GameHelper.GameStatistics 负责 Cocos Creator 小游戏的业务埋点。
本文按“接入准备 → 最小闭环 → API 参考 → 验收”的顺序说明。首次接入建议先完成最小闭环,再按埋点表增加道具、活动、引导等可选事件。
1. 适用范围与统一约定
1.1 能力范围
| 能力 | 接入方式 |
|---|---|
| 业务入口 | GameHelper.GameStatistics |
| 玩法、模式、关卡 | 使用标准状态接口 |
| 道具、活动、养成、引导 | 使用对应业务接口 |
| 关卡资源加载 | 使用 GameLoadRes* 接口 |
| 激励视频 | SDK 自动上报生命周期,业务补充视频点曝光 |
| 支付 | SDK 支付模块自动上报 |
| 自定义事件 | reportEvent |
1.2 核心概念
所有项目统一使用以下层级。名称一旦与数据/运营同学确认,版本内不要随意变更。
| 层级 | 事件字段 | 示例 | 说明 |
|---|---|---|---|
| 首页 | game_name | game_home | 尚未进入具体玩法的页面 |
| 玩法 | game_name | KXPYP | 最大业务单元,例如主玩法、PVP |
| 模式 | mode_name | normal | 玩法下的模式,例如闯关、每日挑战 |
| 关卡 | mode_level | 50 | 模式内的一局或一关 |
没有模式或关卡怎么办
- 没有模式:与对接人确认后统一传
wujin。 - 没有关卡:
mode_level统一传0。 - 没有分数:不传分数,使用接口默认值
-1。不要为了凑字段伪造0或1。
1.3 三个核心字段怎么传
这三个字段不是在每条事件里重复填写,而是按游戏流程逐级设置到 SDK 当前状态中。后续标准事件会自动携带当前值。
| 字段 | 完整传递规则 |
|---|---|
game_name | **怎么传:**调用 EnterGame(gameName)。**什么时候传:**玩家真正进入某个玩法时,必须早于该玩法的 EnterMode 和 StartGame。**有效期:**一直有效,直到再次调用 EnterGame 或 EnterHome。 |
mode_name | **怎么传:**调用 EnterMode(modeName, modelInfo?)。**什么时候传:**玩家选择模式、即将进入该模式时,必须早于 StartGame。**有效期:**一直有效,直到调用 ExitMode 或进入其他模式。 |
mode_level | **怎么传:**调用 StartGame(level, ...),其中 level 就是当前关卡编号。**什么时候传:**每一局、每一关开始时;重新开始也必须再调用一次。 **有效期:**当前关卡期间有效,调用 QuitGame 或 ExitMode 后清理。 |
javascript
const Stats = GameHelper.GameStatistics;
Stats.EnterGame("KXPYP"); // 设置 game_name = KXPYP
Stats.EnterMode("normal"); // 设置 mode_name = normal
Stats.StartGame(50); // 设置 mode_level = 50,并上报 game_start
// 无需重复传三个核心字段,SDK 自动附加当前状态
Stats.ProgressGame({ mode_level_progress: 80 });
Stats.SuccessGame(999);不要通过 extra 覆盖核心字段
不要在 extra 中手动传 game_name、mode_name 或 mode_level。这会造成传入值与 SDK 内部状态不一致,后续时长、广告和关卡事件也可能出现不同口径。
场景切换时按以下规则更新:
- 同一模式进入下一关:只需再次调用
StartGame(newLevel)。 - 同一关重新开始:再次调用
StartGame(currentLevel)。 - 切换模式:先
ExitMode(),再EnterMode(newMode),最后StartGame(level)。 - 回到首页:先结束当前关卡/模式,再调用
EnterHome()。
1.4 调用原则
- 事件名、玩法名、模式名和视频点名称必须与埋点表完全一致,区分大小写。
- 同一局的标准顺序是:进入玩法 → 进入模式 → 开始关卡 → 过程事件 → 结果事件。
gaming、mode_gaming、level_gaming时长事件由 SDK 定时产生,业务层不要重复自定义上报。extra只补充埋点表已定义的属性,不要覆盖game_name、mode_name、mode_level等 SDK 状态字段。- 数量、剩余数量和关卡编号使用非负整数;可选分数字段不传时保持默认值
-1。
2. 最小可用接入
下面示例覆盖单玩法、单模式和多关卡项目。代码应在 SDK 初始化及隐私流程完成后执行。
javascript
const Stats = GameHelper.GameStatistics;
// 1. 玩家进入游戏首页
Stats.EnterHome();
// 2. 玩家进入具体玩法
Stats.EnterGame("KXPYP");
// 3. 进入玩法下的模式
Stats.EnterMode("normal", {
mode_difficulty: 1,
});
// 4. 第 50 关开始
Stats.StartGame(50);
// 5. 可选:进度发生变化
Stats.ProgressGame({
mode_level_progress: 50,
mode_level_score: 600,
});
// 6. 三选一:成功、失败或平局
Stats.SuccessGame(999);
// 7. 离开当前模式并回到首页
Stats.ExitMode();
Stats.EnterHome();一局中途主动退出时调用 QuitGame,不要再补成功、失败或平局事件:
javascript
Stats.QuitGame(600, { quit_reason: "back_to_level_select" });3. 玩法、模式与关卡
3.1 主流程 API
| API | 调用时机 | 关键参数 | SDK 行为 |
|---|---|---|---|
EnterHome() | 首次进入首页、从玩法回到首页 | 无 | 停止上一玩法计时 |
EnterGame(gameName) | 真正进入某个玩法 | 玩法名 | 开始玩法计时并产生 start / gaming 链路 |
EnterMode(modeName, modelInfo?) | 进入模式 | 模式名、可选模式属性 | 开始模式计时并产生 mode_start / mode_gaming |
ExitMode() | 离开当前模式 | 无 | 结束模式计时并清理模式/关卡状态 |
StartGame(level, modeName?, extra?) | 每次开始或重新开始一局 | 关卡编号 | 产生 game_start,开始关卡计时 |
QuitGame(score?, extra?) | 一局未结算时主动离开 | 可选分数 | 产生 game_quit,清理当前关卡状态 |
SuccessGame(score?, extra?) | 成功结算 | 可选分数 | 产生 game_complete |
FailGame(score?, extra?) | 失败结算 | 可选分数 | 产生 game_fail |
DrawGame(score?, extra?) | 平局结算 | 可选分数 | 产生 game_draw |
StartGame 的 modeName 是便捷参数。当前模式不同时,SDK 会先调用一次 EnterMode(modeName):
javascript
// 等价于 EnterMode("daily") 后 StartGame(1)
Stats.StartGame(1, "daily", { level_source: "home_button" });3.2 模式属性
模式属性可在 EnterMode 时传入,并自动附加到后续关卡事件。
| 字段 | 类型 | 说明 |
|---|---|---|
mode_difficulty | number | 模式或关卡难度 |
mode_maxscore | number | 模式最高分 |
mode_startnum | number | 模式开始数值 |
mode_currentnum | number | 模式当前数值 |
mode_maxnum | number | 模式最大数值 |
mode_level_name | string | 关卡展示名 |
mode_level_error | number | 关卡错误码或失败标识,含义以埋点表为准 |
mode_level_skin | string | 关卡皮肤或主题 |
mode_level_progress | number | 关卡进度 |
mode_level_score | number | 关卡分数 |
javascript
Stats.EnterMode("normal", {
mode_difficulty: 2,
mode_maxscore: 1000,
mode_level_skin: "forest",
});切换到另一个模式时,先调用 ExitMode(),再调用新的 EnterMode()。
3.3 暂停与继续
javascript
// POPUP 是默认暂停原因,可以省略 state
Stats.PauseGame(600, undefined, { popup_name: "pause_panel" });
Stats.ContinueGame(50, "normal");PAUSE_STATE | 场景 |
|---|---|
POPUP | 暂停页或业务弹窗导致暂停,默认值 |
ADS | 广告导致暂停 |
BACKGROUND | 前后台切换 |
PROGRESS | 恢复一局有本地进度的游戏 |
ContinueGame 只有在暂停状态和传入的 state 匹配时才生效。用户主动打开暂停页时才调用 PauseGame;不要把每个普通 UI 弹窗都当作关卡暂停。
小游戏需要显式传非默认暂停原因时,使用对应数值:POPUP=1、ADS=2、BACKGROUND=4、PROGRESS=8。
3.4 过程事件
| API | 事件 | 使用时机 |
|---|---|---|
ProgressGame(param) | game_progress | 埋点表要求记录阶段进度或分数变化 |
AliveGame(score?, extra?) | game_revive | 失败后复活 |
SkipGame(score?, extra?) | game_skip | 跳过当前关卡 |
FoulGame(score?, extra?) | game_foul | 发生违规、负反馈或异常操作 |
javascript
Stats.ProgressGame({
mode_level_progress: 80,
mode_level_score: 900,
extra: { checkpoint: "boss" },
});
Stats.AliveGame(600, { revive_source: "reward_video" });4. 关卡资源加载
需要分析关卡加载耗时或失败原因时使用。GameLoadResOver 会自动计算从开始到完成的耗时。
版本声明差异
当前小游戏源码包含这组实现,但部分存量发布包的 .d.ts 尚未声明。TypeScript 工程若出现“属性不存在”,请先向 SDK 对接人确认并更新声明文件版本,不要自行转成 any 绕过检查。
javascript
Stats.GameLoadResStart(50, { bundle_name: "level_50" });
// 加载成功
Stats.GameLoadResOver(50);
// 或加载失败
Stats.GameLoadResFail(50, "download_timeout", {
bundle_name: "level_50",
});| API | 事件 | 说明 |
|---|---|---|
GameLoadResStart(level, extra?) | game_loadstart | 开始加载关卡资源 |
GameLoadResOver(level, extra?) | game_loadover | 加载完成,SDK 计算 _duration |
GameLoadResFail(level, reason?, extra?) | game_loadfail | 加载失败,reason 写入失败原因 |
5. 道具与货币
5.1 类型枚举
| 枚举 | 含义 |
|---|---|
EItemType1_CURRENCY | 货币 |
EItemType1_PROP | 有数量的道具 |
EItemType1_SKIN | 皮肤或永久物品 |
5.2 获取、消耗与使用
javascript
const ItemType = Stats.EItemType1;
// 获得 100 金币,变化后余额 200
Stats.GetItem(
1001,
ItemType.EItemType1_CURRENCY,
100,
200,
"KXPYP",
-1,
-1,
{ source: "reward_video" }
);
// 消耗 20 金币,变化后余额 180
Stats.CostItem(
1001,
ItemType.EItemType1_CURRENCY,
20,
180,
"KXPYP"
);
// 使用没有数量变化的永久皮肤
Stats.UseItem(
3001,
ItemType.EItemType1_SKIN,
"KXPYP",
-1,
-1,
{ skin_name: "forest" }
);| 参数 | 类型 | 规则 |
|---|---|---|
iItemId | number | 稳定且唯一的物品 ID,建议由项目枚举统一维护 |
iItemType1 | EItemType1 | 一级类型 |
iCount | number | 本次变化量,获取和消耗都传非负数 |
iRemainCount | number | 变化后的剩余数量 |
sItemGame | string | 物品所属玩法 |
iItemType2/3 | number | 可选分类;不用时传 -1 或省略 |
extra | object | 埋点表约定的附加属性 |
GetItem 和 CostItem 用于有数量变化的物品;UseItem 用于永久解锁、没有库存扣减的物品。不要把同一次变化同时上报为 CostItem 和 UseItem。
6. 引导、活动与养成
6.1 新手引导
引导事件必须处于已进入模式且已开始关卡的状态,否则 SDK 会忽略调用。
javascript
Stats.GuideStart({ guide_version: "v2" });
Stats.GuideStep(10, { step_name: "move" });
Stats.GuideOver({ guide_version: "v2" });| API | 事件 | 说明 |
|---|---|---|
GuideStart(extra?) | guide_start | 首次引导开始 |
GuideStep(guideId, extra?) | guide_step | 引导进度发生变化 |
GuideOver(extra?) | guide_complete | 首次引导完成 |
6.2 活动
活动统一通过 HandleActivity 上报。
javascript
Stats.HandleActivity(
Stats.EActivityType.START,
"spring_2026",
"daily_challenge",
0,
1,
"normal",
false,
{ entrance: "home_banner" }
);| 枚举 | 含义 |
|---|---|
WARMUP | 首次满足活动预热条件 |
UNLOCK | 活动解锁 |
ENTER | 进入活动主界面 |
START | 开始挑战 |
SUCCESS / FAIL | 进度变化成功 / 失败 |
REWARD | 领取奖励 |
RESET | 活动重置 |
GIVEUP | 放弃活动 |
COMPLETE | 活动完成 |
bIsOtherModeParam 为 true 时,活动信息会关联到后续道具或视频等事件;仅在埋点方案明确要求“激活活动上下文”时使用。
6.3 养成
javascript
Stats.HandleDevelop(
Stats.EDevelopType.LEVELUP,
"hero",
12,
"gold:1000",
"warrior",
"fire"
);| 枚举 | 含义 |
|---|---|
TRAIL | 试用 |
UNLOCK | 解锁 |
LEVELUP | 升级 |
USE | 使用 |
7. 广告与支付
7.1 激励视频
使用 SDK 广告模块时,点击、开始播放、播放成功/失败等生命周期由 SDK 自动上报,业务代码不要重复调用内部生命周期接口。
Cocos 小游戏需要在视频入口从隐藏变为显示时补充一次曝光:
javascript
// videoName 必须与 AdsFunc.showVideo 等广告调用使用的 name 一致
Stats.ShowVideo("double_reward");mode_level_index 的上报与视频继承
mode_level_index 为业务传入的关卡索引扩展属性,取值口径以埋点表为准,不替代 StartGame(level, ...) 设置的 mode_level。
Cocos 小游戏对该字段采用类似 mode_level 的上下文处理方式:在 EnterMode 等接口中通过 statExt 上报 mode_level_index 后,SDK 会保存该值,并在后续 video 事件中自动携带。扩展属性对象如下,需传入所用接口对应的 statExt 参数:
javascript
const statExt = {
mode_level_index: 50,
};应在视频事件触发前完成该字段的上报。关卡索引变化时,随对应业务接口的 statExt 更新为当前值,保证视频事件关联当前关卡。该继承行为适用于支持此能力的小游戏 SDK;不要将其等同于任意自定义事件属性的自动继承。
App 的传参方式不同:需要在每次 AdsVideoManager.showVideo() 调用的 opts.statExt 中显式传入,详见 App 视频广告。
7.2 支付
使用 SDK 支付模块时,支付点击、成功和失败等事件由 SDK 自动处理。除非接入任务明确要求,不要在业务回调中再次调用支付统计接口,否则会产生重复数据。
8. 自定义事件
优先使用前面的标准接口。只有埋点表存在标准接口未覆盖的事件时,才使用 reportEvent。
javascript
Stats.reportEvent("custom_button_click", {
page_name: "shop",
button_name: "buy",
product_id: "coin_1",
});| 参数 | 类型 | 规则 |
|---|---|---|
eventId | string | 后台已配置的事件名,区分大小写 |
params | object | 后台已配置的属性;保持扁平、可序列化 |
属性值必须可序列化,不要写入手机号、身份证、Token 等敏感信息。
9. 联调与验收
9.1 推荐验收路径
至少完整跑通以下用例,并在控制台和埋点后台同时核对:
- 冷启动后进入首页和玩法。
- 进入模式并开始一关。
- 暂停后继续。
- 失败后复活,或直接失败结算。
- 重新开始一关并成功结算。
- 中途退出另一关。
- 获取和消耗一次道具。
- 展示并完整播放一次激励视频。
重点核对 eventId、game_name、mode_name、mode_level、分数、数量以及自定义属性是否与埋点表一致。
9.2 常见问题
| 现象 | 排查项 |
|---|---|
| 没有事件 | 是否在 SDK 与隐私初始化完成后调用;事件名是否已在后台配置 |
| 只有玩法事件,没有关卡事件 | 是否调用 EnterMode 和 StartGame |
ContinueGame 不生效 | PauseGame 与 ContinueGame 的 PAUSE_STATE 是否一致 |
关卡号总是 0 | 是否错误地省略了 StartGame 的 model_level |
| 视频事件重复 | 是否在使用 SDK 广告模块时又手动上报了点击/播放结果 |
| 同一事件属性串到下一次 | 是否复用了并修改同一个 extra 对象;建议每次创建新对象 |
| 数据口径不一致 | 玩法名、模式名、物品 ID 是否由统一常量维护 |
9.3 提测清单
- [ ] 玩法、模式、关卡名称已与埋点表确认。
- [ ] 每局只有一个
game_start,重新开始会再次调用。 - [ ] 每局结算事件与中途退出事件没有重复。
- [ ] 没有手动重复上报 SDK 自动产生的时长、广告和支付事件。
- [ ] 道具变化量和变化后余额均正确。
- [ ] 自定义属性已在后台配置,且不含敏感信息。
- [ ] 已在目标小游戏平台完成至少一次真机/真环境验证。
点我快速对接



›
‹