Files
heros/assets/script/game/hero/BuffSystem_Maintainability.md
2025-10-17 00:29:34 +08:00

9.1 KiB
Raw Blame History

Buff 系统可维护性指南

🎯 系统设计目标

本 buff 系统的核心设计目标是:

  • 易于使用:简单直观的 API
  • 易于扩展:添加新 buff/debuff 无需修改核心代码
  • 易于维护:清晰的代码结构和注释
  • 类型安全TypeScript 完全类型检查
  • 性能优化:按需计算,无冗余处理

📊 系统架构

核心层次

配置层 (SkillSet.ts, HeroInfo)
    ↓
应用层 (addBuff, addDebuff)
    ↓
缓存层 (buffPerm, buffTemp, debuffPerm, debuffTemp)
    ├─ value (数值型)
    └─ ratio (百分比型)
    ↓
计算层 (recalculateAttrs)
    ↓
属性层 (Attrs[])

模块职责

模块 职责 修改频率
SkillSet.ts buff/debuff 配置 经常(添加新技能)
HeroInfo 英雄初始配置 不常
HeroViewComp.ts buff 系统核心 很少(修复 bug
Hero.ts 初始化调用 基本不变

🔧 扩展点分析

1. 添加新 Buff 最容易)

修改位置SkillSet.ts 技能配置

风险等级 无风险

// 只需添加到 buffs 数组
buffs: [
    { buff: Attrs.AP, BType: BType.VALUE, buV: 10, buC: 0, buR: 100 }
]
// 系统自动处理一切

验证

  • 选择有效的 Attrs
  • 设置有效的 BType
  • 测试属性是否正确应用

2. 添加新的 Debuff 类型( 很容易)

修改位置

  1. SkillSet.ts - DBuff enum
  2. SkillSet.ts - getAttrFieldFromDebuff() 映射表
  3. SkillSet.ts - 技能配置

风险等级 低风险

// 步骤 1: 添加类型
export enum DBuff {
    POISON = 20,  // 新增
}

// 步骤 2: 在 SkillSet.ts 中添加映射
export const getAttrFieldFromDebuff = (debuffType: DBuff): number => {
    const debuffAttrMap: Record<DBuff, number> = {
        // ... 现有映射 ...
        [DBuff.POISON]: Attrs.DEF,  // 中毒降低防御
    };
    // ... 其他代码 ...
}

// 步骤 3: 使用
debuffs: [
    { debuff: DBuff.POISON, BType: BType.VALUE, dev: 10, deC: 6, deR: 80 }
]

验证

  • DBuff 类型无冲突
  • 映射到有效的 Attrs
  • 测试效果是否正确

3. 修改核心计算逻辑(⚠️ 非常困难)

修改位置HeroViewComp.ts - recalculateAttrs()

风险等级 高风险

不建议修改的原因

  • 计算流程已经优化
  • 修改可能导致属性计算错误
  • 影响所有 buff/debuff 效果

如需修改

  • 先写单元测试
  • 验证各种 buff/debuff 组合
  • 检查边界条件(最小值、最大值)

📝 最佳实践

1. 添加新属性

如果需要添加新的角色属性:

// 1. 在 Attrs enum 中添加
export enum Attrs {
    // ... 现有属性 ...
    NEW_ATTR = 27,  // 新增
}

// 2. 在 getAttrs() 中初始化为 0
export const getAttrs = () => {
    let reAttrs = {};
    // ... 现有初始化 ...
    reAttrs[27] = 0;  // 新属性初始化
    return reAttrs;
};

// 3. 如果有初始值,在 recalculateAttrs() 中处理
this.Attrs[Attrs.NEW_ATTR] = this.base_new_attr || 0;

// 4. 如果需要限制范围,在 clampAttrs() 中添加
this.Attrs[Attrs.NEW_ATTR] = Math.max(min, Math.min(max, this.Attrs[Attrs.NEW_ATTR]));

// 5. 在技能配置中使用
buffs: [
    { buff: Attrs.NEW_ATTR, BType: BType.VALUE, buV: 5, buC: 0, buR: 100 }
]

2. 修改 Buff 计算方式

如果需要修改百分比计算基数:

// 当前:百分比基于基础属性
const baseVal = baseValues[buff.buff] || this.Attrs[buff.buff];
this.Attrs[buff.buff] += Math.floor(baseVal * (buff.buV / 100));

// 可选:基于当前属性
const currentVal = this.Attrs[buff.buff];
this.Attrs[buff.buff] += Math.floor(currentVal * (buff.buV / 100));

// 可选:自定义计算
// ... 自定义逻辑 ...

3. 添加条件 Buff

如果需要条件触发的 buff仅在特定情况下生效

// 方案 1在 addBuff 前判断
if (someCondition) {
    heroView.addBuff(buffConf);
}

// 方案 2扩展 BuffConf 接口(需要修改 SkillSet.ts
interface BuffConfWithCondition extends BuffConf {
    condition?: () => boolean;
}

// 方案 3在技能中判断
const skillBuff = skillConf.buffs[0];
if (shouldApplyBuff(skillBuff)) {
    heroView.addBuff(skillBuff);
}

