# ROK 业务规则总索引(1:1 迁移依据) > 来源:`E:\Game\gmd\ROK` 服务端 Lua + 客户端 C# + sproto 协议 > 用途:移植到 Survivors 工程前的业务规则全摊牌,**实现时禁止凭空发挥** > 调研日期:2026-05-27 --- ## 0. 四份文档清单 | # | 文档 | 大小 | 摘要 | |---|---|---|---| | 1 | [ROK-Hero-Spec.md](./ROK-Hero-Spec.md) | 70K / 1362 行 | 英雄系统完整业务(招募 / 升级 / 升星 / 技能 / 觉醒 / 天赋 / 装备 / 战力 / 排序 / 同步部队) | | 2 | [ROK-Bag-Spec.md](./ROK-Bag-Spec.md) | 48K / ~770 行 | 背包系统(道具 6 大类 / itemId 编码 / 增删使用 / 礼包 / 资源货币机制) | | 3 | [ROK-HeroAcquire-Spec.md](./ROK-HeroAcquire-Spec.md) | 34K / 456 行 | 英雄获取链路(**ROK 无抽卡**,是宝箱+碎片+主动召唤) | | 4 | [ROK-Equip-Spec.md](./ROK-Equip-Spec.md) | 25K | 装备系统(8 槽位 / 锻造双段 RPC / 分解 / 套装 / 材料合成) | --- ## 1. 四个核心架构结论(必读) ### 结论 1:**ROK 没有抽卡,是"宝箱产出碎片 + 主动碎片召唤"两段式** ``` 酒馆宝箱(白银 / 黄金 / 免费 + 付费) │ Build_Tavern 407 → 服务端 ItemPackage 随机产出 ▼ 碎片 / 资源 / 士兵 / 极少数英雄本体 │ ▼ Captain UI → 点击"召唤" → Hero_SummonHero 601 │ 扣 HeroDefine.getItem × HeroDefine.getItemNum 个碎片 ▼ 英雄入手(每个 heroId 一辈子只能拥有 1 次) ``` **对 openspec 的影响**: - ⚠️ 原 `cn.etetet.gacha` 包**不对应 ROK 任何业务**(ROK 没抽卡) - ✅ 用户明确表示"想要抽卡用来验证产出",所以 `cn.etetet.gacha` **作为 Survivors 独立扩展功能保留**,但定位明确为"在 ROK 基础上**新增**",不是"移植" - ✅ 1:1 严格迁移的入口实际是 `cn.etetet.summon`(碎片召唤)+ `cn.etetet.tavern`(酒馆宝箱),二者比抽卡更接近 ROK ### 结论 2:**资源货币(金/木/石/粮/宝石/VIP/行动力)不进背包,是 Role 字段** ROK 把 **可堆叠的玩家货币** 和 **进背包的道具** 分得很清楚: | 类别 | 存储方式 | 操作 API | 示例 | |---|---|---|---| | **货币** | Role Entity 字段 | `RoleLogic.addGold/Wood/Stone/Grain/Gem/Vip/Vitality` | 金币、木料、粮食、宝石、行动力、VIP | | **资源类道具袋** | Item 入背包 | `ItemLogic.addItem` | 1xxxxxxxx 段的"100 金币袋",使用时调 `ItemChangeResource` 兑换为货币 | | **装备 / 材料 / 经验书 / 其他** | Item 入背包 | `ItemLogic.addItem` | 4xxxxxxxx + 5xxxxxxxx 段 | | **头像框 HEAD** | 不进背包 | `RoleLogic.unlockRoleHead` | 直接挂玩家解锁列表 | **对 openspec 的影响**: - ⚠️ 之前 `bag-system/spec.md` 写的 **"通用 Item 设计原则,全部货币也用 itemId 管理"** **与 ROK 不一致** - ✅ 1:1 迁移应该跟随 ROK:金币 / 钻石 在 PlayerComponent 上做整型字段,而不是 BagItem - ✅ 但"统一奖励 / 消耗结构 RewardEntry { itemId, count }" 这个**抽象层可以保留**——服务端发奖时用 RewardEntry 表达,内部分发到 Role 字段或 BagComponent ### 结论 3:**装备就是带 `heroId` 的 Item,不是独立 Entity** | 维度 | 真相 | |---|---| | 装备的存储 | 背包 ItemUnit,`count=1`,`heroId>0` 表示已穿戴 | | 英雄持有装备 | Hero Entity 上 8 个 int 字段,存 `itemIndex`(引用背包) | | 装备槽位数 | **8 个**(head / breastPlate / weapon / gloves / pants / accessories1 / accessories2 / shoes) | | 装备 subType 数 | **6 种**(HELMET / BREASTPLATE / ARMS / GLOVES / PANTS / ACCESSORIES / SHOES)— accessories 两槽共享同一 subType | | 锻造 RPC | **双段**:CheckMakeEquip (50% 专属概率) → MakeEquipment (真消耗) | | 锻造是否随机 | **必中**(材料够 + 金币够 = 必出),随机的是"专属属性" | | 分解 | 已穿戴可直接分解(前提英雄在城内),返还固定,**无随机** | **对 openspec 的影响**: - ⚠️ 之前规划的"独立 `cn.etetet.equip` 包"过度设计;改为**装备子系统放在 `cn.etetet.bag` + `cn.etetet.hero`** 协作实现 - ⚠️ 之前 spec 说"8 部位"但没说映射,实际是 8 槽 / 6 subType,accessories 双槽共享,需修正 - ⚠️ 之前漏写 CheckMakeEquip 预检 RPC,需补充 ### 结论 4:**英雄字段比 openspec 现有 spec 写的多得多** 英雄 Entity 上的字段(部分): | 之前 spec 提到 | ROK 实际还有 | |---|---| | heroId / level / exp / star / starExp / skills / talents | + summonTime / soldierKillNum / savageKillNum / talentPoint(遗留) / talentTrees(3 套天赋页 map) / talentIndex | | | + 8 个装备字段 | 英雄招募的真实字段名: | openspec 用过的名字 | ROK 真名 | |---|---| | `fragmentItemId` | `getItem` | | `recruitLimit` | **不存在**(每个 heroId 一辈子只能拥 1 次,重复 → `HERO_ALREADY_EXIST` 错误码) | --- ## 2. 与 openspec 现有 spec 的差异清单(必须修正) 以下 specs 文件需要根据本调研结果调整: ### 2.1 `openspec/changes/port-rok-hero-bag-system/specs/hero-system/spec.md` | 需修正项 | 当前写法 | ROK 真相 | 建议改法 | |---|---|---|---| | 招募字段名 | `fragmentItemId` / `recruitLimit` | `getItem` / `getItemNum`,无 recruitLimit | 字段名跟 ROK | | 招募上限 | "上限"概念 | 每个 heroId 拥 1 次(重复报错) | 改成"重复招募校验" | | 战力公式 | 通用描述 | 完整公式见 [Hero-Spec §4.10] | 引用 Doc/ROK-Hero-Spec.md | | 天赋字段 | `TalentIndex` 单值 | `talentTrees` map(1/2/3 三套)+ `talentIndex` | 加 3 套天赋页结构 | | 觉醒触发 | 通用描述 | 前 4 技能满级自动解锁第 5 + 独立 RPC | 双触发机制 | | 部队同步 | 未提 | 任意英雄改动 → 更新 `RoleArmy` 战斗属性 | 加同步规则 | ### 2.2 `openspec/changes/port-rok-hero-bag-system/specs/bag-system/spec.md` | 需修正项 | 当前写法 | ROK 真相 | 建议改法 | |---|---|---|---| | **通用 Item 设计** | "所有货币都走 itemId" | ROK 金/木/石/粮/宝石/VIP 是 Role 字段 | **改成"统一奖励结构 RewardEntry,内部分发到 Role 字段 / BagComponent"** | | 道具脚本 | "ItemScript 注册机制" | ROK 没有脚本表,是 if/elseif 硬编码 | Survivors 可以做得更好(用 IItemUseHandler 注册),但要意识到 ROK 是硬编码 | | 新道具标记 | "服务端 + 客户端分工" | ROK 全在客户端 PlayerPrefs | 跟 ROK:客户端 SaveManager 存 | | BagItemType | "6 大类" | ROK Tab 只显 5 个(HEAD 类不入背包) | 改成 5 Tab | | 头像框 | 未提 | HEAD 类不进背包,直走 unlockRoleHead | 加单独说明 | | 资源阈值告警 | 未提 | `s_GameWarning.num` 大额变动通知运营 | 可保留作为 P3 | ### 2.3 `openspec/changes/port-rok-hero-bag-system/specs/equipment-system/spec.md` | 需修正项 | 当前写法 | ROK 真相 | 建议改法 | |---|---|---|---| | 部位数 | "8 部位 + 4 个 EquipItemType" | 8 槽 / 6 subType(accessories 双槽共享) | 修正映射 | | 锻造 | 单 RPC | 双 RPC(CheckMakeEquip + MakeEquipment) | 加预检 RPC | | 专属属性 | 未提 | 50% 概率,独立 exclusive 字段 | 补充 | | 套装 | 未提 | 2/4/6/8 件**逐级叠加**加成 | 补充 EquipComposeDefine | | 千分比数值 | 未提 | 服务端 attAddEx 用千分比整数 | 数据类型澄清 | ### 2.4 `openspec/changes/port-rok-hero-bag-system/specs/gacha-system/spec.md` | 需修正项 | 当前写法 | ROK 真相 | 建议改法 | |---|---|---|---| | **整体定位** | "1:1 移植 ROK 抽卡" | ROK 无抽卡 | **改为"独立扩展功能(非 ROK 移植)"** | | 类比 | 借鉴 ROK 卡池 | ROK 没卡池 | 类比常见 SLG 抽卡(COK / RoK 实际游戏)或参考 gmd 姐妹工程 | | 优先级 | P1 | 推迟到 P3 或更后 | **降级**:先做 ROK 现有的"召唤 + 酒馆",抽卡可作为 P4+ 扩展功能 | ### 2.5 `tasks.md` 需要追加的任务: | 新增章节 | 任务 | |---|---| | 2.0 → 改为 2.1 | 抽卡降级到 P3+ | | **新 2.0** | 「英雄碎片召唤 + 酒馆宝箱」(对应 ROK `Hero_SummonHero` + `Build_Tavern`) — **真正的 P1** | | 4.1 → 替换 | 升星:星级 1-N,溢出 → 星级+1,**带幸运双倍机制** | | 3.4 → 修正 | `C2G_CheckMakeEquip` + `C2G_MakeEquipment` 双 RPC | | 1.11 → 修正 | 通用 Item:保留 `RewardEntry`,但**金币/钻石/资源走 Role 字段** | --- ## 3. 推荐实现路径(在 ROK 真相基础上) ### 3.1 包结构调整 **之前 openspec 规划**: ``` cn.etetet.hero # 英雄 cn.etetet.bag # 背包 + 装备 cn.etetet.gacha # 抽卡(ROK 无对应) ``` **根据调研推荐**: ``` cn.etetet.hero # 英雄养成(招募 / 升级 / 升星 / 技能 / 觉醒 / 天赋 / 战力) cn.etetet.bag # 背包 + 装备(装备是带 heroId 的 Item,不独立分包) # 锻造放 bag/Forge/ 子目录 cn.etetet.summon # 碎片召唤 RPC(薄薄一层,主要在 hero 内复用)— 可与 cn.etetet.hero 合并 cn.etetet.tavern # 酒馆宝箱(ROK 主要碎片来源)— P2/P3 视优先级 cn.etetet.gacha # 抽卡(独立扩展,非 ROK 移植)— P3+ 或后期 ``` 实际可以**合并**:把 summon 并到 hero 里、tavern 单独包(因为它是独立的 UI 入口 + Build_Tavern 协议)。 ### 3.2 阶段重排(基于 ROK 真相) | 阶段 | 目标 | 端到端验证 | |---|---|---| | **P0** | 基础设施(DB / 日志 / GM / 配置 / Luban / 协议) | Login Demo 通 | | **P1** | 英雄招募(碎片召唤 RPC) + 经验升级 + 通用 Item 增删 + 货币变动 | GM `AddItem 碎片 30` → `SummonHero heroId` → 英雄出现,升级 | | **P2** | 升星 + 技能升级 + 装备穿戴 + 战力计算(套装) | GM 完整养成链路 | | **P3** | 觉醒 + 天赋树 + 锻造(双段 RPC)+ 分解 | GM 全养成 + 装备产出闭环 | | **P3+** | 酒馆宝箱(ROK 主要碎片来源) + 雕像兑换 | UI 之前用 GM 验证酒馆 | | **P4** | UI 集中实现(YIUI Panel) | 全功能可视化 | | **P4+ / 可选** | **抽卡扩展**(非 ROK 移植,独立设计) | 用户验证产出 | --- ## 4. 实现时的"防走样"检查清单 每写一个业务函数前,**对照本索引文档 + 对应模块 spec**: - [ ] 数据字段名是否跟 ROK(如 `getItem` 不要写成 `fragmentItemId`) - [ ] RPC 个数是否对(如锻造 2 个不是 1 个) - [ ] 公式是否照 ROK(如战力公式参考 ROK-Hero-Spec §4.10) - [ ] 错误码段位是否对(3000-3027 Hero,6029-6031 BuildEquip) - [ ] 货币走 Role 字段 vs Item,分得清吗 - [ ] 装备槽位映射对吗(8 槽 / 6 subType,accessories 双槽) - [ ] 配置表字段全部翻译到 Luban 了吗(不要漏列) --- ## 5. 给用户的建议 ### 5.1 必须先做 1. **修正 openspec specs**:按本索引 §2 的差异表逐项修正 `hero-system/spec.md` / `bag-system/spec.md` / `equipment-system/spec.md` / `gacha-system/spec.md` 2. **调整 proposal.md**:抽卡定位明确为"独立扩展,非 ROK 移植" 3. **调整 tasks.md**:阶段重排(按本索引 §3.2),新增"召唤 + 酒馆"任务 4. **调整 design.md D2 包组织**:把 `cn.etetet.equip` 合并到 `cn.etetet.bag` ### 5.2 可以推迟(先不调整) - ROK 的`雕像兑换` / `天赋页改名` 等次要功能可放最后 - `酒馆宝箱` 可在 P3 才补(先用 GM `AddItem 碎片 N` 模拟产出) - 抽卡扩展先不做,P1-P3 用 ROK 原版机制(召唤)验证产出 ### 5.3 决策点请确认 | 决策点 | 选项 A | 选项 B | 推荐 | |---|---|---|---| | 货币是否进 Item | A. 跟 ROK:金/钻是 Player 字段 | B. 统一 Item:金/钻也是 itemId | **A**(与 ROK 一致,便于 1:1 迁移) | | 装备分包 | A. 跟 ROK:装备并入 Bag | B. 独立 `cn.etetet.equip` 包 | **A**(与 ROK 一致) | | 抽卡优先级 | A. P1 实现(用户要求) | B. P4+ 扩展(避免干扰 1:1 迁移) | **B**(先把 ROK 跑通,抽卡作为后续创新点) | | 召唤 + 酒馆放哪 | A. 合并到 hero 包 | B. 独立 `cn.etetet.tavern` 包 | **A 合并到 hero,酒馆 UI 时再独立** | 确认这些决策后,我可以动手按结论修正 openspec 全部文档。 --- ## 6. 用户最新决策与统一设计哲学(2026-05-27 确认) > 这一节是 ROK 调研之后用户拍板的设计原则。**与 ROK 部分实现细节不一致**,但作为 Survivors 工程的最终设计哲学,后续 openspec 修改必须以此为准。 ### 6.1 决策汇总 | # | 议题 | 决定 | 与 ROK 关系 | |---|---|---|---| | D1 | 货币管理 | **通用 Item**:金/钻/木/粮/碎片/英雄道具/装备/材料**全部** itemId 管理 | ✗ 与 ROK 不一致(ROK 把货币存 Role 字段) | | D2 | 装备分包 | **并入 `cn.etetet.bag`**(装备是带 heroId 的 Item) | ✓ 与 ROK 一致 | | D3 | 抽卡优先级 | **推迟 P4+**,先把 ROK 召唤+酒馆跑通 | — | | D4 | "抽卡 / 召唤" 重新定义 | **抽卡 = 酒馆开盲盒(ItemPackage 机制);召唤 = 英雄碎片 Item → 英雄 Entity 转化** | ✓ 本质与 ROK 一致,抽象更统一 | ### 6.2 核心抽象:**"一切皆 Item,开盲盒即抽卡"** #### 抽象 1:通用 Item | 范畴 | itemId 示例段位 | 例子 | |---|---|---| | 货币类 Item | 1xxxxx (跟 ROK itemId 编码) | itemId=1 金币 / itemId=2 钻石 / itemId=3 木料 / itemId=4 粮食 | | 资源道具袋 | 1xxxxxxx | 100 金币袋 / 1000 钻石袋(使用时扣道具+加货币 Item) | | 加速 / 增益 / 杂项 | 2xxx / 3xxx / 5xxx | 训练加速卷、迁城卡、经验书 | | 装备 / 材料 / 图纸 | 4xxx | 装备本体(`count=1`+`heroId>=0`)、材料、图纸 | | **英雄碎片** | 类似 ROK `getItem` 编码 | 招募关羽碎片 / 招募张飞碎片 | | **英雄 Item**(新增抽象) | 新增段位 | "直接获得 1 名关羽"道具,使用 → 转化为 Hero Entity | **统一接口**(服务端 `BagComponentSystem`): ```csharp // 任何业务发奖、扣资源都走这两个接口 AddItems(List rewards) RemoveItems(List costs) HasItems(List costs) GetItemCount(itemId) ``` #### 抽象 2:ItemPackage(开盲盒 / 抽卡 / 礼包统一模型) ``` 输入:消耗 CostEntry 列表 + 一个 packageId 内部:按 PackageConfig.weights 加权随机 输出:RewardEntry 列表(itemId, count)→ 调用 BagComponentSystem.AddItems ``` **ItemPackage 的具体业务化身**: | 业务 | 实现 = 一次 ItemPackage 调用 | |---|---| | 酒馆白银宝箱(ROK Build_Tavern silverBox) | 消耗:免费次数 or 银币 / 输出:silverBoxItemPackage 加权产出 | | 酒馆黄金宝箱(ROK Build_Tavern goldBox) | 消耗:钻石 / 输出:goldBoxItemPackage 加权产出 | | 邮件附件领取 | 消耗:0 / 输出:邮件配置的 RewardEntry 列表(无随机) | | 任务奖励 | 同上 | | 礼包道具使用(gift box) | 消耗:1 个礼包 Item / 输出:固定 / 加权 RewardEntry | | **未来"抽卡"扩展** | 消耗:抽卡券 or 钻石 / 输出:英雄碎片 / 英雄 Item / 资源等 | > **关键洞察**:上面 6 种业务**底层是同一个函数** `ItemPackageSystem.Open(rid, packageId)`,只是 UI 入口和配置不同。 #### 抽象 3:Item → Entity 转化("召唤"机制) ``` 玩家持有英雄碎片 Item(如关羽碎片 ×30)或英雄 Item(直接获得 1 名关羽) │ 调用 UseItem 协议 ▼ ItemUseHandler 分发(按 ItemDefine.useType / useScript) │ ▼ 对于"英雄碎片"类型 Item: - 校验数量足够(>= getItemNum) - 校验该 heroId 未被拥有 - HeroComponentSystem.CreateHero(heroId) - BagComponentSystem.RemoveItems(碎片 × getItemNum) 对于"英雄 Item"类型(直接给英雄): - 校验该 heroId 未被拥有 - HeroComponentSystem.CreateHero(heroId) - BagComponentSystem.RemoveItems(英雄 Item × 1) 对于"装备"类型 Item:不可使用(穿戴走另外的 RPC) 对于"经验书"类型 Item:调 HeroComponentSystem.AddExp 对于"金币袋"类型 Item:扣道具 + AddItem 金币 itemId ... 等 ``` > **关键洞察**:ROK 的"召唤" 在 Survivors 不需要独立 RPC,本质就是 **UseItem 协议** 的一个分支。 ### 6.3 包结构最终方案(基于 D1-D4 决策) ``` cn.etetet.bag # 核心:Item + RewardEntry + ItemPackage + Forge ├── Scripts/Model/Server/ │ ├── BagComponent.cs # 玩家背包 │ ├── ItemUnit.cs # 通用 Item 单元(含 heroId / exclusive 字段供装备用) │ ├── ItemPackageConfig.cs # ItemPackage 配置 │ └── CurrencyItemIds.cs # 货币 itemId 常量(1=金币 2=钻石 3=木料 ...) ├── Scripts/Hotfix/Server/ │ ├── BagComponentSystem.cs # AddItems / RemoveItems / HasItems / GetItemCount │ ├── ItemPackageSystem.cs # Open(packageId) 加权随机 → RewardEntry │ ├── ItemUseHandler.cs # UseItem 分发(按 useType) │ ├── Forge/ # 装备锻造子目录 │ └── UseHandlers/ # 各类道具使用 Handler(IItemUseHandler) │ ├── HeroFragmentUseHandler.cs # 英雄碎片 → 召唤 │ ├── HeroItemUseHandler.cs # 英雄 Item → 直接获得 │ ├── ExpBookUseHandler.cs # 经验书 → 英雄加经验 │ └── CurrencyBagUseHandler.cs # 金币袋 → 加货币 cn.etetet.hero # 英雄养成(升级 / 升星 / 技能 / 觉醒 / 天赋 / 装备穿戴 / 战力) ├── 没有"招募"RPC(招募通过 UseItem 触发,统一入口) cn.etetet.tavern # 酒馆(ItemPackage 的具体业务应用 + UI 入口) ├── Scripts/Hotfix/Server/ │ └── TavernSystem.cs # OpenSilverBox / OpenGoldBox(内部调 ItemPackageSystem.Open) (已删除:cn.etetet.gacha / cn.etetet.equip / cn.etetet.summon — 通通不需要) ``` ### 6.4 设计哲学相比 ROK 的"升级点" | 维度 | ROK 原版 | Survivors 升级 | 收益 | |---|---|---|---| | 货币管理 | Role 字段 + Item 双轨制 | 全部 Item(itemId 段位区分) | 接口统一,避免每种货币都写一遍 add/remove | | 道具使用 | ItemLogic 巨型 if/elseif | IItemUseHandler 注册机制 | 新增道具类型加一个 Handler 类,零修改老代码 | | 抽卡 / 宝箱 / 礼包 | 分散在 ItemLogic / Tavern / 各业务 | 统一 ItemPackage 机制 | 一处实现,N 处复用 | | 召唤 | 独立 Hero_SummonHero 协议 | UseItem 分支 | 协议数量减少,玩家行为路径统一 | ### 6.5 与 openspec 现有 spec 的对应调整(待用户读完文档后执行) | openspec 文档 | 主要修改 | |---|---| | `proposal.md` | 抽卡定位 → 推迟 P4+;新增 ItemPackage 抽象说明;包结构按 6.3 重写 | | `design.md` D2 | 包列表按 6.3;删 gacha/equip/summon | | `design.md` 新增 D14 | ItemPackage 设计;Item→Entity 转化机制 | | `specs/bag-system/spec.md` | 通用 Item 覆盖货币;新增 ItemPackage 章节;新增 ItemUseHandler 注册机制;装备并入此 spec(不再分文件) | | `specs/hero-system/spec.md` | 删"招募 RPC",改为"通过 UseItem 触发";字段名跟 ROK;战力公式引用 Doc/ROK-Hero-Spec.md | | `specs/equipment-system/spec.md` | **合并进 `specs/bag-system/spec.md` 作为子章节**("装备子系统");删独立文件 | | `specs/gacha-system/spec.md` | **删除**,被 ItemPackage 抽象替代;后续做扩展抽卡时再起新 change | | `tasks.md` | P0/P1 阶段重排;新增 ItemPackage 任务;新增 ItemUseHandler 注册任务;删独立 gacha/equip 任务 | --- ## 7. 调研未覆盖的次要功能(按需补充) 如有需要再单独调研: - `Build_Tavern` 协议详细(酒馆开宝箱完整流程) — 需要时去看 `proxy/Build.lua` `response.Tavern` - 雕像兑换 `Hero_ExchangeHeroItem` — `proxy/Hero.lua` - 行动力减免与技能关联 — `HeroLogic.lua` + 战斗服务器 - 限时礼包触发 `RechargeLogic.triggerLimitPackage` — 与英雄关联但非英雄本身 - 红点系统在客户端 — `BagProxy` PlayerPrefs 部分