Files
ft/CodexOutput/upserver/阶段4最小真实玩法闭环方案-待评审-2026-09-24.md

114 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段4最小真实玩法闭环方案(R1,待独立评审)
目标:按用户已确认的**真实游戏、单账号、重启式重登、最小改动**,先完成“进入游戏→装备已有鱼竿→KV保存确认→重启并从服务器恢复”。本方案申请对原B/C先行范围作一次合并裁决,不申请全游戏或正式用户启用,不将4B3A关闭当作本方案编码批准。
## 1. 选择及边界
选择复用正常UserService的一次API认证、4A Bridge、4B2 Schema/Transaction和原PlayFabMgr业务入口。暂不建立通用操作上下文/回调注册框架,不遍历改写81个调用文件,不重写31模块算法。B/C全量跨账号迁移留后续。
另外两条路线:完整B/C先行首次可运行较晚;独立验证面板不满足用户选择,均不作为本次路线。
首轮仅Editor专用测试模式,默认PF模式不变,Player编译不开放模式。真实后端固定http://s101.local:18080/。可以继续依赖PF登录取得外围身份/头像,**不得用PF UserData初始化本次游戏存档、回退或双写**;不承诺这一轮移除PF认证依赖。本人KV使用认证数字ID,外围PF ID不机械替换。
单账号限制是硬合同:一个Unity进程至多一次该模式的登录尝试;登录失败、退出、401、故障均不得再次发布会话,同账号也不例外。重登验收重新启动Unity进程;只停止Play、销毁Root或域重载不算重启。允许牺牲本开发模式的进程内重试,换取不在首轮建立全业务跨账号回调体系。
## 2. 启动、认证、加载、发布
### 2.1 开始前固定模式
通过新Editor专用设置入口生成本机运行许可,字段限于版本、固定API、已确认的专用账号、fixture备份位置及摘要;不存Cookie/密码。启动时SubBoostrap.RegisterServices在AddComponent<PlayFabMgr>之前读取并校验许可,将本次后端固定为kv-loop。普通配置kv仍按既有规则拒绝,不能通过改字符串绕过数据边界。
进程使用标记以项目标识+当前进程ID/进程启动时间命名,以CreateNew方式持久化到项目KVGameplayLoopTests/run-control;首次读取许可即占用,关闭不删除。域重载或重复进入Play再次发现标记时拒绝进入游戏。新进程启动时间不同才可重新占用。标记不是账号凭据。校验失败明确报错,不能静默走PF。
PlayFabMgr.Awake在该模式只建立已有组件实例,不启动旧缓冲、PlayerPrefs比较或40秒PF循环。已启动旧实例不允许热切该模式。其他模式保持原行为;场景/prefab/meta GUID不改。
### 2.2 一次API认证和严格加载
UserService正常实例承担原来已有的session拥有权,新增一个4A Bridge字段及单次运行状态。**不使用B2验证Capability创建真实handler,不修改既有Context/Coordinator/Lease/Registry/Cache/State。**
顺序固定:锁定测试CustomId及generation→PF仅身份/资料登录(本模式不请求或消费UserData,不执行旧InitData)→现有API登录一次→Bridge.OpenAsync借用同一apiSession→一次Ready快照→完整Schema.Decode→31真实对象Reset/Replace→发布本次固定handle→启动KV周期同步→发布已有API成功事件/初始化通知→Done。
API认证在本模式暂缓发布InternalId/API登录成功事件,避免Hub/普通业务在存档未就绪时启动;CustomServerMgr沿用UseAccountSession共享Cookie。解码的AccountDescriptor取session真实响应;PrepareResult只用本次成功Open和实际快照构造,记录同一playerId/epoch/OwnerId,不凭空制造Prepared或改数据以通过schema。取得快照前后、Apply每阶段及发布前复查generation与单次状态。
新绑定辅助只将B2交付的M01~M31映射连接到真实GContext已有对象;映射与配置快照字段逐项沿用PlayerKVEditorValidationHost.RunFullLoad及《阶段4B2字段与模块加载合同-正式版3-2026-09-23.md》。不构造第二组业务对象,不复制codec/Reset/Replace算法。新快照使用当前配置、实际服务时间及原批准文化/时区规则,不使用测试host固定日期。
加载期间使用现有guard,Transaction的notify不执行旧有副作用;所有模块成功后解除本次guard并发布固定handle,再在原Agg Login订阅仍有效期间触发普通初始化通知。UserService/Agg的M31 Reset/Replace只增加“本模式正在加载且尚未发布”的准入,不放宽普通外部调用或B2验证限制。Raw传给后续通知的是独立副本;读取和初始化存档来源一致。
EmptyNew/EmptyExisting、Malformed、Conflict/Unknown/StorageError以及任何模块加载失败均不Done、不建默认档、不自动迁移。先正常关闭Bridge,再释放API session。首轮只使用预先准备且Schema通过的专用fixture;新手档自动创建不是本次目标。
### 2.3 发布后的既有初始化
FishingStage.InitData仍执行已有模块Init和登录事件,其普通写入统一走固定handle;不称“只写装备key”。应记录从登录开始到装备完成的全部KV变更key,并与专用fixture允许范围核对。若初始化调用需要PF存档、未授权写入或出现Schema不能接受的派生值,停止该run,记录最小差异再裁决;不得临时开PF回退或大量放宽解码。
## 3. 普通读取、保存与故障
PlayFabMgr旧公开方法保留签名与调用点:GetLocalData在本模式委托ReadKV;只对有效缺键返回null,失败必须抛出明确异常并终止本run。UpdateUserDataValue委托WriteKV,保留remoteStore语义;不再触碰旧buffer/localData/PlayerPrefs。合法Accepted仅表示本地已接受,StorageError/Blocked/Validation触发一次性故障撤销并抛出,不回退PF、不自动重复业务动作。
复用现有40秒调度位置,但本模式调度只调用固定handle.FlushKVAsync;不同时启用原PF循环,不新增第二套后台队列。同一Owner处理并发Flush。暂停触发一次Flush观察;观察取消不取消底层排水。Unknown/401进入故障停止,不按“失败”自动重发。
为装备链添加一条窄的可等待保存结果通路:PlayerData原SavePlayerData的序列化代码只保留一份,提取内部返回结果的核心;旧void接口仍调用该核心。新装备入口在首次内存变更前捕获并检查固定handle,沿用原装备/红点逻辑,再取得该次NewPlayerDataDic对应的真实票据;不从全局“最后一次写”推测票据。装备UI等待该票据Confirmed后才显示本模式的持久化成功;等待期间防重入。
装备动作持有本次真实票据,发起一次原handle的Flush并等待该票据;Superseded不能声称当前值已确认。本方案选择**遇Superseded/Unknown/Blocked直接停止验收run并报告,保留原结果,不寻找替代票据、不实现复杂恢复UI**。不自动重新执行装备动作,不回滚已可能提交的业务动作,不在另一个账号重试。
发生故障时同步撤销所有facade新操作,记录原始结果,安排已有退出流程并明确显示失败;可能已经改变的本进程内存不当作服务器成功,也不再次保存“补偿”。由于不再允许第二会话,不会将残留内存用于新账号。
立即保存与消费不获启用:本模式SyncDataImmidiate不能转换Unknown为true,不提供消费成功替身。验收不执行抛竿、转盘、升级、购买、广告奖励。若进入这些路径或观察到初始化自动触发该类消费,立即停止run;这只是专用账号的开发验证边界,**不构成4C通过或可对普通用户开放的安全承诺**。
## 4. 关闭与重登
退出最先同步关闭facade业务准入与周期任务,使既有generation失效并调用Bridge.Close等待已准入工作排水。退出本身不发起新的Flush或重试未知写,保持现有Bridge关闭合同;**本次成功闭环必须在退出前由装备入口完成票据Confirmed**。其他尚未确认的本地记录保留,不能把退出记录成全部远端确认;完整退出自动保存仍归后续生命周期工作。继续使用既有ShutdownRegistry保留关闭Task与有界观察,超时不释放底层资源或允许重登。完成Bridge排水后才Dispose apiSession/清Cookie;正常和异常关闭均保留进程占用标记。
UserService的401监听在本模式只故障撤销,禁止原来的自动LoginApiServer;Logout不能在Bridge前Dispose session。QuitAct复用现有注销/观察位置,不能仅靠MonoBehaviour.OnDestroy等待异步清理。强制结束进程的未确认结果保留为未知,不计作成功退出。
成功重登验收:首次真实装备Confirmed后正常退出并关闭Unity;重新启动Unity,通过CLI Loop确认新进程和正确项目。使用新独立KV缓存根登录同一账号;从服务Get的NewPlayerDataDic恢复目标装备,证明不是旧内存/缓存。保存前后关联字段摘要也要核对;同run中允许发生的正常初始化字段变化逐项记录。
## 5. 精确实施边界与检查点
以下是申请评审的白名单,**待通过裁决后生效**。每项只允许本模式分支和必要接线,原默认行为不重写。
| 文件(Client/Assets/下) | 允许改动 |
|---|---|
| Scripts/SubBoostrap.cs | AddComponent前固定模式,拒绝热切换 |
| Scripts/Core/PlayFabMgr.cs | 本模式Awake/生命周期及旧facade转发;既有四个固定入口合同不变 |
| Scripts/Services/UserService.cs | PF只身份分支、API成功延迟发布、登录接线、401及Logout关闭顺序 |
| Scripts/Services/UserService.KVLoad.cs | 仅M31在运行时加载窗口的准入;B2受控入口保持 |
| Scripts/Services/AggUserService.cs | Editor本模式固定CustomId、M31运行时准入及通知时序;不迁移真实渠道SDK |
| Scripts/Services/UserService.KVGameplayLoop.cs(新增+meta) | 单次运行状态/Bridge拥有权、加载和发布、故障及关闭;本机许可/进程标记,不另建通用框架 |
| Scripts/Services/PlayerData/PlayerKVGameplayBindings.cs(新增+meta) | 31现有对象与已批准Schema/Transaction的绑定、配置快照;无模块算法复制 |
| Scripts/Stages/LoginStage.cs | 本模式固定走已有Editor输入登录路径,阻止重复进程内登录;不更改场景资产 |
| Scripts/Stages/PFLoginAct.cs | 固定测试ID与本模式明确错误退出,不提供同进程重试假象 |
| Scripts/Stages/QuitAct.cs | 接入本模式已拥有的关闭Task,保留原退出清理 |
| Scripts/DataCenter/DataCenter.PlayerData.cs | 原序列化单份复用、窄装备可等待入口;字段/格式/经济算法不改 |
| Scripts/UI/Rod/FishingRodPanel_Level.cs | 仅装备按钮本模式防重入、结果等待与错误显示;升级逻辑不改 |
| Editor/KVGameplayLoopSetup.cs(新增+meta) | 本机许可准备、只读预检、固定CLI可调用状态/结果,不做任意反射执行器 |
| CodexOutput/upserver/KVGameplayLoopTests/及本阶段文档 | 测试与证据,不污染旧工程Compile树 |
禁止改动:B1 Context、B2受控Capability/Coordinator、底层State/Cache/网络Client/SyncCoordinator、其余业务模块、SDK/包/场景/服务器。若上述白名单确实不足,先给出具体方法级差异供同一方案补审,不在实现时擅自扩展。
检查点0:评审+逐条裁决、测试数据许可、保存这批文件基线;1:单次模式与登录/真实加载;2:统一facade与装备保存/关闭;3:Unity真实闭环与限定回归、结果交付。每点只更新同一实施记录和开发日志,避免重复复制整套历史文档。
## 6. 验收与运行前置
| 项 | 通过条件 |
|---|---|
| R1-01 | 无许可/Player模式拒绝;PF默认路径保持;模式在PF Awake之前固定 |
| R1-02 | 同一进程第二次尝试(含域重载)拒绝;新进程才允许重新开始 |
| R1-03 | 一次API认证、同Cookie Bridge/HTTP;Get/Decode/Apply任一失败无Done、无默认保存 |
| R1-04 | 31真实容器对象就地加载,原序列化往返;启动自动保存全部可解释、无PF存档回退/双写 |
| R1-05 | 真实鱼竿界面装备已有鱼竿,确认原票据;失败不显示云端保存成功、不重复动作 |
| R1-06 | 401禁重认证、注销先撤销、Bridge排水后session销毁;旧调用拒绝且不能取得第二会话 |
| R1-07 | 重启Unity并换新缓存根,实际Get后恢复装备;前后相关字段核对 |
| R1-08 | 编译、原4A/4B1/4B2/4B3A必要回归及受改服务宿主;默认PF路径回归;保留首败 |
真实运行前必须确认专用测试账号和可写全档fixture:已有至少两根可装备鱼竿、配置匹配、Schema通过、前置备份和恢复途径明确。测试不能把正式老用户空KV当新档,不能自动复制PF全档到KV。若没有合适数据,先交付明确的fixture准备内容,待用户确认账号/数据范围后执行;这不阻止先审查与实施接线代码。
全程Unity CLI Loop、不用UnitySkills、暂不打包。真实PlayMode与业务写属于本方案通过且数据许可明确后的验证,不沿用A的“仅合成handler”结果冒充。P2-α真实存量用户专项、身份全迁移、4C、tickets长期历史、热换号和G4仍保留。
## 7. 给独立评审AI的提示词
请审查本R1方案,重点判断是否以合理的小范围达到用户确认的真实游戏单账号重启式闭环,是否仍有不必要的抽象/重复实现。先读4B3A关闭裁决与本方案、范围核查、当前源码,再核对配套受审hash。只新增《阶段4最小真实玩法闭环方案独立审查-2026-09-24.md》及独立日志,不改共享状态或实现。
逐项检查:启动先于PF Awake;正常API session直接借给4A Bridge是否可行;31真实对象绑定与M31准入;初始化自动写及PF身份/存档分离;原保存序列化是否单份复用;准确票据与装备UI;进程重载限制是否可靠;Logout/401排水;Editor模式数据授权及4C未启用边界。可明确退回有缺口的合同,不能因“只是测试账号”忽略实际跨会话或正式数据风险,也不要无依据要求先做全部B/C重构。
给出接受/修订后接受/退回、P1/P2/P3、具体文件/方法和最小修正建议;分别回答“范围调整是否合理”和“方案是否足以批准白名单编码”。主会话收到后逐条裁决。本轮无权编写生产实现。