docs: add skill template refactor design and migration plan docs

新增技能基座重构的设计文档和完整迁移计划文档,包含新的接口定义、配置结构、运行时参数解析逻辑以及分步迁移验证方案,为后续技能系统重构提供完整的设计指导。
This commit is contained in:
walkpan
2026-05-22 10:22:33 +08:00
parent c96eac9bac
commit eae62f245a
2 changed files with 794 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
# 技能基座重构 — 迁移计划
基于 spec: `docs/superpowers/specs/2026-05-22-skill-template-refactor-design.md`
## 迁移原则
- 每个步骤是**最小功能单元**,完成后可独立验证
- 使用**兼容层**过渡:新旧接口并存期间,代码同时读取两个位置
- 验证方式:每步完成后运行游戏,确认技能系统行为不变
---
## Phase 1类型定义零风险不改行为
### Step 1.1:新增 SkillTemplate/SkillDefaults/HeroOverrides 接口
**文件**`SkillSet.ts`
**改动**
- 在现有 `SkillConfig` 下方新增 `SkillTemplate``SkillDefaults``HeroOverrides` 接口定义
- 新增 `TriggerSkillConf` 接口
- 更新 `BuffConf`:新增 `attr` 字段,保留旧 `buff` 字段(标注 `@deprecated`
- 不删除任何旧代码
**验证**:编译通过,游戏行为不变(新接口尚未被使用)
### Step 1.2:新增 resolveSkillParams 工具函数
**文件**`SkillSet.ts` 或新建 `SkillResolve.ts`
**改动**
```typescript
export function resolveSkillParams(
template: SkillTemplate,
heroSkill?: HSkillInfo,
triggerConf?: TriggerSkillConf
): { kind: SkillKind } & SkillDefaults {
return {
kind: template.kind,
...template.defaults,
...heroSkill?.overrides,
...triggerConf?.overrides,
};
}
```
**验证**:编译通过,写一个简单的测试用例验证三级覆盖逻辑
---
## Phase 2兼容层数据迁移的安全网
### Step 2.1:新增兼容读取函数
**文件**`SkillSet.ts`
**改动**:新增辅助函数,从旧 `SkillConfig` 构造 `SkillTemplate` + `SkillDefaults`
```typescript
/** 从旧 SkillConfig 提取 defaults 字段(过渡期使用) */
export function legacyDefaults(config: SkillConfig): SkillDefaults {
return {
TGroup: config.TGroup,
ap: config.ap,
t_num: 1, // 旧配置无此字段,使用默认值
hit_count: config.hit_count,
hitcd: config.hitcd,
crt: config.crt,
frz: config.frz,
bck: config.bck,
buffs: config.buffs,
};
}
/** 从旧 SkillConfig 提取 template 字段 */
export function legacyTemplate(config: SkillConfig): SkillTemplate {
return {
uuid: config.uuid,
name: config.name,
sp_name: config.sp_name,
icon: config.icon,
kind: config.kind ?? SkillKind.Damage,
act: config.act,
readyAnm: config.readyAnm,
endAnm: config.endAnm,
EAnm: config.EAnm,
DAnm: config.DAnm,
ready: config.ready,
IType: config.IType,
RType: config.RType,
EType: config.EType,
speed: config.speed,
DTType: config.DTType,
with: config.with,
bezier_start_y: config.bezier_start_y,
bezier_mid_y: config.bezier_mid_y,
bezier_arc: config.bezier_arc,
time: config.time,
defaults: legacyDefaults(config),
info: config.info,
};
}
```
**验证**:编译通过,可写测试验证提取结果与原配置一致
---
## Phase 3数据迁移逐个技能类型
### Step 3.1:迁移 buff 技能数据6401-6406, 6501
**文件**`SkillSet.ts`
**改动**:将 6401-6406、6501 从 `SkillConfig` 格式改为 `SkillTemplate` 格式:
- 顶层数值字段 → `defaults`
- 显式添加 `kind: SkillKind.Support`
- `buffs` 中的 `buff:``attr:`
**存储方式**:新增 `BuffSkillTemplates: Record<number, SkillTemplate>`,旧数据保留在 `SkillSet`
**验证**:游戏运行,确认卡牌释放 buff 技能效果不变
### Step 3.2迁移辅助技能数据6301-6305
**文件**`SkillSet.ts`
**改动**:将护盾/治疗技能从旧格式改为 `SkillTemplate` 格式
- 护盾类:`kind: SkillKind.Shield`
- 治疗类:`kind: SkillKind.Heal`
**存储方式**:新增 `SupportSkillTemplates: Record<number, SkillTemplate>`,旧数据保留
**验证**:游戏运行,确认护盾和治疗技能效果不变
### Step 3.3迁移必杀技数据6104-6107
**文件**`SkillSet.ts`
**改动**:将必杀技从旧格式改为 `SkillTemplate` 格式
- 全部 `kind: SkillKind.Damage`
- `crt`/`frz` 移入 defaults
**验证**:游戏运行,确认必杀技伤害和特效不变
### Step 3.4迁移基础攻击技能数据6001-6103
**文件**`SkillSet.ts`
**改动**:将所有攻击技能从旧格式改为 `SkillTemplate` 格式
- 全部 `kind: SkillKind.Damage`
**验证**:游戏运行,确认所有英雄和怪物的普攻、远程攻击正常
### Step 3.5:合并为新表
**文件**`SkillSet.ts`
**改动**:将分散的 `BuffSkillTemplates``SupportSkillTemplates` 等合并为一个:
```typescript
export const SkillTemplates: Record<number, SkillTemplate> = { ... ... }
```
**验证**:通过所有新模板创建技能,确认与旧 `SkillSet` 行为一致
---
## Phase 4消费者适配逐文件
### Step 4.1:适配 Skill.ts技能实体创建
**文件**`assets/script/game/skill/Skill.ts`
**改动**
- `skill.load()` 参数从 `config: SkillConfig` 改为 `template: SkillTemplate`
- 内部读取 `template.sp_name`(表现字段,未变)
- 传递给 SMoveSystem/STimeComp 的 config 改为 template
- `ap`/`crt`/`frz`/`hit_count``template.defaults` 读取(通过兼容函数)
**关键行**
- ~112: `config.sp_name``template.sp_name`
- ~153: `config.EType``template.EType`
- ~181: `config.RType``template.RType`
- ~183-185: `config.bezier_*``template.bezier_*`
- ~195: `config.time``template.time`
- ~196: `config.hitcd``template.hitcd`
- ~211-214: `config.crt`/`config.frz`/`config.ap`/`config.hit_count``template.defaults.*`
**验证**:释放各种技能,确认弹道动画和伤害数值正确
### Step 4.2:适配 SMoveSystem.ts技能移动
**文件**`assets/script/game/skill/SMoveSystem.ts`
**改动**
- 类型引用 `SkillConfig``SkillTemplate`
- 读取的字段speed、RType、EType、bezier_*)均在模板顶层,无需改逻辑
**验证**:确认弹道轨迹(直线/贝塞尔/固定)正常
### Step 4.3:适配 STimeComp.ts技能时间控制
**文件**`assets/script/game/skill/STimeComp.ts`
**改动**
- 类型引用 `SkillConfig``SkillTemplate`
- 只读 `EType`(模板顶层字段),逻辑不变
**验证**:确认技能持续时间、碰撞消失逻辑正常
### Step 4.4:适配 SkillView.ts技能视图
**文件**`assets/script/game/skill/SkillView.ts`
**改动**
- 类型引用 `SkillConfig``SkillTemplate`
- 只读 `EType`(模板顶层字段),逻辑不变
**验证**:确认技能特效显示正常
### Step 4.5:适配 HeroViewComp.ts命中动画
**文件**`assets/script/game/hero/HeroViewComp.ts`
**改动**
- ~507: `SConf?.DAnm``template?.DAnm`(字段仍在顶层,只改引用名)
**验证**:确认受击动画(普通/冰/火/风)显示正确
### Step 4.6:适配 SCastSystem.ts施法系统 — 核心)
**文件**`assets/script/game/hero/SCastSystem.ts`
**改动**
- 引入 `resolveSkillParams()``legacyTemplate()`
- `forceCastSkill()``SkillSet[s_uuid]``SkillTemplates[s_uuid]`,通过 `resolveSkillParams(template, undefined, undefined)` 获取参数
- `applyFriendlySkillEffects()` 改为接收 resolved params
- `applyActualFriendlyEffect()` 中:
- `config.buffs``resolved.buffs`
- `buffConf.buff``buffConf.attr`(同时兼容旧 `buff` 字段)
- 伤害技能路径中 `config.ap`/`config.crt`/`config.frz`/`config.hit_count` → 从 resolved params 读取
- `config.TGroup``resolved.TGroup`
- `config.kind``template.kind`(模板固定)
**验证**
1. 英雄普攻伤害正确
2. 必杀技伤害和特效正确
3. 护盾/治疗/buff 效果正确
4. 卡牌技能效果正确
### Step 4.7:适配 HeroAtkSystem.ts伤害系统
**文件**`assets/script/game/hero/HeroAtkSystem.ts`
**改动**
- ~292: `sConf.ap` → 从 resolved defaults 读取
- ~221: `reviveSkillConf.ap` → 从 resolved defaults 读取
- ~236: `reviveSkillConf.readyAnm` → 从 template 读取(模板顶层字段)
**验证**
1. 英雄伤害数值正确
2. 复活技能恢复血量正确
### Step 4.8:适配 SkillTriggerHelper.ts触发技能
**文件**`assets/script/game/hero/SkillTriggerHelper.ts`
**改动**
- 触发技能时,将 `triggerConf.overrides` 传递给 `resolveSkillParams()`
**验证**:确认受击触发护盾、普攻触发治疗等触发技能正常
### Step 4.9:适配 Hero.ts + Mon.ts初始化
**文件**`Hero.ts``Mon.ts`
**改动**
- 英雄/怪物初始化时,将 `heroInfo.atking`/`atked` 等配置传入 HeroAttrsComp
- HeroAttrsComp 中的类型同步更新为 `TriggerSkillConf[]`
**验证**:英雄和怪物的触发技能正常工作
### Step 4.10:适配显示层文件
**文件**`CardComp.ts``IBoxComp.ts``TooltipCom.ts``SIconComp.ts``SkillBoxComp.ts``HlistComp.ts`
**改动**
- 仅引用名变更(`SkillConfig``SkillTemplate`
- 读取的字段name、icon、IType、info均在模板顶层无需改逻辑
**验证**:卡牌显示、信息面板、技能图标显示正常
---
## Phase 5角色定制新功能启用
### Step 5.1:更新 heroSet.ts 触发配置类型
**文件**`heroSet.ts`
**改动**
- `atking`/`atked` 等类型从 `{s_uuid, t_num}` 内联 → `TriggerSkillConf[]`
- 向后兼容:`overrides` 可选,旧配置无需修改
**验证**:编译通过,游戏行为不变(尚未添加 overrides
### Step 5.2:为首个角色添加 overrides
**文件**`heroSet.ts`
**改动**:选一个典型角色(如盾骑士 5002作为试点为其触发技能添加 overrides
```typescript
5002: {
...,
atked: [{ s_uuid: 6301, t_num: 2,
overrides: { TGroup: TGroup.Team, ap: 2, t_num: 5, hit_count: 3 }
}],
},
```
**验证**:盾骑士受击后给全队加盾,而非只给自己加。对比修改前后行为确认覆盖生效
### Step 5.3:逐步为其他角色添加 overrides
**文件**`heroSet.ts`
**改动**:逐个角色添加 overrides每添加一个验证一次
**验证**:每个角色的技能行为符合设计意图
---
## Phase 6清理
### Step 6.1:删除旧 SkillConfig 接口和 SkillSet 数据
**文件**`SkillSet.ts`
**改动**
- 删除 `SkillConfig` 接口
- 删除旧 `SkillSet` 数据(已被 `SkillTemplates` 替代)
- 删除 `legacyTemplate()`/`legacyDefaults()` 兼容函数
- `SkillTemplates` 重命名回 `SkillSet`(或保持新名,全局替换引用)
**验证**:全面回归测试
### Step 6.2BuffConf 清理
**文件**`SkillSet.ts``SCastSystem.ts`
**改动**
- 删除 `BuffConf.buff` 字段,只保留 `attr`
- 所有配置数据中 `buff:``attr:`
**验证**buff 技能效果正确
### Step 6.3:删除 kind 回退逻辑
**文件**`SCastSystem.ts`
**改动**
- 移除 `config.kind ?? SkillKind.Damage``config.kind ?? SkillKind.Support` 回退
- 全部使用 `template.kind`
**验证**:所有技能类型判定正确
---
## 验证检查清单
每个 Step 完成后,运行以下检查:
| 检查项 | 方法 |
|--------|------|
| 编译通过 | 无 TypeScript 错误 |
| 普攻正常 | 放置近战/远程英雄,观察普攻弹道和伤害 |
| 必杀技正常 | 触发必杀技,确认特效和伤害 |
| 护盾正常 | 触发护盾技能,确认护盾层数和显示 |
| 治疗正常 | 触发治疗技能,确认血量恢复 |
| Buff 正常 | 触发 buff 技能,确认属性变化 |
| 卡牌技能正常 | 使用卡牌释放各种技能 |
| 触发技能正常 | 受击/攻击/死亡/开始触发链正常 |
| 怪物行为正常 | 怪物攻击和技能释放正常 |
| 无控制台报错 | 检查浏览器控制台无 JS 错误 |