6.6 KiB
R1复验裁决与后续最小范围
日期:2026-09-24。主会话。当前交付:复验逐项裁决、后续源码核查和范围建议;不是后续编码批准。
检查点0:复验裁决
《阶段4R1关闭复验-2026-09-24.md》SHA256:2D2D3CDA2B51C89B55EA0ADB7CD3D472A2824398153034CE8D3DB0D94FA7EBD5。
主会话在更新状态文档前重算KVGameplayLoopTests/repair-final-hashes.json:56/56一致,0缺失、0差异。
| 复验项 | 主会话裁决 |
|---|---|
| P2-1建筑默认值 | 接受;缺键0、已有字符串/显式null/Reset边界保持;无需再次改代码 |
| 退出衔接 | 接受;仅Editor KV模式,Ready才Stop,其他状态不重进;保留审批来源区别 |
| 56项hash | 主会话重算一致,接受受审版本 |
| 红测先行 | 接受既有首败记录,不覆盖、不为本轮文档确认重复制造失败 |
| 独立复跑4B2/B3A | 接受75组1716及13组544;三个条件探针证据沿用修复交付,不把单次运行当三次 |
| 第三进程真实回归 | 接受建筑0、正常关闭及非运行状态证据,不把CLI await超时解释成关闭失败 |
| 服务器对账 | 接受101仍空、102仍45键且逐值一致;不再导入或补写 |
| 工具限制 | 保留跨Stop等待超时和Unknown tool记录,不删除或美化 |
| 关闭范围/备注 | 接受;R1关闭有效、无新P1/P2,不重开R1复审;后续仍需独立方案和裁决 |
本次复验没有新的代码修订要求。旧修复清单保留为历史受审版本;随后状态文档变化属于本次检查点,不回写旧hash清单。
检查点1:下一步的实际阻塞
沿用用户“真实游戏先跑起来、单账号重启式重登、最少改逻辑”的要求。候选优先级为4C1普通钓鱼的一次消费保存确认,不默认启动全B/C热换号或转盘改造。已向用户提供范围选择,尚未收到新选择时按此候选继续设计准备,不视为消费方案已经批准。
源码事实:
PlayFabMgr.SyncDataImmidiate(323行起)在KV模式明确终止run;全项目直接业务调用仅捕鱼和转盘两处。不能为了让捕鱼运行而全局改成true或开放另一个未经处理的调用方。FishingBehaviorB.DoConsumeBait(744行起)先启动async void的ConsumeBaitOnPlayfab,立即调用WaitForFishBiteED;后者开启后续玩法/拉杆按钮,未等待保存结果。接收bool也只写日志。ConsumeBaitOnPlayfab(769行起)先复制扣费前的PlayerDataDic,再只改副本的energy别名;同时ReduceEnergy修改实际内存。若副本已有newData且费用大于0,则newData第4槽仍是旧体力,energy是扣后体力。当前Schema.DecodeCore(290、318行附近)明确将二者不等判为ConflictingRepresentations。这里是源码推导,未实际发送该数据。ReduceEnergy→SetEnergy会累计energyRM、发布PlayerData并保存;从满体力降到阈值下还会启动RecoveryEnergy,再次写入恢复时间和整档。故不能把扣体力当作一条无副作用赋值,也不能简单加一次“最后写入票据”就声称所有原写都已确认。ConditionType.ConsumeEnergy有成就、战令、MiniBP、LuckyTask等订阅。具体本次场景哪些订阅激活、哪些键会写入尚须逐条核实;当前不宣称全链已盘点完成。- 转盘旧协程的等待只走一次便break,ConsumeOnPlayfab不论bool真假都设isDataSynced=true。它需要自己的失败合同,本次不得因共享保存入口变化被连带开放。
三条路线与建议
| 路线 | 收益与成本 | 结论 |
|---|---|---|
| 先完成全B/C跨账号隔离 | 覆盖全面,但扩大大量回调和共享对象改动;不是当前单账号运行所必需 | 后置 |
| 先改完整退出自动保存 | 能处理普通未确认记录,但不能解决消费后立即继续玩法及旧副本冲突 | 独立后续项 |
| 先做普通钓鱼消费确认 | 直接推进可玩的普通玩法;保留单账号限制,聚焦扣费、确认和继续时机 | 推荐 |
后续完整方案必须定下的合同
以下是设计验收清单,不是已完成实施设计,不凭本材料直接编码:
- 唯一动作入口:首次扣费前固定原会话和本次动作;重复点击/协程/动画回调不得二次扣费。免费、重试、特殊鱼走向逐一界定,不能仅改收费支路就声称全普通钓鱼通过。
- 唯一有效存档表达:复用PlayerData现有整档序列化,不继续发送“旧newData+新energy”的副本;保留其余玩家字段,不放宽Schema来容忍矛盾。
- 副作用与原票据:列明ReduceEnergy、恢复计时、PlayerData通知及消费事件的同步/异步写;明确哪些票据属于本动作,如何处理同键替代,不能从全局最后票据推定。
- 继续条件:持有原票据确认且动作/对象仍有效后,才允许调用一次WaitForFishBiteED。Accepted不是Confirmed;Unknown、401、关闭、StorageError和取消不能转换成可重扣的false。
- 失败语义:保留不确定结果,不自动回滚、重扣或领奖;明确已扣款但未继续玩法时的表现。此处涉及用户体验与恢复范围,不能把原R1停止run合同直接等同于完成消费事务。
- 明确非原子范围:扣费和后续鱼获/任务奖励不是天然原子事务。完整收鱼奖励链未经核查前,不能承诺一次完整捕鱼闭环或普通用户正式启用。
- 测试与真实运行分开:先用合成后端覆盖确认前不继续、重复回调、写后丢响应、同键替代、关闭与恢复计时竞争。再列真实102现有档的备份、允许变化key、一次动作和重登对账;不重导45键,不用101空档造数据过关。
候选代码范围仅FishingBehaviorB.cs对应消费链、DataCenter.PlayerData.cs复用序列化/消费方法、UserService.KVGameplayLoop.cs必要的固定动作确认及固定验证入口;是否需要修改共享PlayFabMgr、许可字段或其他订阅者,必须由上述调用链证据决定。现在没有对这些文件的编码批准,也不另造Owner、缓存、传输或通用事务框架。
下一检查点及责任
主会话:完成消费事件及恢复计时写入矩阵、原动作身份与错误合同、精确方法白名单、测试矩阵,形成完整4C1方案。独立评审侧:收到完整方案后评审;主会话核hash逐条裁决后才编码。当前无需评审者重复审R1,也不能把本次关闭复验当成4C1实施批准。
本轮没有改游戏代码、没有启动Unity、没有发正式服务器请求。固定http://s101.local:18080/;Unity CLI Loop、不用UnitySkills、暂不打包。