XtGameKit/Doc/ROK-Spec-Index.md

20 KiB
Raw Permalink Blame History

ROK 业务规则总索引1:1 迁移依据)

来源:E:\Game\gmd\ROK 服务端 Lua + 客户端 C# + sproto 协议 用途:移植到 Survivors 工程前的业务规则全摊牌,实现时禁止凭空发挥 调研日期2026-05-27


0. 四份文档清单

# 文档 大小 摘要
1 ROK-Hero-Spec.md 70K / 1362 行 英雄系统完整业务(招募 / 升级 / 升星 / 技能 / 觉醒 / 天赋 / 装备 / 战力 / 排序 / 同步部队)
2 ROK-Bag-Spec.md 48K / ~770 行 背包系统(道具 6 大类 / itemId 编码 / 增删使用 / 礼包 / 资源货币机制)
3 ROK-HeroAcquire-Spec.md 34K / 456 行 英雄获取链路(ROK 无抽卡,是宝箱+碎片+主动召唤)
4 ROK-Equip-Spec.md 25K 装备系统8 槽位 / 锻造双段 RPC / 分解 / 套装 / 材料合成)

1. 四个核心架构结论(必读)

结论 1ROK 没有抽卡,是"宝箱产出碎片 + 主动碎片召唤"两段式

酒馆宝箱(白银 / 黄金 / 免费 + 付费)
   │  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

维度 真相
装备的存储 背包 ItemUnitcount=1heroId>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 subTypeaccessories 双槽共享,需修正
  • ⚠️ 之前漏写 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 map1/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 subTypeaccessories 双槽共享) 修正映射
锻造 单 RPC 双 RPCCheckMakeEquip + 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 碎片 30SummonHero heroId → 英雄出现,升级
P2 升星 + 技能升级 + 装备穿戴 + 战力计算(套装) GM 完整养成链路
P3 觉醒 + 天赋树 + 锻造(双段 RPC+ 分解 GM 全养成 + 装备产出闭环
P3+ 酒馆宝箱ROK 主要碎片来源) + 雕像兑换 UI 之前用 GM 验证酒馆
P4 UI 集中实现YIUI Panel 全功能可视化
P4+ / 可选 抽卡扩展(非 ROK 移植,独立设计) 用户验证产出

4. 实现时的"防走样"检查清单

每写一个业务函数前,对照本索引文档 + 对应模块 spec

  • 数据字段名是否跟 ROKgetItem 不要写成 fragmentItemId
  • RPC 个数是否对(如锻造 2 个不是 1 个)
  • 公式是否照 ROK如战力公式参考 ROK-Hero-Spec §4.10
  • 错误码段位是否对3000-3027 Hero6029-6031 BuildEquip
  • 货币走 Role 字段 vs Item分得清吗
  • 装备槽位映射对吗8 槽 / 6 subTypeaccessories 双槽)
  • 配置表字段全部翻译到 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

// 任何业务发奖、扣资源都走这两个接口
AddItems(List<RewardEntry> rewards)
RemoveItems(List<CostEntry> costs)
HasItems(List<CostEntry> costs)
GetItemCount(itemId)

抽象 2ItemPackage开盲盒 / 抽卡 / 礼包统一模型)

输入:消耗 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 入口和配置不同。

抽象 3Item → 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/               # 各类道具使用 HandlerIItemUseHandler
│       ├── 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 双轨制 全部 ItemitemId 段位区分) 接口统一,避免每种货币都写一遍 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_ExchangeHeroItemproxy/Hero.lua
  • 行动力减免与技能关联 — HeroLogic.lua + 战斗服务器
  • 限时礼包触发 RechargeLogic.triggerLimitPackage — 与英雄关联但非英雄本身
  • 红点系统在客户端 — BagProxy PlayerPrefs 部分