From 46fff1c94f818fd7f41a1881d1d372d25aa435f9 Mon Sep 17 00:00:00 2001 From: Teakowa Date: Sat, 10 Oct 2026 05:20:37 +0800 Subject: [PATCH 1/2] fix(settings): resolve reviewed hero setting names for fire-mode keys The enableAutomaticFire and enableScoping keys were routed through a primaryFire gameplay-slot lookup that no applicable hero carries, so emission failed with a missing-mapping error instead of using the reviewed literal labels (No Automatic Fire, No Scope) already in the catalog. Drop the dead slot arm. Pin the remaining oracle-verified per-hero fire-mode names as reviewed aliases: the generic Secondary Fire label for the fourteen heroes the pinned schema includes (matching the existing Mei precedent), Roadhog's Pig Pen ability-2 names and Take a Breather secondary-fire names in en-US, and Vendetta's Warding Stance Regen Scalar. Roadhog's zh-CN secondary-fire spellings stay verbatim per the pinned ai-pve artifact (OverPy 9.7.13), with the 9.7.10 localized spellings kept as secondary parse aliases. Fixes #414 --- .../settings/data/hero_setting_aliases.json | 65 +++++++++++++++---- crates/workshop-rs/src/settings/table.rs | 1 - crates/workshop-rs/tests/settings_pipeline.rs | 35 ++++++++++ 3 files changed, 86 insertions(+), 15 deletions(-) diff --git a/crates/workshop-rs/src/settings/data/hero_setting_aliases.json b/crates/workshop-rs/src/settings/data/hero_setting_aliases.json index c43fb3f9..fa493d2c 100644 --- a/crates/workshop-rs/src/settings/data/hero_setting_aliases.json +++ b/crates/workshop-rs/src/settings/data/hero_setting_aliases.json @@ -1,20 +1,57 @@ [ - { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "en-US", "display": "secondaryFireCooldown%" }, + { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "en-US", "display": "Take a Breather Cooldown Time" }, { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "zh-CN", "display": "secondaryFireCooldown%" }, - { "hero": "sojourn", "key": "secondaryFireEnergyChargeRate%", "locale": "zh-CN", "display": "充能速度 充能射击" }, + { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "zh-CN", "display": "呼吸器冷却时间" }, + { "hero": "roadhog", "key": "secondaryFireMaximumTime%", "locale": "en-US", "display": "Take a Breather Maximum Time" }, + { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "en-US", "display": "Take a Breather Recharge Rate" }, { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "zh-CN", "display": "secondaryFireRechargeRate%" }, { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "zh-CN", "display": "呼吸器充能速度" }, + { "hero": "roadhog", "key": "enableAbility2", "locale": "en-US", "display": "Pig Pen" }, + { "hero": "roadhog", "key": "enableAbility2", "locale": "zh-CN", "display": "拴猪圈" }, + { "hero": "roadhog", "key": "ability2Cooldown%", "locale": "en-US", "display": "Pig Pen Cooldown Time" }, + { "hero": "roadhog", "key": "ability2Cooldown%", "locale": "zh-CN", "display": "拴猪圈冷却时间" }, + { "hero": "sojourn", "key": "secondaryFireEnergyChargeRate%", "locale": "zh-CN", "display": "充能速度 充能射击" }, { "hero": "hazard", "key": "secondaryFireRegen%", "locale": "zh-CN", "display": "尖刺护体资源恢复" }, - { "hero": "hazard", "key": "secondaryFireCost%", "locale": "zh-CN", "display": "尖刺护体资源消耗" } - ,{ "hero": "mei", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" } - ,{ "hero": "mei", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" } - ,{ "hero": "wreckingBall", "key": "ability1Cooldown%", "locale": "zh-CN", "display": "工程抓钩冷却时间" } - ,{ "hero": "wreckingBall", "key": "ability2Cooldown%", "locale": "zh-CN", "display": "感应护盾冷却时间" } - ,{ "hero": "wreckingBall", "key": "ability3Cooldown%", "locale": "zh-CN", "display": "重力坠击冷却时间" } - ,{ "hero": "hammond", "key": "ability1Cooldown%", "locale": "zh-CN", "display": "工程抓钩冷却时间" } - ,{ "hero": "hammond", "key": "ability2Cooldown%", "locale": "zh-CN", "display": "感应护盾冷却时间" } - ,{ "hero": "hammond", "key": "ability3Cooldown%", "locale": "zh-CN", "display": "重力坠击冷却时间" } - ,{ "hero": "hammond", "key": "ability1Cooldown%", "locale": "en-US", "display": "Grappling Claw Cooldown Time" } - ,{ "hero": "hammond", "key": "ability2Cooldown%", "locale": "en-US", "display": "Adaptive Shield Cooldown Time" } - ,{ "hero": "hammond", "key": "ability3Cooldown%", "locale": "en-US", "display": "Piledriver Cooldown Time" } + { "hero": "hazard", "key": "secondaryFireCost%", "locale": "zh-CN", "display": "尖刺护体资源消耗" }, + { "hero": "vendetta", "key": "secondaryFireRechargeRate%", "locale": "en-US", "display": "Warding Stance Regen Scalar" }, + { "hero": "vendetta", "key": "secondaryFireRechargeRate%", "locale": "zh-CN", "display": "招架姿态恢复倍率" }, + { "hero": "anran", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "anran", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "baptiste", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "baptiste", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "cassidy", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "cassidy", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "genji", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "genji", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "illari", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "illari", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "kiriko", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "kiriko", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "mei", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "mei", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "mercy", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "mercy", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "moira", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "moira", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "roadhog", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "roadhog", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "symmetra", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "symmetra", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "torbjorn", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "torbjorn", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "winston", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "winston", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "zarya", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "zarya", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "zenyatta", "key": "enableSecondaryFire", "locale": "en-US", "display": "Secondary Fire" }, + { "hero": "zenyatta", "key": "enableSecondaryFire", "locale": "zh-CN", "display": "辅助攻击模式" }, + { "hero": "wreckingBall", "key": "ability1Cooldown%", "locale": "zh-CN", "display": "工程抓钩冷却时间" }, + { "hero": "wreckingBall", "key": "ability2Cooldown%", "locale": "zh-CN", "display": "感应护盾冷却时间" }, + { "hero": "wreckingBall", "key": "ability3Cooldown%", "locale": "zh-CN", "display": "重力坠击冷却时间" }, + { "hero": "hammond", "key": "ability1Cooldown%", "locale": "zh-CN", "display": "工程抓钩冷却时间" }, + { "hero": "hammond", "key": "ability2Cooldown%", "locale": "zh-CN", "display": "感应护盾冷却时间" }, + { "hero": "hammond", "key": "ability3Cooldown%", "locale": "zh-CN", "display": "重力坠击冷却时间" }, + { "hero": "hammond", "key": "ability1Cooldown%", "locale": "en-US", "display": "Grappling Claw Cooldown Time" }, + { "hero": "hammond", "key": "ability2Cooldown%", "locale": "en-US", "display": "Adaptive Shield Cooldown Time" }, + { "hero": "hammond", "key": "ability3Cooldown%", "locale": "en-US", "display": "Piledriver Cooldown Time" } ] diff --git a/crates/workshop-rs/src/settings/table.rs b/crates/workshop-rs/src/settings/table.rs index fa92d14c..cc3f1f96 100644 --- a/crates/workshop-rs/src/settings/table.rs +++ b/crates/workshop-rs/src/settings/table.rs @@ -719,7 +719,6 @@ pub(crate) fn ability_slot_for_path(path: &[PathPart<'_>]) -> Option<&'static st Some("ultimate") } Some(PathPart::Part("enablePassive")) => Some("passive"), - Some(PathPart::Part("enableAutomaticFire" | "enableScoping")) => Some("primaryFire"), _ => None, } } diff --git a/crates/workshop-rs/tests/settings_pipeline.rs b/crates/workshop-rs/tests/settings_pipeline.rs index 13e49335..f7c6b5dc 100644 --- a/crates/workshop-rs/tests/settings_pipeline.rs +++ b/crates/workshop-rs/tests/settings_pipeline.rs @@ -217,6 +217,41 @@ fn pinned_ai_hero_setting_aliases_are_canonical() { ); } +#[test] +fn pinned_hero_setting_names_emit_the_oracle_spellings() { + let catalog = catalog(); + let en = en(); + let source = "settings { heroes { General { \ + Ana { No Automatic Fire: Off No Scope: Off } \ + Genji { Secondary Fire: Off } \ + Roadhog { Take a Breather Cooldown Time: 50% Take a Breather Maximum Time: 60% Take a Breather Recharge Rate: 70% Secondary Fire: Off Pig Pen: Off Pig Pen Cooldown Time: 80% } \ + Vendetta { Warding Stance Regen Scalar: 90% } \ + } } }"; + let program = internal::parse_in(source, &en); + let emitted = internal::emit_in(&program, &en); + for expected in [ + "No Automatic Fire: Off", + "No Scope: Off", + "Secondary Fire: Off", + "Take a Breather Cooldown Time: 50%", + "Take a Breather Maximum Time: 60%", + "Take a Breather Recharge Rate: 70%", + "Pig Pen: Off", + "Pig Pen Cooldown Time: 80%", + "Warding Stance Regen Scalar: 90%", + ] { + assert!(emitted.contains(expected), "{emitted} missing {expected}"); + } + let reparsed = internal::parse_in(&emitted, &en); + assert!(roundtrip::equivalent_wir(&program, &reparsed)); + assert!( + program + .semantic_issues(&catalog) + .iter() + .all(|issue| issue.kind != workshop_rs::rules::IncompletenessKind::RawSetting) + ); +} + #[test] fn mixed_locale_primary_hero_setting_name_is_canonical() { let catalog = catalog(); From 52359f80c88a3ab645f925cac23185a6580f2fbe Mon Sep 17 00:00:00 2001 From: Teakowa Date: Sat, 10 Oct 2026 05:52:39 +0800 Subject: [PATCH 2/2] fix(settings): pin roadhog zh-CN secondaryFireMaximumTime spellings The key otherwise hard-errors MissingMapping in zh-CN: the verbatim pin keeps 9.7.13-corpus emission while the 9.7.10 spelling stays parse-accepted, matching the sibling Take a Breather keys. --- crates/workshop-rs/src/settings/data/hero_setting_aliases.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/workshop-rs/src/settings/data/hero_setting_aliases.json b/crates/workshop-rs/src/settings/data/hero_setting_aliases.json index fa493d2c..5b5fcf22 100644 --- a/crates/workshop-rs/src/settings/data/hero_setting_aliases.json +++ b/crates/workshop-rs/src/settings/data/hero_setting_aliases.json @@ -3,6 +3,8 @@ { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "zh-CN", "display": "secondaryFireCooldown%" }, { "hero": "roadhog", "key": "secondaryFireCooldown%", "locale": "zh-CN", "display": "呼吸器冷却时间" }, { "hero": "roadhog", "key": "secondaryFireMaximumTime%", "locale": "en-US", "display": "Take a Breather Maximum Time" }, + { "hero": "roadhog", "key": "secondaryFireMaximumTime%", "locale": "zh-CN", "display": "secondaryFireMaximumTime%" }, + { "hero": "roadhog", "key": "secondaryFireMaximumTime%", "locale": "zh-CN", "display": "呼吸器最长时间" }, { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "en-US", "display": "Take a Breather Recharge Rate" }, { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "zh-CN", "display": "secondaryFireRechargeRate%" }, { "hero": "roadhog", "key": "secondaryFireRechargeRate%", "locale": "zh-CN", "display": "呼吸器充能速度" },