212 lines
15 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.

# 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<T>/Query<T>/Delete<T>` + 连接池 + 慢查询 + 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 集中 UIYIUI 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 已有的协议版本号机制