Files
pixelheros/put/server/data/heroes.json编辑指引.md
panFD 0066faea1e docs(heroes): add manual editing guide for heroes.json
补充英雄数据库JSON文件的手动修改规范文档,包含数据源说明、字段规则、操作流程和常见错误规避方法,方便无UI场景下直接编辑调整英雄配置。
2026-09-06 21:34:21 +08:00

121 lines
8.2 KiB
Markdown
Raw 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.
# heroes.json 手动修改指引(智能体用)
> 本文件是 `put/server/data/heroes.json`(英雄编辑器数据库)的手动修改规范。
> 适用场景:不启动编辑器 UI,直接修改 JSON 新增/调整英雄。
> 规则与说明 only —— 所有底座数值请以「数据源」所列真实配置文件为准,禁止凭记忆填写。
## 0. 数据源(修改前必读,唯一事实源)
| 要什么 | 读哪里 |
|---|---|
| 技能底座(普攻/大招/辅助,含 kind/TGroup/默认数值) | `assets/script/game/common/config/SkillSet.ts` → `SkillSet` |
| 驻场光环底座(类型/图标/元数据) | 同文件 → `FieldSkillSet` |
| 计时 buff(timed_buff_id 可用值与效果) | `assets/script/game/common/config/BuffSet.ts` → `BuffList` |
| 职业属性模板 / 成长系数 / lv12 专项 | `assets/script/game/common/config/heroSet.ts` → `HERO_ROLE_BASE` / `HERO_GROW_COEF` / `HERO_LV12_SPECIAL_ATTR` |
| 攻速档位表达式 | 同文件 → `AtkSpeedSet` / `AtkSpeedLv` |
| 现有英雄写法样例 | 本 JSON 内 5001~5010 条目 |
| 编辑器枚举键(职业/成长/类型/底座映射) | `put/web/src/constants.js`(`HERO_ROLES` / `GROW_TYPES` / `H_TYPES` / `ROLE_ATK_SKILL` / `ROLE_ULT_SKILL` / `SUPPORT_ULT` / `OVERRIDE_KEYS`) |
服务端运行时可 `GET /api/meta` 获取底座快照(需先启动 server);修改 SkillSet 等 TS 后需 `POST /api/refresh` 或重启。
## 1. 文件角色与数据流
- 本文件是**编辑器数据库**:编辑器"保存"即全量覆盖写本文件;手动改本文件与编辑器保存等价。
- `POST /api/apply` 把本文件**全部条目**渲染成 TS,整体替换 `heroSet.ts` 中
`// @hero-setup:heroes-begin` ~ `// @hero-setup:heroes-end` 之间的英雄区。
- 推论:
- 不要手改 heroSet.ts 英雄区 —— 下次 apply 会被覆盖;
- 新增一条英雄 = 在本 JSON 数组追加一个对象,然后 apply;
- 标记区之外的 `HeroList`、`HeroComboSet`、怪物配置不受 apply 影响。
## 2. 英雄对象字段规范
| 字段 | 类型 | 规则 |
|---|---|---|
| `uuid` | number | 英雄 5000 段,全局唯一。当前已用 5001~5010,新增从 **5011** 起(修改前 grep 全库确认未占用) |
| `name` / `comment` | string | 显示名 / 设计说明(comment 可空,建议填写机制主题) |
| `path` | string | 美术资源名,必须存在 `assets/resources/game/heros/{path}.prefab`(修改前用文件系统确认) |
| `rarity` | 1~5 | 仅缩放 lv1 基础属性 ×(1+0.05×(rarity−1));卡池费用 5/10/15、抽卡权重 40/25/15/8/3 自动派生 |
| `roleKey` | string | 职业:`Tank`/`Warrior`/`Assassin`/`Archer`/`Mage`/`Support` |
| `growKey` | string | 成长曲线:`Tank`/`Warrior`/`Assassin`/`Mage`/`Support`/`Archer`,通常与 roleKey 同职业 |
| `typeKey` | string | 攻击定位:`Melee`/`Mid`/`Long`(决定默认攻击距离 100/300/450) |
| `statBase` | {hp,ap,def} | 相对 `HERO_ROLE_BASE[roleKey]` 的**偏移量**(可为负,如 5007 hp=−5);惯例量级 ±5/10/20/30 |
| `dis` / `speed` | number\|null | 英雄一般 null(走默认);显式配置才填 |
| `skills` | array | **恰好 2 个**:`[普攻, 大招]`,结构见 §3 |
| `atking`/`atked`/`fstart`/`dead` | object | 触发组,结构见 §4 |
| `field` | array | 驻场光环档位,结构见 §5 |
| `ap_bonus`/`hp_bonus`/`def_bonus` | array | 一次性属性奖励 `[{lv,value}]`,运行时累加 ≤英雄等级的档;常规英雄留空 |
| `info` | string | 描述文案,可空 |
| `revive` | — | **已废弃**:复活改在 `dead` 组 overrides 里配 `revive_hp`/`revive_count`,不要写独立字段 |
## 3. skills 规范
每个技能对象:`{uuid, name, cd, cdExpr, overrides, desc, lv_entries}`。
**普攻 skills[0]**
- `uuid` 必须 ∈ `ROLE_ATK_SKILL[roleKey]`;
- `cdExpr` = `"AtkSpeedSet[AtkSpeedLv.<SpeedKey>].cd"`(SpeedKey ∈ VeryFast/Fast/Normal/Slow/VerySlow),`cd` 填对应数值(0.75/0.90/1.05/1.20/1.50);
- `lv_entries` 惯例只有一档:`{lv:2, s_lv:2, overrides, desc}`。
**大招 skills[1]**
- `uuid` ∈ `ROLE_ULT_SKILL[roleKey]`;辅助类底座(`SUPPORT_ULT` 列表)任意职业可作大招;
- `cd: 8`、`cdExpr: null`;
- `lv_entries` 两档:`{lv:8, s_lv:2, ...}`、`{lv:16, s_lv:3, ...}`。
**通用**
- `name` 留空则回退 SkillSet 底座名;建议普攻/大招起特色名;
- `desc` 为描述模板,占位符 `{target}` `{ap}` `{dur}` `{技能字段名}` 由 HeroSkillText 渲染实时数值;空字符串等价省略;
- 档位 `overrides` 与基础 `overrides` **浅合并**(档位优先),档位只写变化键。
## 4. 触发组规范(atking / atked / fstart / dead)
- 结构:`{ "<技能uuid字符串>": [条目, ...] }`,一个组可挂多个技能 uuid;
- 条目:`{lv, s_lv, name, t_num, overrides, desc}`;
- 解锁等级惯例 **lv4**(`lv:4, s_lv:1`;heroSet.ts 头部注释写的 lv6 已过时,现有英雄与编辑器默认值均为 lv4);
- `t_num`:每 n 次普攻(atking)/受击(atked)触发一次;
- `name` 为组对外展示名(写在该组首档),留空回退底座名;
- 复活:在 `dead` 某条目 `overrides` 配 `revive_hp`(回血%)+ `revive_count`(次数上限);
- 无触发组时写空对象 `{}`,**不要省略字段**。
## 5. field 光环规范
- 结构:`[{lv:4, uuids:[{uuid, value, name}], desc?}]`;
- `uuid` 必须 ∈ `FieldSkillSet`(7001~7022 段);`value` 为实际生效数值(按光环类型:比例类为小数如 0.15,次数/固定值类为整数);
- `name` 可空(回退底座名);`desc` 可空(回退自动生成);
- 解锁等级惯例 lv4;无光环写空数组 `[]`。
## 6. overrides 白名单与特殊存储格式
可用键(对照 `SkillSet.ts` 的 `SkillOverrides` 接口;编辑器 UI 白名单 `OVERRIDE_KEYS` 是其子集,手动改 JSON 可用全集):
`ap, hit_count, hitcd, crt, frz, stun, para, bck, bck_chance, TGroup, buff_type, timed_buff_id, buff_value, buff_duration, buff_chance, buff_target, call_hero, summon_count, is_accel, num, revive_hp, revive_count, proc_skill, icon`
特殊存储格式(导出时由 server 还原为 TS 枚举表达式):
- `TGroup`:JSON 存字符串(如 `"Team"`),导出还原 `TGroup.Team`;`null` 表示不覆写;
- `buff_target`:存数字 0~3(Hit/Self/Ally/Enemy),导出还原 `BuffTarget.X`;
- `proc_skill`:对象 `{s_uuid, chance?, overrides?}`(命中后概率触发另一技能);
- `icon`:字符串图标帧名(uicons 图集),非数值;
- 其余一律直存数值。
引用校验:`timed_buff_id` 必须 ∈ `BuffList`;`proc_skill.s_uuid` / 触发组 key / 召唤类引用必须 ∈ `SkillSet`。
## 7. 新增英雄操作清单
1. 读 §0 数据源:选定技能/光环/buff 底座,确认 `HERO_ROLE_BASE` 模板值与攻速档位;
2. 选 uuid(≥5011 且全库唯一)、选 `path`(确认 prefab 存在);
3. 在本 JSON `heroes` 数组**末尾**追加完整英雄对象(所有字段齐全,空组写 `{}`/`[]`);
4. JSON 语法校验(如 `node -e "JSON.parse(require('fs').readFileSync('put/server/data/heroes.json','utf8'))"`);
5. 启动服务 `npm run dev`(put 目录),`POST /api/apply` 写入 heroSet.ts;
6. **手动把新 uuid 追加进 `heroSet.ts` 的 `HeroList`**(标记区之外,apply 不会代做 —— 最易漏的一步,漏了英雄不进卡池、游戏不加载);
7. 验证:编辑器 UI 重开确认渲染正常;游戏内抽卡/面板检查;必要时用 `calcHeroPowerNormalized`(基准 5001=100 分)评估强度。
## 8. 常见错误
- 手改 heroSet.ts 英雄区 → 被下次 apply 覆盖;
- 漏加 `HeroList` → 英雄存在但不可获得;
- 引用不存在的技能/光环/buff uuid 或 `path` → 编译或运行期才爆;
- 写独立 `revive` 字段 → 已废弃,复活走 dead 组;
- 触发技/光环解锁写 lv6、大招档位写 lv9 → 现行惯例 lv4 / lv8+lv16;
- 普攻用数值 cd 而不给 `cdExpr` → 丢失攻速档位语义(编辑器攻速下拉失效);
- 档位 overrides 全量复制基础档 → 浅合并下冗余且后续改基础值不生效;
- desc 与 overrides 数值脱节 → desc 模板只写 `{ap}` 等占位符,不要硬编码数字。