212 lines
15 KiB
Markdown
212 lines
15 KiB
Markdown
# 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 集中 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 已有的协议版本号机制
|