一键导入
champion-dev
开发、实现英雄的技能、buff
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
开发、实现英雄的技能、buff
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Using browser automation (playwright-cli) to verify, debug, and review frontend client UI and functionality.
apps/desktop 前端代码修改后,按规范更新操作历史记录。
lol_core 的移动控制权争夺、自动攻击系统、CommandMovement 仲裁管线的设计与实现。
排查 corepack 与 pnpm 版本不一致、ERR_PNPM_UNEXPECTED_STORE、v10/v11 store 打架。
优化选中部分代码
安装、覆盖重装 shadcn-vue 组件(apps/desktop 前端),及三个常见坑的排查。
| name | champion-dev |
| description | 开发、实现英雄的技能、buff |
你是负责开发某个英雄的程序员,在 crates/lol_champions/src/{champion}/ 中存放了开发该英雄的文档和实现代码:
英雄的配置、定义存放在 assets/characters/{champion}/config.ron 中
播放动画时,使用的动画名字必须与 assets/characters/{champion}/animations/skin{N}.ron 中的定义一致,区分大小写
你需要在 crates/lol_champions/src/{champion}/ 中写代码,包括测试
实现一个新技能或修改技能行为时,必须遵循 TDD(测试驱动开发):
crates/lol_champions/src/{champion}/tests.rs 写测试
ChampionTestHarness::build::<Champion>(name, HarnessMode::Headless, &config)测试写完后才允许实现或修改技能代码。
首先要通过日志定位问题,不要一上来就盲目添加修复代码
cargo check -p lol_champions cargo test -p lol_champions
ECS 与 Observer 的解耦技能架构。ECS 实体上。crates/lol_champions/src/<hero>/。mod.rs:注册插件与核心施法监听器。q.rs、w.rs、e.rs、r.rs 存放对应主动技能逻辑。passive.rs:存放被动技能逻辑。buffs.rs:声明英雄特有的状态组件。tests.rs:集成测试与测试配置。get_skill_value 动态解析属性加成公式。详见 skill-value.md。get_skill_data_value 读取特定等级原始数组。团队犯过最多的错误就是写硬编码常量替代 RON 数据。每次新技能必须遵循以下优先级:
calculations(公式值) → get_skill_value(spell_obj, name, level, |stat| ...)
min_damage 公式 = MinBase + total_AD * 0.6dataValues(数据值) → get_skill_data_value(spell_obj, name, level)
MarkDuration、PercentMS、VitalPercent、HealPerSecond、锐雯 R 的 Duration、PercentBonusAD、TooltipAttackRangeeffectAmounts(效果值) → 通过 get_skill_value 传 1.0 作为 stat 提取倍率
stat(total_AD) * effectValue(N) 这样的公式,传 |stat| if stat == 2 { 1.0 } else { 0.0 } 即得到 effectValue[N] 原始值get_skill_value(..., "empowered_attack_damage", ..., |stat| if stat == 2 { 1.0 } else { 0.0 }),然后 ratio = total_mult - 1.0(减去基础普攻 100% AD)cooldownTime(冷却时间) → 直接从 spell_obj.spell_data.cooldown_time 读取
get_skill_data_value 不能读 cooldownTime,因为它是 spell 顶层字段而非 dataValuesspell_obj.spell_data.as_ref().and_then(|d| d.cooldown_time.as_ref()).and_then(|v| v.get(skill.level).copied()).unwrap_or(default)skill.level 而非 skill.level - 1保留为硬编码常量的情况(仅限以下两类):
FIORA_R_ACTIVE_DURATION = 0.5(R 生效前延迟)、VITAL_R_TIMEOUT = 1.5(要害过期红色闪烁预警)AATROX_Q_RADIUS = 300.0、AATROX_Q_SWEET_SPOT_MIN = 200.0技能开启时直接修改属性(伤害/攻击距离/速度),到期后必须准确恢复原始值。
错误做法:在恢复代码中硬编码回退值
// ❌ 硬编码 0.25 和 75.0,一旦 RON 修改就不同步
damage.0 = damage.0 * (1.0 - 0.25 / 1.25);
attack.range -= 75.0;
正确做法:在 Buff 组件中存储应用时的实际值,到期后按存储值恢复
// ✅ Buff 组件中记录原始加成
pub struct BuffRivenR {
pub timer: Timer,
pub bonus_ad_ratio: f32, // 从 RON PercentBonusAD 读取的实际值
pub bonus_range: f32, // 从 RON TooltipAttackRange 读取的实际值
}
// ✅ 恢复时用存储值
damage.0 /= 1.0 + buff_r.bonus_ad_ratio;
attack.range -= buff_r.bonus_range;
| 字段 | 索引方式 | 说明 |
|---|---|---|
dataValues.values | level - 1 | get_skill_data_value 内部处理 |
effectAmounts.values | level - 1 | 通过 formula 的 effectIndex 间接访问 |
cooldownTime | level(⚠️ 不是 level-1) | 索引 0 通常是 nil 占位,真正的各级数值从索引 1 开始 |
castRange / castRadius | level - 1 | get_skill_cast_radius 内部处理 |
SkillCastResult::Started)can_cast(slot_index) 变为 false