XtGameKit/Doc/ROK-Spec-Index.md

377 lines
20 KiB
Markdown
Raw Permalink 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.

# 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 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 碎片 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 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`
```csharp
// 任何业务发奖、扣资源都走这两个接口
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_ExchangeHeroItem``proxy/Hero.lua`
- 行动力减免与技能关联 — `HeroLogic.lua` + 战斗服务器
- 限时礼包触发 `RechargeLogic.triggerLimitPackage` — 与英雄关联但非英雄本身
- 红点系统在客户端 — `BagProxy` PlayerPrefs 部分