# Port ROK Hero & Bag System ## Why 工程 (`Survivors`) 当前是基于 OctoberStudio 模板的单机肉鸽,**没有任何卡牌养成或道具背包逻辑**;只有金币 (`CurrencySave`)、角色解锁 (`CharactersSave`) 和宝箱抽能力这种轻量级 `ISave` 持久化。我们要把 ROK (`E:\Game\gmd\ROK`) 这套完整 SLG 卡牌养成(英雄招募/升级/升星/技能/觉醒/天赋/装备)+ 道具背包 + 装备锻造系统移植过来。 但是两个项目的技术栈完全不兼容: | 维度 | ROK | Survivors | |---|---|---| | 客户端框架 | PureMVC + ILRuntime/IFix | ET + YIUI + HybridCLR | | 协议格式 | sproto | protobuf3 | | 服务端 | C++ + Lua (9 微服务) | ET Server (单进程/Watcher 多进程) | | 配置 | 自研 `*Define` + LitJson | **Luban**(新业务表)+ ET ExcelExporter(老配置兜底) | **直接复制源码连编译都不会通过**,依赖的 `PureMVC` / `SprotoType` / `Skyunion` / `Data` / `LitJson` 在新工程都不存在。因此本次变更的本质是:**借鉴 ROK 的业务设计(数据结构、Config 字段、UI 流程、服务端 RPC 列表),用 ET + YIUI 在 Survivors 工程里完整重写一遍**。 ## What Changes ### 交付策略 - **服务端先行 + 日志 + GM 验证 + UI 后置** - **P1-P3 阶段不做任何 YIUI UI**:所有业务通过 **GM 命令 + jsonl 日志 + 单元测试** 验证 - **UI 集中在 P4 一次性补齐**:业务接口稳定后,UI 不会反复返工 - **每个新 RPC Handler MUST 同时新增对应 GM 命令**(CI 强制校验) - **三层日志体系**:L1 业务日志(30 天)+ L2 审计日志(jsonl,永久)+ L3 错误日志(90 天) - **关键操作必写审计**:抽卡、付费、GM 操作、资源大额变动、英雄招募/升星 - **慢操作必告警**:DB 查询 >100ms、Handler 执行 >500ms ### 通用 Item 设计原则(贯穿所有系统) - **所有游戏内"可获得资源"统一视为 Item**:金币 / 钻石 / 英雄碎片 / 装备 / 材料 / 经验书 / 升星石 / 觉醒符文 / 礼包 / 图标,**全部用一个 `ItemConfig` + 一个 itemId 管理** - **统一奖励/消耗描述结构** `RewardEntry { itemId, count }`:抽卡奖励、关卡奖励、商店售卖、邮件附件、礼包道具、英雄升级消耗、升星消耗、技能升级消耗——全部用同一个数据结构 - **统一变更入口** `BagComponentSystem.AddItems(rewards)` / `RemoveItems(costs)`:服务端任何业务发奖/扣资源都走这两个接口 - **客户端统一道具 UI** `BagItemUICommon.prefab`:列表/抽卡结果/奖励飘字/邮件附件/商店货品全部复用同一个图标组件,传 `(itemId, count)` 即可渲染 ### 客户端 (ET Client + YIUI) - 新增 **抽卡系统** Hotfix 业务包 `cn.etetet.gacha` - `GachaComponent` 挂在玩家根 Entity 上,记录每卡池抽数、保底计数、十连历史 - 业务逻辑:单抽、十连、卡池切换、保底(每 X 抽必出某品质) - 抽卡是**端到端验证最佳工具**:消耗道具 → 服务端随机 → 发放奖励到背包 → 招募英雄 → 培养——一条完整生产链 - 新增 **英雄系统** Hotfix 业务包 `cn.etetet.hero`(或 `Assets/Scripts/Hero/`) - `HeroComponent` 挂在玩家根 Entity 上,缓存玩家所有 `Hero` 子 Entity - 每个 `Hero` Entity 含等级/经验/星级/天赋页/技能等级数组/装备引用 - 业务逻辑:招募、加经验、升星、技能升级、觉醒、天赋学习/重置、穿/卸装备 - 战力计算:基础分 + 等级分 + 技能分 + 天赋分 + 装备分 - 新增 **背包系统** Hotfix 业务包 `cn.etetet.bag`(或 `Assets/Scripts/Bag/`) - `BagComponent` 挂在玩家根 Entity 上 - 6 大类道具分类缓存(Resource/Speedup/Boost/Equipment/Other/Icon) - 业务逻辑:增/减/使用/分解/合成/锻造图纸 - 新增 **英雄 UI**(基于 YIUI 自动化工具生成) - `HeroListPanel` - 列表(按 SortType: Rare/Star/Level/Power)+ 三段分组(已拥有/可召唤/未集齐) - `HeroDetailPanel` - 详情 + 升级/升星/技能/觉醒/天赋/装备入口 - `HeroSummonPanel` - 召唤展示 - 复用刚做好的 `CommonHeader` 顶栏 + `CommonClose` 关闭按钮 - 新增 **背包 UI** - `BagPanel` - 分页背包(资源/装备/道具/材料),使用 `cn.etetet.yiuiloopscrollrectasync` 循环列表 - `BagItemTooltip` - 道具详情浮层 - `EquipForgePanel` - 装备锻造/合成/分解面板 - `BagItemUICommon` - **通用道具显示组件**,所有 UI 凡显示道具图标+数量都复用它 - 新增 **抽卡 UI** - `GachaPanel` - 抽卡主界面(卡池列表、单抽/十连按钮、保底进度、消耗显示) - `GachaResultPanel` - 抽卡结果展示(含十连奖励列表、新英雄特殊动画) - `GachaPoolUICommon` - 单个卡池显示组件 ### 服务端 (ET Server) - 新增 **服务端持久化基础设施 `cn.etetet.db`**(**包装现有 MongoHelper + MongoDB.Driver**,不重写) - 现状:`cn.etetet.core/MongoHelper` 已有 BSON 序列化,`com.etetet.init/Plugins/MongoDB` 已有原生 DLL,**缺业务层封装** - 新包提供:`IDBComponent.Save/Query/Delete` + 连接池 + 慢查询 + Memory/Mongo 双模式 - 扩展 `cn.etetet.login/C2G_LoginGateHandler`:登录时从 DB 加载 `HeroComponent` + `BagComponent` + `GachaComponent` 到内存(**只加 5-10 行 DB 调用,不重写 Login**) - 关键操作后异步落库(脏标记 + 定时刷盘) - 新增 **服务端英雄/背包/抽卡业务**(仿 `HeroLogic.lua` / `ItemLogic.lua` 重写) - `HeroComponentSystem` - 服务端真权威,校验所有英雄养成操作 - `BagComponentSystem` - 服务端真权威,统一发奖/扣资源入口 - `GachaComponentSystem` - 服务端真权威,加权随机 + 保底机制 + 防爆 0 - 协议 Handler:`C2G_SummonHero` / `C2G_HeroLevelUp` / `C2G_HeroStarUp` / `C2G_HeroSkillUp` / `C2G_HeroWearEquip` / `C2G_TalentUp` / `C2G_GachaDraw` / 等约 15 个 RPC + Item 同步推送 ### 协议层 - 新增 **协议定义** `Packages/<新包>/Proto/HeroOuter_C_xxxx.proto` - 数据结构:`HeroInfo`、`ItemInfo`、`SkillInfo`、`TalentTree`、`EquipInfo` - C2S 请求(约 15 个):`C2G_SummonHero`、`C2G_HeroAddExp`、`C2G_HeroStarUp`、`C2G_HeroSkillUp`、`C2G_HeroAwake`、`C2G_TalentUp`、`C2G_ChangeTalentIndex`、`C2G_ResetTalent`、`C2G_HeroWearEquip`、`C2G_TakeOffEquip`、`C2G_ExchangeHeroItem`、`C2G_ModifyTalentName`、`C2G_GachaDraw`、`C2G_UseItem`、`C2G_MakeEquipment` - 服务端推送:`Hero_HeroInfo`(同步单个英雄)、`Item_ItemInfo`(同步道具变化)、`Gacha_GachaInfo`(同步抽卡进度/保底) ### 配置表 - **改用 Luban + ROK 数据自动迁移** - 引入 **Luban 工具链**(替代 ET ExcelExporter 用于本次新增的所有业务表) - 输入:`Config/Datas/*.xlsx` 数据 + `Config/Defines/*.bean.xml` schema - 输出:`Bundles/Config/*.json`(运行时)+ `cn.etetet.config/Scripts/Model/Share/cfg/*.cs`(生成代码) - **不写自定义模板**,用 Luban 原生 API + `ConfigComponent` 包装层接入 ET - **老配置(OctoberStudio + ET ExcelExporter 现有测试表)保持不动** - **ROK 配置数据来源(不需要手输)** - ROK 工程**无 Excel 源文件**:服务端只有 `Configs.data`(45 万行 Lua 表,`tabtoy` 生成),客户端只有加密 SQLite + 205 个 `*Define.cs` DTO - **派生 Luban Schema**:扫描 ROK Client `*Define.cs` 字段 → 自动生成 `*.bean.xml` - **派生 Luban 数据**:扩展姐妹工程已有的 `gmd/Tools/export_hero_json_from_configs_data.py`(已验证可解析 Hero/HeroLevel/HeroStar 等表),导出 JSON → 转 Luban `*.xlsx` - 全程**零手工录入** - 新增 **英雄/物品/抽卡 Luban 配置**(基于 ROK `HeroDefine` 11 张表字段定义,重新设计为 Luban bean schema) - `HeroConfig` - 英雄基础(ID/稀有度/初始星/技能数组/天赋数组/碎片ID/招募上限) - `HeroLevelConfig` - 等级升级(rareGroup + lv → exp/soldiers/score) - `HeroStarConfig` - 升星阶段(每星攻防血加成) - `HeroStarExpConfig` - 升星材料(item + 经验值 + 幸运系数) - `HeroSkillConfig` - 技能(5 个技能槽) - `HeroSkillEffectConfig` - 技能等级 → 属性数值 - `HeroSkillLevelConfig` - 技能升级消耗 - `HeroTalentConfig` - 天赋节点 - `HeroTalentGainTreeConfig` - 天赋树 - `HeroTalentMasteryConfig` - 天赋专精 - `ItemConfig` - **全道具基础**(含金币/钻石/碎片/装备/材料,全部用 itemId 索引) - `EquipConfig` - 装备属性(8 个部位 + 4 个 EquipItemType) - `GachaPoolConfig` - 卡池基础(id / 名称 / 单抽消耗 / 十连消耗 / 保底次数 / 保底品质) - `GachaWeightConfig` - 卡池权重表(poolId + entryIndex → itemId + count + weight + rare) ### Modified(不破坏现有功能) - **BREAKING**: 工程主入口必须改成走 `Init.unity` 场景启动 ET,再加载 OctoberStudio 主菜单 - 当前 OctoberStudio 主菜单作为"单机模式"保留,但默认走联网模式 - `cn.etetet.proto` 包内新增协议文件(新增不修改既有 Login/StateSync proto) - ET Server 启动配置 `StartConfig` 不变,新增 Hero/Bag 业务由 Gate Scene 加载 ### 不做 - **不做** ROK 服务器 (C++/Lua) 的对接(协议不兼容、架构不兼容) - **不做** ROK 完整 UI 美术素材搬运,UI 用 YIUI 重新搭,先功能可用再美化 - **不做** "雕像兑换" / "天赋页改名" 这种次要功能(一期不做,二期再说) - **不做** 与 OctoberStudio 局内战斗的深度耦合,先把英雄/背包做出来,局内带哪个英雄出战留待后续接入 - **不做** 抽卡的真实付费接入(一期只做"扣道具/钻石抽卡"逻辑,支付接入后续阶段) - **不做** 抽卡概率官方公示页面(一期内部测试用,上线前补) ## Capabilities ### New Capabilities - `hero-system`: 英雄养成系统 - 英雄实体定义、招募、升级、升星、技能升级、觉醒、天赋树、属性/战力计算、装备穿戴逻辑 - `bag-system`: 背包道具系统 - **通用 Item 数据模型(所有资源统一)**、6 大类分类管理、增减/使用/堆叠规则、新道具标记、红点;**统一奖励/消耗结构 RewardEntry** - `equipment-system`: 装备系统 - 8 部位装备穿脱、装备锻造/合成/分解、图纸制作、装备品质排序 - `gacha-system`: 抽卡系统 - 卡池配置、加权随机算法、单抽/十连、保底机制、抽卡历史、与背包/英雄系统的发奖联动 - `client-server-protocol`: Hero/Bag/Gacha 客户端-服务端协议 - 15+ 个业务 RPC + 数据推送 - `server-persistence`: MongoDB 玩家数据持久化 - DBComponent 封装、登录加载、脏标记落库 - `observability-logging`: **三层日志体系** - 业务日志/审计日志(jsonl)/错误日志、reqId 全链路追踪、慢操作告警、客户端日志桥接 - `gm-tools`: **GM 命令验证** - 双轨入口(服务端 Console + 客户端 Panel)、覆盖所有 RPC、概率模拟、数据快照、一致性校验、Release 包剥离 ### Modified Capabilities (无 - 这是首次添加业务能力,没有现存 spec 被修改) ## Impact ### 新增代码(估算) | 模块 | 估算规模 | |---|---| | 客户端 Hero 业务(Model + Hotfix + YIUI Panel × 3) | ~2000 行 | | 客户端 Bag/装备业务(Model + Hotfix + YIUI Panel × 3) | ~1800 行 | | 客户端 Gacha 业务(Model + Hotfix) | ~500 行 | | 服务端 Hero/Bag/Gacha 业务 + DB 集成 | ~3000 行 | | **`cn.etetet.db` 业务封装(基于 MongoHelper)** | ~400 行 | | **`cn.etetet.logging` 扩展(Audit/Slow/Module + reqId 透传)** | ~300 行 | | **GM 业务命令实现(基于 yiuigm + console 现成框架)** | ~800 行 | | **ROK 配置迁移脚本(Configs.data → Luban xlsx)** | ~300 行 Python | | 协议 .proto + 生成 C# | ~400 行 proto + ~2000 行 gen | | Luban schema + 配置 + 生成 C# | 14 张 bean.xml + ~1000 行 gen | | **P4 集中 UI(YIUI Panel × 8 + UICommon × 4)** | ~3500 行 | | **合计** | **~12500 行手写 + ~300 行 Python + ~3000 行生成** | ### 依赖项 **复用现有 ET 包**(详见 `Doc/ET-Packages-Audit.md`): - 现有 `cn.etetet.login`:登录链路(C2R_Login / C2G_LoginGate)必须先跑通,**仅扩展 Player 不重写** - 现有 `cn.etetet.proto`:用 `ET/Proto/Proto2CS` 工具生成 C# - 现有 `cn.etetet.core/MongoHelper` + `com.etetet.init/Plugins/MongoDB`:**BSON + Driver 现成**,不重写 - 现有 `cn.etetet.core/Log`:日志入口现成,**仅加扩展方法不重写** - 现有 `cn.etetet.yiuigm`:客户端 GM 框架现成,**仅加 `[GM]` 业务类** - 现有 `cn.etetet.console`:服务端 Console 框架现成,**仅加 `[ConsoleHandler]` 业务类** - 现有 `cn.etetet.yiui*` 系列:用 `ET/YIUI 自动化工具` 生成 UI Component/System 代码 - 现有 `cn.etetet.hybridclr`:Hero/Bag 业务代码全在热更层 (`ET.Hotfix`) - 现有 `cn.etetet.yiuiloopscrollrectasync`:背包列表用循环 ScrollRect - 现有 `cn.etetet.excel`:**仅保留给 StartConfig 等基础设施**,新业务表不用 **新增 ET 包**: - `cn.etetet.db`:DBComponent 业务封装(基于 MongoHelper) - `cn.etetet.logging`:Audit/Slow/Module 扩展(基于 ET Log) - `cn.etetet.config`:Luban Tables + ConfigComponent - `cn.etetet.hero` / `cn.etetet.bag` / `cn.etetet.gacha`:业务包 ### 阻塞前置项(必须先完成) 1. **客户端热更 DLL 编译** - 执行 `ET/Loader/Compile (F6)`,生成 `Packages/cn.etetet.loader/Bundles/Code/ET.*.dll.bytes` 2. **服务端 dotnet 编译** - `dotnet build ET.sln -c Debug`,生成 `Bin/ET.App.dll` 3. **跑通 Login Demo** - 确认 `C2R_Login` → `R2C_Login` → `C2G_LoginGate` 链路正常 4. **DB 业务封装** - 新建 `cn.etetet.db` 包装 `MongoHelper + MongoDB.Driver`(不重写 BSON) 5. **日志扩展** - 新建 `cn.etetet.logging` 加 `Log.Audit/Log.Slow/Log.Module` 扩展方法(不重写 Log) 6. **ROK 配置迁移工具链** - 派生 Schema + 改写姐妹工程 Python 脚本,跑通 Hero/Item 两张表 ### 受影响系统 / 改造点 - **场景加载流程**:`Init.unity` → Realm 登录 → Gate 连接 → 主菜单(融合 OctoberStudio) - **OctoberStudio `SaveManager`**:与 ET 服务端存档**并存**,本地存档继续用于"局内进度/设置",服务端存档用于"英雄/背包/账号资产" - **现有 `CommonHeader` / `CommonClose`**:直接复用作为新建 UI 面板的顶栏 - **HybridCLR AOT 元数据**:新增的服务端调用泛型可能需要补 `link.xml` / AOT generic 扫描 ### 风险 - ROK 业务量大,一次性做完工期长(评估 3-4 周);建议在 tasks.md 中分阶段交付(先英雄基础养成,再装备,再天赋) - DB 落库性能/一致性:脏标记 + 定时刷盘需要谨慎,避免落库竞争 - 协议变更后双端版本对齐:建议引入 ET 已有的协议版本号机制