🧪 测试清单

单元测试(推荐)

describe('Buff System', () => {
    let hero: HeroViewComp;

    beforeEach(() => {
        hero = new HeroViewComp();
        hero.initBuffsDebuffs();
    });

    test('数值型 buff 应用', () => {
        const before = hero.Attrs[Attrs.AP];
        hero.addBuff({
            buff: Attrs.AP,
            BType: BType.VALUE,
            buV: 10,
            buC: 0,
            buR: 100
        });
        expect(hero.Attrs[Attrs.AP]).toBe(before + 10);
    });

    test('百分比型 buff 应用', () => {
        const baseAP = hero.base_ap;
        hero.addBuff({
            buff: Attrs.AP,
            BType: BType.RATIO,
            buV: 20,
            buC: 0,
            buR: 100
        });
        const expected = Math.floor(baseAP * 1.2);
        expect(hero.Attrs[Attrs.AP]).toBe(expected);
    });

    test('临时 buff 应过期', () => {
        hero.addBuff({
            buff: Attrs.AP,
            BType: BType.VALUE,
            buV: 10,
            buC: 1  // 1 秒
        });
        
        hero.updateTemporaryBuffsDebuffs(1.1);  // 超过 1 秒
        
        // buff 应被移除,属性恢复
        expect(hero.Attrs[Attrs.AP]).toBe(hero.base_ap);
    });

    test('debuff 正确映射', () => {
        hero.addDebuff({
            debuff: DBuff.SLOW,
            BType: BType.RATIO,
            dev: 50,
            deC: 0,
            deR: 100
        });
        
        // SLOW 应映射到 Attrs.AS
        const expected = Math.floor(hero.base_ap * 0.5);
        expect(hero.Attrs[Attrs.AS]).toBeLessThan(100);
    });
});

集成测试

// 测试完整的技能应用流程
test('技能应用完整流程', () => {
    const skillId = 6001;
    const skill = SkillSet[skillId];
    
    const hero = new HeroViewComp();
    hero.initBuffsDebuffs();
    
    // 应用技能
    for (const buff of skill.buffs) {
        hero.addBuff(buff);
    }
    for (const debuff of skill.debuffs) {
        hero.addDebuff(debuff);
    }
    
    // 验证属性正确应用
    // ...
    
    // 验证临时效果正确过期
    // ...
});

🚀 性能优化建议

当前优化

  • 按需计算(不是每帧)
  • 缓存分离(持久/临时)
  • 类型分离(数值/百分比)
  • 批量处理(临时过期时一次重算)

未来优化方向

  1. Buff 去重

    • 相同 buff 只计算一次
  2. 缓存预热

    • 英雄加载时预计算
  3. 异步处理

    • 大量 buff 变动时异步计算

📋 维护检查清单

月度检查

  • 检查 console 是否有 buff 相关的 warning
  • 验证新增技能的 buff/debuff 配置
  • 检查属性计算是否正确

季度检查

  • 审查 DBuff 映射表是否完整
  • 检查是否有重复或冲突的 buff/debuff
  • 验证系统性能buff 数量、计算次数)

年度检查

  • 评估系统是否需要重构
  • 考虑是否需要添加新的系统特性
  • 检查是否有安全漏洞

🐛 常见问题排查

症状 1: Buff 没有效果

排查步骤

  1. 检查 Attrs 是否有效 → console.log(Attrs.AP)
  2. 检查 BuffConf 是否正确 → console.log(buffConf)
  3. 检查 addBuff 是否调用 → 添加 log
  4. 检查 recalculateAttrs 是否执行 → 添加 log
  5. 检查最终属性值 → console.log(heroView.Attrs)

症状 2: Debuff 报错

排查步骤

  1. 检查 console 是否有 warning
  2. 查看 DBuff 是否在 enum 中定义
  3. 查看是否在 debuffAttrMap 中有映射
  4. 验证映射的 Attrs 是否有效

症状 3: 属性值异常

排查步骤

  1. 检查基础属性是否正确初始化
  2. 检查百分比计算公式
  3. 检查 clampAttrs 中的限制是否合理

📞 获取技术支持

如果遇到问题:

  1. 检查日志

    • 查看 console 是否有 warning
    • 检查 HeroViewComp 的 log
  2. 查阅文档

    • BuffSystem_QuickRef.md - 快速查找
    • BuffSystem_Guide.md - 详细说明
    • BuffSystem_Extension.md - 扩展方法
  3. 查看源码

    • HeroViewComp.ts - 核心实现
    • 代码中的详细注释
  4. 调试技巧

    • 添加 console.log 追踪执行
    • 使用浏览器开发者工具
    • 逐步调试跟踪变量值

🏆 系统特点总结

特性 评级 说明
易用性 简单直观的 API
可扩展性 添加新 buff/debuff 无需修改核心
可维护性 清晰的结构,充分的注释
性能 按需计算,高效处理
类型安全 完全 TypeScript 类型检查

系统已准备好长期维护和扩展! 🎉