| name | update-abilities-override |
| description | Dota 版本更新时,以 docs/reference 中官方技能 KV 为骨架维护 game/scripts/npc/npc_abilities_override.txt:仅写差分,引擎合并缺失键。 按 P1 删同值 → P2 差分与 MaxLevel 扩展 → P3 注释校验 的优先级逐技能处理。 |
Update Abilities Override
维护 game/scripts/npc/npc_abilities_override.txt:仅写与当前参考的差分(扩展等级、有意加强等),引擎从原版合并缺失键。
前置条件
参考文件路径见 CLAUDE.md「Dota 2 参考文件速查」。英雄名 / 技能名查找规则见「技能系统名查找」章节。
用 grep / 片段读取定位,禁止一次读入整个 override 文件。
判断某技能当前实际生效的数值(如蓝耗)时,不能只看 docs/reference 原版,也不能只看顶层字段——override 常把数值写成 AbilityValues 内的嵌套子块(如 AbilityManaCost { "value" "9 10 11 12 13" })而非顶层字段。例:drow_ranger_frost_arrows 原版 0 蓝,本图 override 里实际是 AbilityValues 嵌套的 9-13 蓝/箭,只 grep 顶层 AbilityManaCost 会误判为 0 蓝。先精确读该技能整段(到下一个顶层技能名前),同时检查顶层字段和 AbilityValues 嵌套块;override 未覆盖时才回落原版。
技能范围
用户未指定技能时,从参考 npc_heroes.txt 读取槽位:
| 槽位 | 规则 |
|---|
| Ability1–3, Ability6 | 一律纳入 |
Ability4/5 = generic_hidden | 跳过 |
Ability4/5 先天技能("Innate" "1") | 不扩展等级,仅写明确数值差分 |
| Ability4/5 其它实技能 | 同 Ability1–3 规则 |
npc_heroes_custom.txt 覆盖了槽位时以 custom 为准。
等级规则
| 类型 | 本图 MaxLevel | 参考缺省 |
|---|
| 小招 | 5 | 4 |
大招(ABILITY_TYPE_ULTIMATE) | 4 | 3 |
先天技能("Innate" "1") | 不扩展;若参考显式写明 MaxLevel "1",override 中不得写 MaxLevel(删除已有的) | — |
若参考或 override 已显式写明 MaxLevel,以显式值为准。
核心规则(按优先级)
维护任一技能时严格按 P1 → P2 → P3 顺序处理,后步不得推翻前步结论。
P1 删除同值与禁止项
与参考逐字相同的键一律不写入 override,已写入的删除。
同值判定范围:
- 单值相同
- 多档每档与参考对应档相同,包括为凑 MaxLevel 而重复末档(如参考
"20 20 20",本图写 "20 20 20 20" 仍属同值)
- 注意:「前几档与参考相同、新档按差值延伸」不是同值。示例:参考
"140 150 160 170",本图 MaxLevel=5 写 "140 150 160 170 180",第5档180≠参考末档170,必须写入 override
AbilityBehavior、SpellImmunityType、AbilityCastPoint 等属性键
- 与参考相同的
special_bonus_unique_* / special_bonus_scepter / special_bonus_shard
- 子块内任意键(
value、affected_by_aoe_increase、special_bonus_scepter 等)与参考相同 → 删该行,保留有差分的兄弟键;若子块全无差分则删整块
绝对禁止项:
CalculateSpellDamageTooltip(交给原版)
special_bonus_facet_*(7.41+ 废弃);若子键仅有已废 facet 而无 value,不得新造 value
- 参考曾经存在、现已删除的键:须从 override 中删除
参考从未有过的键(本图自定义):
- override 里有、历来参考里都不存在的键,且行尾注释明确写有
// 原版不存在,手动修改 → 保留
- 行尾注释没有该说明(如仅写
// x2.5 或无注释)的处理:
- 仅限
LinkedAbility / AbilityDraftPreAbility / 自定义天赋键(special_bonus_* 参考中不存在) → 用 AskUserQuestion 询问用户是否有意添加;确认有意时补写 // 原版不存在,手动修改 保留,否则删除
- 原版结构变化导致的失效键:子块结构发生变化时,按以下规则处理:
- 旧格式写了
value "X",新格式改成 special_bonus_scepter "Y"(或 special_bonus_shard):自动迁移——将旧 value 的设计值迁移到新键名上,用原注释推断倍率/差值并重算,写入 "special_bonus_scepter" "迁移值" // 官方值 [规则标记],无需询问(规则明确时);规则不明确时用 AskUserQuestion 确认
- 旧格式有
RequiresScepter "1" 等辅助键,新格式无此键 → 直接删除辅助键,无需询问
- 子键在参考中已完全消失(非结构迁移)→ 直接删除,无需询问
- 版本更新后键名改变(如旧版
foo_tooltip → 新版 foo):删旧键名,按新键名走正常 P1/P2/P3 流程
P2 差分与 MaxLevel 扩展
读设计意图
- 有行尾注释(
x2、+N、差值N 等) → 按该规则在当前参考值上重算 value;若重算结果与现有 value 不符,进入「旧版参考缺失处理」流程
- 无行尾注释 → 默认仅等级扩展;value 必须与参考相同前几档 + 差值延伸。若与参考不符,视为官方版本更新了数值,直接同步为官方最新值并补全新档(不加注释,无需询问)
MaxLevel 扩展必扫(强制)
本图 MaxLevel 高于参考时,以参考该技能整段为全集扫描所有多档键,禁止只扫 override 已有行:
| 多档键位置 | 说明 |
|---|
| 块顶多档 | AbilityCooldown、AbilityManaCost、AbilityDuration、AbilityCastRange 等 |
| AbilityValues 子块 | "键" { "value" "a b c" ... } |
| AbilityValues 顶层平铺(易漏) | 直接 "键名" "a b c" 无子块 |
顶层 vs 子块冲突:若参考将某键(如 AbilityCooldown)放在 AbilityValues 子块内,而 override 写成顶层,顶层写法无效(子块优先)。处理时:删除 override 中的顶层写法,在 AbilityValues 子块内按 P1/P2/P3 正常处理。无需询问,直接处理。
对参考全集中每个多档键(含「参考有 override 无」的差集)依次判定:
- 同值多档 → 不写(P1 优先)。判定标准:参考各档与本图各档逐一对应且相同,或参考档数不足时末档重复延伸后与本图各档相同(如参考
20 20 20,本图 MaxLevel=5 补成 20 20 20 20 20,仍属同值)。注意:若参考只有 N 档而本图 MaxLevel > N,且按差值延伸后新档的值与参考末档不同,则属于需要写入 override 的扩展,不是同值。
- 恒定单值(本图各级同数)→ 单 token,禁止
n n n
- 随等级变化 → 档数 = 有效 MaxLevel;新档按相邻差延伸
数值计算
| 情形 | value 处理 | 行尾注释 |
|---|
| 仅等级扩展 | 前几档同参考,新档按差值延伸 | 无(不写注释) |
| 固定差值 | 每档 = 参考 + N | // 参考各档 +N |
| 倍数 | 先推参考第 N 档再乘倍率 | // 参考各档 xN(基数必须写出) |
自定义键(参考从未有过,且已有 // 原版不存在,手动修改 注释) | 保留本图值;同样须做 MaxLevel 扩展 | // 原版不存在,手动修改 |
| 参考无、且无上述注释 | 删除 | — |
| CD 末档 | 封顶值:小招 10s / 大招 60s;参考档位中的最小冷却值 min。 大招特殊规则:若参考 min > 60s,直接按原差值延伸(不锁末档,不调首档),无需对齐封顶值。示例:参考 100 90 80(min=80 > 60),MaxLevel=4,末档=70 → 100 90 80 70。 小招 / 大招 min ≤ 60s 时:末档锁为 max(min, 封顶值),优先保持等差数列。步骤:(1) 尝试保持参考首档不变,新公差 = (末档 - 参考首档) / (MaxLevel - 1);(2) 若无法整除,微调首档使公差为整数,末档不变。 CD 数值风格:尽量取 5 或 10 的整数倍(如 10、15、20、25…),若原差值已是 5/10 的倍数则直接延伸,否则就近取整使结果对齐。 情形1 · 大招 min > 60,直接延伸:参考 100 90 80,MaxLevel=4 → 100 90 80 70。 情形2 · 首档不变即整数公差:参考 22 18 14 10(4 档,min=10),MaxLevel=5,延伸末档 6 < 10 → 末档锁 10,(10-22)/4=-3 整除 → 22 19 16 13 10。 情形3 · 调首档以保证整数公差:参考 20 17 14 11(4 档,min=11),MaxLevel=5,延伸第5档=8 < 10 → 末档锁 10,保持首档 20 时 (10-20)/4=-2.5 非整数 → 首档下调至 18,公差 -2 → 18 16 14 12 10。 | 无 |
| CD 档数不足 | 保持同一档差递减至参考末档,如参考 12 10 8 6 → 10 9 8 7 6 | 无 |
| 百分比键封顶 | 键名以 _pct 结尾(或其他明确表示百分比的键):延伸后各档不得超过 100。若参考最大值 > 50 时,差值延伸将超过 100,则改写差值使末档恰好等于参考最大值(max),差值 = (max - 首档) / (MaxLevel - 1),各档均匀分布;如无法整除则就近取整。示例:参考 40 60 80 100,MaxLevel=5,末档延伸为 120 → 改差值 15 → 40 55 70 85 100。 | // 参考首档…末档 差值N |
版本更新后重算(处理已有 override 时必做)
处理任何已有 override 记录的技能时,先逐一核对所有行尾注释的参考基数是否与当前版本一致,再执行 P1/P2/P3:
注释基数 = 当前官方值时:说明官方该数值未发生版本更新,无需重算,不触发「旧版参考缺失」询问,直接保留 override 现有 value 和注释,继续 P1/P2 正常流程。
- 注释有参考基数(如
// 15 30 45 60 x2)且参考基数 ≠ 当前官方值→ 直接按注释规则用当前版本参考值重算并写入,无需询问
- 注释无参考基数(仅
// x2)→ 直接按最新版官方值 ×N 重算并补全注释基数,无需询问
- 无注释,且 value 是官方差值的延伸 → 自动按官方差值补全新档,无需询问
- 无注释,且 value 与参考差值不符 → 官方版本更新了数值,直接同步为官方最新值并补全新档,无需询问(不保留旧值,不加注释)
旧版参考缺失时的处理
触发条件(满足任一):
- 按注释规则重算后结果与现有 value 不符,且旧版参考不存在(无法确认规则是否变更)
以下情形不触发询问,直接按 P2 规则处理:
- 无注释 → 无论 value 与参考是否一致,均直接同步官方最新值,无需询问
- 有注释规则标记(
xN、+N、差值N 等),override 值与按当前官方值重算的结果不符 → 视为官方版本更新了基数,直接用当前官方值按注释规则重算并写入,无需询问
- 选项显而易见只有一种合理处理方式(如删除同值、删除无注释的不合规值、P1 禁止项)→ 直接处理,无需询问
必须使用 AskUserQuestion 工具以选项菜单形式询问用户,不得用文字列出 A/B/C/D,不得自行假设。
询问规则:
- 每个待决策键单独一道问题(
question 字段),最多4题一批;超过4键分批询问
header 填系统键名(截短到12字符内)
question 用中文描述:「{技能中文名}」{中文属性名}({系统键名}):当前官方值 {参考值},现有 override 值 {当前值},原注释 {注释}。如何处理?(必须在问题开头写出技能中文名,方便用户区分同名属性归属于哪个技能)
options 固定提供以下选项(按实际情况选取相关项,无关项可省略):
× N 重算:description 写出具体候选倍数和结果(如 ×2 → 结果值);若倍数不确定,先用此选项让用户选 Other 填写,再单独一题确认
+ N 重算:description 写出具体候选差值和结果
纯等级扩展:description 写出按差值延伸的结果值
保留现有 value:description 写出修正后的注释内容
- 若倍数/差值需要二次确认(用户在第一轮选了「×N」但未指定 N),发起第二轮问题列出常见倍数选项
- 技能中文名:直接使用 override 文件中该技能块上方的注释(如
// 诅咒);若 override 中无该技能块,再从 docs/reference/{version}/abilities_schinese.txt 查 DOTA_Tooltip_ability_{ability_name}
- 属性中文名从
docs/reference/{version}/abilities_schinese.txt 查找:DOTA_Tooltip_ability_{ability_name}_{key_name} 对应的值(去掉末尾冒号);若查不到则用系统键名
- 用户选择后按其指示重算并更新 value 和注释
P3 注释格式
仅在 override 值与参考不同时写行尾注释。格式:"本图值" // 参考值 [规则标记]
| 场景 | 示例 |
|---|
| 单值对照 | "12" // 18 |
| 多档对照 | "90 80 70 60" // 150 130 110 |
| 倍数 | "30 60 90 120 150" // 15 30 45 60 x2 |
| 固定差值 | "300 500 700 900" // 200 400 600 800 +100 |
| 改差值 | "3 3.5 4 4.5 5" // 3 4 5 6 差值0.5 |
| 参考值 + 设计说明 | "=0" // =1 移除 连环霜冻无限弹跳天赋 |
| 纯设计说明 | // 原版不存在,手动修改、// 百分比伤害,限制上限 |
规则:
// 后先写当前参考官方数,倍率/差分标记放末尾;参考值后可接中文设计说明解释意图,已有的说明应保留
- 倍数标记
x2 等必须同时写参考数,禁止 // x2 无基数
- 同值不占坑(
"30" // 30 → 删整行)
- 禁止:分号分隔、命石/facet 名称
- 增加参考不存在的键 → 行尾
// 中文原因
- 沿用同文件、同英雄区段已有注释风格
执行顺序(逐英雄)
- 定范围:从
npc_heroes.txt(+ npc_heroes_custom.txt)确定技能列表
- 逐技能:
a. 读参考整段,列出全部多档键(全集)
b. 读 override 该技能块,标出差集(参考有 override 无)
c. P1:删同值键 + 禁止项
d. P2:处理差分、扩展新档、重算倍数/差值
e. P3:校验注释格式
- 自检:
- 所有英雄处理完毕后,调用
update-heroes-custom 对本次修改的英雄逐一验证 Bot.Build 合规性。