15 KiB
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.gachaGachaComponent挂在玩家根 Entity 上,记录每卡池抽数、保底计数、十连历史- 业务逻辑:单抽、十连、卡池切换、保底(每 X 抽必出某品质)
- 抽卡是端到端验证最佳工具:消耗道具 → 服务端随机 → 发放奖励到背包 → 招募英雄 → 培养——一条完整生产链
-
新增 英雄系统 Hotfix 业务包
cn.etetet.hero(或Assets/Scripts/Hero/)HeroComponent挂在玩家根 Entity 上,缓存玩家所有Hero子 Entity- 每个
HeroEntity 含等级/经验/星级/天赋页/技能等级数组/装备引用 - 业务逻辑:招募、加经验、升星、技能升级、觉醒、天赋学习/重置、穿/卸装备
- 战力计算:基础分 + 等级分 + 技能分 + 天赋分 + 装备分
-
新增 背包系统 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.xmlschema - 输出:
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.csDTO - 派生 Luban Schema:扫描 ROK Client
*Define.cs字段 → 自动生成*.bean.xml - 派生 Luban 数据:扩展姐妹工程已有的
gmd/Tools/export_hero_json_from_configs_data.py(已验证可解析 Hero/HeroLevel/HeroStar 等表),导出 JSON → 转 Luban*.xlsx - 全程零手工录入
- ROK 工程无 Excel 源文件:服务端只有
-
新增 英雄/物品/抽卡 Luban 配置(基于 ROK
HeroDefine11 张表字段定义,重新设计为 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 大类分类管理、增减/使用/堆叠规则、新道具标记、红点;统一奖励/消耗结构 RewardEntryequipment-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 + ConfigComponentcn.etetet.hero/cn.etetet.bag/cn.etetet.gacha:业务包
阻塞前置项(必须先完成)
- 客户端热更 DLL 编译 - 执行
ET/Loader/Compile (F6),生成Packages/cn.etetet.loader/Bundles/Code/ET.*.dll.bytes - 服务端 dotnet 编译 -
dotnet build ET.sln -c Debug,生成Bin/ET.App.dll - 跑通 Login Demo - 确认
C2R_Login→R2C_Login→C2G_LoginGate链路正常 - DB 业务封装 - 新建
cn.etetet.db包装MongoHelper + MongoDB.Driver(不重写 BSON) - 日志扩展 - 新建
cn.etetet.logging加Log.Audit/Log.Slow/Log.Module扩展方法(不重写 Log) - 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 已有的协议版本号机制