# cloudRise 开发与验证记录 依据:[PRD V1.2](cloudRise-PRD.md)。后端仓库为相邻的 `server`,不是本项目内的旧 `server` 副本。 2026-09-12 更新:页面已改为独立 Prefab,业务脚本迁入 cloud_rise 分包,并增加登录后的资格检查与后台预加载。编辑器维护方法和加载条件见 [Prefab 与登录预加载](cloudRise-prefab.md)。 ## 客户端接入 - `assets/Script/CloudRiseView.ts`:首页与游戏内入口、Prefab 实例化、游戏暂停与首页弹窗协调。 - `assets/cloud_rise/prefab/CloudRise.prefab`:总览、匹配、阶段进度、100 人名单和成功/失败/超时页面,固定布局可在编辑器中维护。 - `assets/cloud_rise/scripts/CloudRisePanel.ts`:页面绑定与交互;不再按代码坐标生成活动页面。 - `assets/cloud_rise`:独立分包,包含 Prefab、页面与业务脚本、美术。登录后仅为服务端确认有参与资格或仍有有效个人挑战的玩家预加载。 - 主包 `CloudRiseService.ts`:资格检查、分包加载与主线事件桥接;分包 `CloudRiseRuntime.ts`:每账号独立持久化队列、开局标记、结算重试、活动状态和弹窗确认记录。 - `CloudRiseRuntime.ts`:前端计算 `ceil(ceil(奖池/存活人数)/10)*10`,通过 save_reward 上报奖励和最终余额;服务端仅保存,成功后前端更新金币。已删除 CloudRiseWallet 及通用登录/金币/丛林宝藏中的累计奖励补差。 - `JiaZai/Map/Block/SceneManager`:入口挂载和主线胜负接入。 - `HomePopupQueue`:百人赛结果弹窗加入首页队列,关闭之前不让其他自动弹窗插入。 - 首页转场期间队列等待 `zhuanchang` 节点隐藏;由现有 `down` 动画完成回调放行,百人赛淘汰、阶段总览和奖励弹窗均不会抢在转场结束前展示。未播放转场时不额外延迟。相关队列和百人赛页面测试 51 项通过。 stage1/2 成功后状态为 waiting。主线结算“下一关”通过 `CloudRiseView.continueFromNextLevel` 同步存档并展示待播结算。结算动画播完后点击任意位置切换到活动总览;只有手动点击“开始下一阶段”才匹配,关闭总览后继续主线下一关。返回首页不再因 waiting 状态自动打开 overview;玩家可点击首页入口手动查看。尚未展示的胜负结算仍由 HomePopupQueue 补播。等待期间未开启阶段不登记本活动的关卡尝试;三个阶段共用最初截止时间,stage3 完成后不再匹配。 结算播放时机:通关后先显示主线胜利页,百人赛动画等待玩家点击“下一关”,或确认新玩法“帮帮TA”后续关时播放。`playElimination` 同时处理待播进度动画和未确认展示的阶段结果,队列为空也会补开奖励页;胜利结算关闭后展示活动总览,下一阶段等待玩家手动开始。结算页隐藏右上角关闭按钮,动画中拦截点击,动画结束后接受一次新的点击;点击不会穿透到总览按钮。点击“重试”调用 `settleCloudRiseLoss()`,先播放淘汰与失败结算再重开。Lose 的放弃、Health 中间页以及两处返回首页入口调用 `settleCloudRiseLoss(false)`,只记录失败;到 HomeScene 后由原有持久化记录及弹窗队列播放,延迟响应也会补播。复活选择不判负。相关测试覆盖按钮触发顺序、首页延迟补播、重复点击、资源失败与阶段奖励;尚未重新构建或真机复验。 同一期重置复测:服务端 run.id 由玩家和 periodId 派生。同一期参与记录被管理员清空后重新报名,会复用 run.id;旧 journal.seenResults 可使前两阶段已保存奖励却不展示动画。现仅在 start 报名成功时清除该 run.id 的旧展示确认,start_stage、状态轮询、重登不清除,发奖回执不变。该情景已先复现再修复,运行时 21 项测试通过;实际 Cocos 引擎中连跑两轮 5/7/9 关(第二轮复用同一期和 run.id),六次阶段结束均显示全部四组奖励元素。此为本地隔离接口验证,尚未取得用户设备的存档以确认其具体触发原因。 首次有效棋盘操作登记本关尝试。使用可消除方块的锤子/魔法棒也接入登记;无效目标不登记。通关只结算一次,复活窗口本身不判负;确认放弃、有效重开、最终失败才结算失败。 切后台与网络错误没有独立判负逻辑。新实例读取未完成尝试时补传 interrupted;已经保存的胜利优先重试上传,不能改判中断。 ## 运行检查 客户端: ```sh node --test tools/test-cloud-rise.cjs tools/test-cloud-rise-prefab.cjs tools/test-prop-guide.cjs tools/test-battle-pass.cjs node tools/preview-cloud-rise.cjs ``` 预览地址 `http://127.0.0.1:8765`。该工具使用实际构建的 Prefab、脚本、Cocos 2.4.15 引擎和资源,接口由隔离测试状态提供;不会访问生产 API。 默认构建路径为 `build/cloud-rise-prefab-verification/web-mobile`,也可用 `CLOUD_RISE_BUILD` 指定。重新构建后需重启预览进程,以读取最新带哈希的文件名。 预览顶部可切换阶段、成功、失败、超时,并用“通关”模拟进度以检查实际按钮跳转和显示。 后端配置与完整接口说明见相邻仓库 `server/laf-cloud/functions/cloudRise/README.md`。 首页解锁门槛:未报名且 GM_INFO.level 小于配置 unlockLevel 时,点击入口仅提示“月光宝盒活动通过第${unlockLevel}关后解锁”,不加载或打开活动弹窗。按已通关数量判断,服务端同步使用 users.levelAmount >= unlockLevel;已参赛轮次仍可访问进度和结算。覆盖 103/109 未解锁、110 已解锁、同步后门槛变化及已参赛访问;客户端相关 47 项、后端相关 6 项测试通过。 2026-09-15 配置开关调整:删除配置 status 依赖,沿用 startsAt/endsAt 判断活动时段,enabled 仅控制首次报名。时段内关闭报名仍可看到入口和倒计时,已报名玩家继续按个人 expiresAt 闯关。管理接口读取不返回旧 status,保存时删除该字段;索引初始化改为时间索引。前端相关 69 项测试通过,后端配置与报名相关 9 项测试通过。后端全量测试中不活跃月份和旧奖励金额两项失败已在修改前的 HEAD 代码上复现;客户端类型检查仍有既存的 17 项平台全局变量及其他模块类型错误。本次未部署云函数、未修改线上数据库、未构建客户端发布包。 ## 当前验证证据与边界 前端发奖方案:后端专项 22 项通过,包含客户端上报保存、重复保存不覆盖新余额、过期补存和真实客户端联调;客户端增加奖励向上取整、响应丢失、重登和账号切换检查。下面的 Prefab 构建与全量测试统计为此前版本记录,不代表累计奖励方案仍在使用。 - 后端活动专项测试 20 项通过,包含真实客户端服务与真实后端处理函数的联调、丛林宝藏并发保护。 - 客户端活动专项测试 12 项、Prefab/预加载专项 6 项通过;联合道具引导、通行证相关测试共 45 项通过。新增覆盖有效期与资格判断、登录不阻塞、账号切换、加载重试、Prefab 引用和真实桥接/Runtime 的三阶段流程。 - Prefab 版本的 Cocos 2.4.15 web-mobile 与 wechatgame 最终构建均退出 0,输出位于 `build/cloud-rise-prefab-verification/`。CloudRisePanel、CloudRiseRuntime、CloudRiseSurface 的模块定义仅存在于 cloud_rise,活动 Prefab 位于该包内;微信自定义 `game.json` 与生成的配置均包含 cloud_rise 分包。 - 使用完整构建的引擎与资源包预览,已检查总览、三阶段进度、成功/失败/超时结算、真实猫头像及 100 人名单滚动。成功结算返回活动后显示“开始下一阶段”,点击才进入 0/7、100/100 的第二阶段,个人截止时间保持不变。最后预览无控制台错误或警告。 - 客户端类型检查与修改前对照:17 条已有诊断,本次新增诊断为 0。 - 整套客户端测试在修改前有 37 项失败;初次本次运行的两项新增失败分别为旧测试的整文件不变断言和缺少新增服务替身,已修正并通过相关专项测试。 - 整套后端最近运行 190 项:168 项通过、22 项失败,其中存在 Node 测试子进程序列化错误。受影响的 Jungle 文件另以 `--test-isolation=none` 对照原代码与当前代码,两者均为 13 项中 7 通过、6 失败,失败场景一致;复活测试缺失路径在基线中同样存在。没有发现新增业务断言失败,不以专项通过宣称整套回归通过。 - 本地开发和构建验证已完成;尚未进行实体设备上的微信生命周期/网络恢复验收,也未连接生产数据库、部署云函数或开放活动。发布前按后端接入说明配置活动期、索引和运营密钥,并进行真机验证。 以上记录明确区分函数/模拟数据库验证、引擎画面预览与完整平台验证,不代表线上验收已经完成。 ## PRD 验收证据对应 | PRD 项 | 本地证据 | | --- | --- | | A01–A06:报名、次数、个人期限、三阶段顺序 | 后端专项中的 signup、registration closes、interrupted、all three stages 测试;服务端 canJoin 与 expire | | A07–A12:99 人固定匹配、起点分布、重复样本、冷启动 | 后端 Rules 专项中的 normal、weights、histogram、cold simulation、99 pairs;数据生成器 `--check` | | A13–A15:零分初始存活、逐关淘汰、失败结束 | Rules 的 initial survivors、win progression、fail before ten 测试;finishAttempt 的 round 与 survivors 计算 | | A16–A21:复活、放弃、重开、后台、重启、断网 | 客户端 revive/background、cold restart、offline victory 测试及 Map/Block/SceneManager 接入检查;平台行为仍需真机验收 | | A22–A24:向上取整、保留已获金币、重复结算 | 前端向上取整、保存失败/响应丢失重试;后端重复报告与全三阶段测试 | | A25–A26:超时与真实样本 | API interrupted/expiry 与 persistHistory:只写 won/lost,expired 不写样本,成功阶段保留 | | A27:旧金币存档与登录 | 原有 userCoin/Jungle 流程恢复;阶段报告重复保存与客户端重登检查 | | A28:与十连胜独立 | cloudRise 独立 journal 和 users.cloudRiseState;Rules 低连胜失败测试;旧 winState/winStreak 无修改 | | A29:美术动态数值 | 实际构建资源的 Cocos 页面预览:5/7/9、奖池、100/100、实际奖励、个人倒计时、失败/超时 | | A30–A32:结算后展示总览、手动开启下一阶段 | 客户端测试覆盖三个阶段结算点击、动画期间拦截、总览等待、手动匹配和首页不重复弹出;主线下一关不自动匹配 | 专项测试执行真实业务代码,数据库由隔离替身提供;画面预览使用隔离状态,不等同于线上端到端验收。 本次前端发奖调整验证:前端联合专项 48 项、后端活动专项 22 项通过;Web 构建退出 0,构建产物不再包含 CloudRiseWallet,发奖计算与上报代码仅在 cloud_rise 分包。未部署。 2026-09-15 结算关闭与阶段衔接:移除结算页关闭按钮,动画完成后新的一次点击才关闭;胜利后切换活动总览,下一阶段只接受玩家手动开始。81 项客户端相关测试通过。本地隔离接口配合实际 Cocos 引擎跑完三个阶段,验证动画中点击无效、宝箱与空白区域点击均可关闭、stage1/2 等待手动匹配、stage3 显示完成,无页面运行错误。类型检查仍有原有 17 项其他模块错误;未重新构建微信发布包或真机验证。 2026-09-15 局内流程补充修复:elimination 会隐藏所有按钮,后续 render 现在按页面显式恢复总览开始按钮和参与者返回按钮,避免胜利结算转总览后按钮仍隐藏。失败结算曾在停留 1.2 秒后自动关闭;现已按最新要求移除此自动继续逻辑,胜利和失败都必须在动画结束后重新点击屏幕,才执行下一步。胜利点击后显示活动总览,下一阶段仍需手动开始;失败点击后才释放等待中的重试/首页展示流程。状态轮询不会自动关闭结算。此调整的 7 项针对性测试通过。 验证:84 项相关测试通过;本地实际 Cocos 引擎中,用鼠标点击可见的阶段按钮完成 stage1→2→3,失败页无点击自动关闭并恢复等待流程,无页面运行错误。类型检查仍为既存的 17 项其他模块错误;未重新构建微信包或真机验证。 2026-09-15 新玩法续关审计:`NewMode.clickBtn(mode=0) → onNewModeConfirmed → winLevel(true)` 原先跳过百人赛结算,现在与普通“下一关”共用 `continueFromNextLevel`,等待进度/阶段奖励及总览关闭后才切换关卡。重复确认不重复安排自动续关;同步或资源加载失败恢复可见的下一关/首页按钮供重试,未完成结算不切换关卡,下一阶段仍仅手动开始。 | 通关后的入口 | 百人赛处理 | | --- | --- | | 普通下一关、新玩法/新道具“帮帮TA” | 统一等待待播进度、奖励及活动总览关闭 | | 最大关卡提示确认/继续 | 经 winLevel2 或 winLevel 进入同一结算检查 | | 胜利页首页、入职/定位返回首页 | 保留持久化结果,首页队列在转场结束后补播 | | 新手道具引导关 | 普通 winLevel 续关,继续保留原引导标记 | | 关卡内重试、放弃及体力/连胜提示 | 保持原有失败登记,重试前或首页转场后播放淘汰 | | 复活、双倍奖励广告、进关前介绍 | 不作为新的通关结果,也不额外触发结算 | 本次验证:74 项百人赛运行时、页面衔接和动画测试通过,包含实际 NewMode.clickBtn 与 Map 续关方法的联动、重复确认及失败重试。类型检查仍为既存 17 项其他模块错误;未重新构建微信包或真机验证。 2026-09-15 取消阶段成功后首页重复总览:删除 cloudRiseNextStage 自动入队及仅用于该逻辑的局部确认标记。局内胜利结算关闭后仍显示总览,返回首页不会仅因等待下一阶段而再弹总览;首页手动入口、尚未展示的胜负结果和进度补播保持原样。 2026-09-16:取消 enabled,报名仅按 startsAt/endsAt 开放,保留解锁和每期一次限制。新增 durationHours(正整数小时,默认 24),报名时固定 expiresAt,已有轮次不随配置变化。管理接口 migrate_config 为旧配置补默认时长并删除 enabled/status。总览未参加、进行中、等待阶段统一使用说明文字.png;全部完成、失败、超时隐藏本期入口。独赢仍显示分享说明,其他人数为 0;第三阶段胜利手动关闭后直接退出。胜负动画及奖励补存仍独立执行。 验证:客户端页面与 prefab 52 项通过;后端 43 项通过,2 项既有失败(不活跃日期月份计算、旧集成奖励金额断言)在修改前同样存在。本次未部署云函数、未修改线上数据库、未构建微信发布包;线上旧字段需部署后执行 migrate_config。 ## 2026-09-16 页面分包调整 旧 cloud_rise 聚合预制体拆为 cloud_rise_home(主包普通 Bundle)、cloud_rise_matching、cloud_rise_stage1/2/3(四个独立分包)。每个 stage 包含当前路线、名单、头像模板和胜负/超时结算;旧 Result 等被替代节点移除。登录只预加载 home;手动报名先准备目标分包,避免资源失败消耗资格。页面关闭期间的下载回调不再访问销毁后的字段。微信自定义 subpackages 清单已同步更新。具体路径、节点编辑方式和验证范围见 cloudRise-prefab.md。 ## 2026-09-16 分包预制体构建修复 修复匹配根节点与各 stage 根节点、AvatarTemplates、ExpiredMessage 共 10 处缺失的 cc.PrefabInfo,明确绑定各自 prefab 根节点、asset UUID 和 sync=false。此前预览可运行,但构建序列化读取根节点的 _prefab.sync 时会失败。新增逐节点 PrefabInfo 回归检查,95 项百人赛测试通过。命令行微信构建尝试停留在资源库初始化,未获得完整构建成功结果,已停止本次验证进程。 ## 2026-09-16 公共字体导致的 Bundle 加载错误 微信构建产物中,home 的高优先级将 common/font 纹理及 scoin 字形归入 cloud_rise_home,主场景、shop、lose、action_bundle 的资源因此反向引用 home;这些页面先加载时出现 Please load bundle cloud_rise_home first。 最初通过新增独立 scoin 图集隔离依赖,后按共享资源要求撤回此方案,当前实现以下节为准。回归测试同时兼容编辑器保存后的本地 Prefab asset 引用和空数组。 ## 2026-09-16 公共字体统一归属启动场景 删除 home/images/scoin_digits 图片、图集及元数据,五个百人赛预制体恢复引用 common/font 原有 UUID。cloud_rise_home 优先级从 9 降为 6,匹配与三个 stage 维持 3;LoadScene 的 Load.commonFont 绑定公共字体完整图集,使其由内置 start-scene(优先级 9)持有并随启动场景加载。common 仍为普通目录,不额外增加 Bundle,也不复制字体。这里使用 start-scene,而非本项目已配置为微信分包的内置 main。 96 项回归测试通过,覆盖启动场景绑定、优先级、五个预制体共享十个字形及不存在字体副本;git diff --check 通过。本次未重新构建微信包或真机验证,需重新构建后确认字体归属和旧依赖重定向已刷新。 ## 2026-09-16 入口弹窗初始化失败 当前 home 预制体的 StartStage 仅剩 CaptionCover,动态文字节点 Caption 缺失,CloudRisePanel.overviewAction 为 null。render 写入 overviewAction.string 时抛出空引用异常,CloudRiseView.open 的统一 catch 将其显示为“活动资源加载失败,请重试”,并非此次字体依赖报错。 恢复 StartStage/Caption 的 Label、描边、PrefabInfo 及 overviewAction 绑定。新增读取实际预制体绑定并执行初始化的回归测试:修复前复现 Cannot set properties of null (setting 'string'),修复后验证开始、开始下一阶段、知道了及文字遮盖关系。97 项相关测试通过;本次未重新构建微信包或真机验证。 ## 2026-09-16 匹配页面提前显示与准备阶段取消 CloudRisePanel 同时准备匹配页和目标 stage,仅等待匹配页就绪即可切页。准备期间显示本人头像、1/100 和准备提示,右上角关闭按钮取消此次匹配并返回活动总览。此时尚未调用 startStage,不消耗报名机会,也不推进下一阶段;下载继续并复用既有缓存。 stage 就绪后进入报名确认,隐藏取消入口,沿用 Runtime 的报名、持久化队列和重试机制;确认成功后播放对手入场动画并进入进度页。每次匹配使用请求序号隔离取消后的异步回调,旧请求不能报名、切页、覆盖新请求的 busy 状态或弹出过期错误。 104 项百人赛回归测试通过,新增覆盖匹配提前显示、准备期间取消、取消后重试共享下载、旧请求竞态、销毁期间下载完成及报名确认失败。本次未重新构建微信发布包或进行真机验证。 ## 2026-09-16 统一微信分包、按 Bundle 准备页面 home 继续放主包。新增项目构建扩展 packages/cloud-rise-package,在微信 build-finished 后把 matching、stage1/2/3 四个 Bundle 放进同一个 cloud_rise 分包。它们的 config、资源 UUID 和依赖保持不变,统一入口执行四个 Bundle 的脚本入口;下载器共享一次 wx.loadSubpackage,再按请求读取对应 Bundle 配置。其他 Bundle 沿用 Cocos 加载器。扩展校验输入齐全后再处理输出,支持重复执行及重新构建覆盖。源码 meta 的 subpackage 是 Creator 中间输出格式。 活动状态同步完成后,对可参与或个人挑战未结束、有待处理奖励/结算的玩家后台准备统一分包。优先完整加载匹配预制体,打开总览后准备隐藏匹配节点;stage 在需要时加载资源和实例化。预加载不报名、不提前推进阶段;失败可重试。点击开始时仍未准备好则显示准备提示。取消、奖励和手动关闭结算规则保持不变。 112 项百人赛回归测试通过,包含构建目录合并、重复构建、缺失输入、统一下载并发/失败重试、按 Bundle 读取配置、状态预加载和隐藏匹配页复用。另对现有微信构建产物的副本执行合并,确认最终仅一个 cloud_rise 分包、内部四个配置及资源目录保留。变更脚本 TypeScript 转译及 git diff --check 通过。尚未在 Creator 完整重构建或微信真机验证;首次启用项目扩展需重启 Creator 后构建。 ## 2026-09-16 微信分包 root 不存在修复 实际产物 game.json 已指向 subpackages/cloud_rise,但磁盘仍为四个独立目录。Creator 构建日志的 platform 是 mini-game,actualPlatform 才是 wechatgame;扩展原有 platform 判断会跳过合并。改为优先 actualPlatform,同时模板清单恢复四个中间目录,仅在合并成功后由扩展写入统一目录,避免未执行扩展时产生无效 root。 新增真实 Creator 平台参数、其他平台跳过及模板到最终清单的回归验证,相关 29 项测试通过。已备份当前构建入口/配置到 temp/cloudrise-before-root-fix-o81IeD,再直接修复 build/wechatgame,确认全部 17 个分包 root 和 game.js 均存在、四个 Bundle 版本配置存在,home 保留主包。未运行微信开发者工具编译;后续构建需重启 Creator 以加载修正后的扩展。