Skip to content

feat(calc): implement DistanceRamp tag (Close/Far Combat distance MORE)#14

Merged
ackness merged 3 commits into
masterfrom
feat/offensive-close-combat-cluster
Jun 29, 2026
Merged

feat(calc): implement DistanceRamp tag (Close/Far Combat distance MORE)#14
ackness merged 3 commits into
masterfrom
feat/offensive-close-combat-cluster

Conversation

@ackness

@ackness ackness commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the PoB2 DistanceRamp modifier tag — the distance-interpolated MORE/INC
damage that Close Combat / Far Combat / Point Blank / Far Shot grant. Previously
translate_tag had no DistanceRamp arm, so the whole stat-map entry fell to
UnsupportedTag and was silently dropped.

This PR also lands the oracle-verified correction of the offensive Close-Combat
cluster roadmap, which turned out to be a static-analysis misdiagnosis.

What changed (commit d3456ec)

  • New ModTag::DistanceRamp { ramp } + linear interpolation with endpoint clamp in
    Modifier::effective_number (ramp_factor, vendor ModStore.lua:574-590 line-for-line).
  • translate_tag parses the ramp point list (stat_map_engine.rs); matches() and
    canonical_tag() get the new arm.
  • skillDist source = new CalcConfig::skill_distance, set in the orchestrator to
    mode_effective && the enemyDistance <Input> value ONLY. This mirrors vendor exactly:
    skillCfg.skillDist = env.mode_effective and env.configInput.enemyDistance
    (CalcActiveSkill.lua:655), where configInput is the <Input> channel and does
    not include <Placeholder> values. The placeholder-inclusive
    Multiplier:enemyDistance (ConfigTab apply fallback) is a separate channel feeding
    only the accuracy distance penalty.

Why it is dormant for the demo suite (and that is correct)

All 18 demo-bd-test builds carry enemyDistance as <Placeholder number="20">, none as
<Input>skill_distance == None → every DistanceRamp mod is skipped, matching the
golden output (PoB2 likewise applies no Close Combat distance MORE to these builds).
parity_no_regression is therefore unchanged. The tag activates only for builds that set
enemyDistance as an explicit <Input>.

Oracle proof (flicker-strike): editing the build's enemyDistance 5 → 40 leaves AvgDamage
unchanged at 108623.8 (== golden); the MoreDamage intermediate is 1.3 = Concentrated Area
only, no Close Combat. The roadmap's expectation that DistanceRamp would move
monk-twister / flicker / shield-wall parity is void.

Roadmap correction (commit 7fabaca)

devs/docs/audits/offensive-parity-roadmap-2026-06-28.md gets a "MAJOR CORRECTION" section
recording the oracle-verified facts: #2 is not a parity-mover (placeholder enemyDistance),
monk-twister has no Close Combat on its Twister group, and #1 Onslaught is a real
over-application but the roadmap's Condition:UsingFlask fix does not work (the grantor is a
trigger-gated Silver Charm). Methodology lesson: oracle-verify every offensive root cause
before implementing.

Test plan

  • cargo fmt --check clean
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • cargo nextest run --workspace — 2097 passed, 5 skipped
  • cargo test -p pobr-build --test parityparity_no_regression unchanged (dormant tag)
  • New unit tests: interpolation at distance 20 (→ 0.6 factor), endpoint clamp, and the
    None-skip path (panel / placeholder-only enemyDistance)

ackness added 3 commits June 28, 2026 22:19
Add the PoB2 DistanceRamp modifier tag (ModStore.lua:574-590): Close Combat /
Far Combat / Point Blank / Far Shot grant a MORE/INC damage mod whose value is
linearly interpolated against the enemy distance. Previously translate_tag had
no DistanceRamp arm, so the whole mod entry fell to UnsupportedTag and was
dropped.

Pipeline: stat_map_engine translate_tag parses the ramp point list into a new
ModTag::DistanceRamp { ramp }; Modifier::effective_number interpolates value by
ramp_factor(ramp, skillDist) with endpoint clamp; canonical_tag + matches() get
the new arm.

skillDist source = CalcConfig::skill_distance, set in the orchestrator to
mode_effective && the enemyDistance <Input> value ONLY. This mirrors vendor
exactly: skillCfg.skillDist = env.mode_effective and env.configInput.enemyDistance
(CalcActiveSkill.lua:655), where configInput is the <Input> channel and does NOT
include <Placeholder> values. The placeholder-inclusive Multiplier:enemyDistance
(ConfigTab apply fallback) is a separate channel feeding only the accuracy
distance penalty.

All 18 demo-bd-test builds carry enemyDistance as <Placeholder> (none as
<Input>), so skill_distance is None and every DistanceRamp mod is skipped --
matching the golden output (PoB2 likewise applies no Close Combat distance MORE
to these builds). parity_no_regression unchanged; the tag activates only for
builds that set enemyDistance as an explicit Input. Unit tests cover
interpolation, endpoint clamp, and the None-skip path.
Static-analysis roadmap (#1/#2/#5/#8) overturned by direct pob2-oracle runs:
- #2 DistanceRamp: enemyDistance is <Placeholder> not <Input> in all 18 builds
  -> vendor skillDist=nil -> CC distance MORE never applies. Implemented the tag
  correctly (input-only skill_distance, dormant for demo suite).
- monk-twister: Close Combat is NOT on the Twister skill group (it's on Hollow
  Focus / Righteous Descent). Real gap is crit-mult (tangled), not CC.
- #1 Onslaught: real over-application, but grantor is a triggered Silver Charm
  and the roadmap's Condition:UsingFlask fix does not work (oracle: forcing
  UsingFlask still yields no Onslaught). Real gate is charm-effect-active.
- Lesson: oracle-verify every offensive root cause before implementing.
…ffect-active)

The earlier correction guessed the #1 gate was charm-effect-active. run-parsemod.sh
shows the true cause: PoB2's ModParser leaves 'Grants Onslaught during effect'
unsupported, so PoBR's parse_granted_buff_flag was an over-parse ahead of PoB2.
Fixed in PR #15 (remove the parse). Add a third methodology trap (PoB2-unsupported
mod-text -> PoBR over-parse) and mark #1 LANDED.
@ackness
ackness merged commit a57fdb7 into master Jun 29, 2026
@ackness
ackness deleted the feat/offensive-close-combat-cluster branch July 8, 2026 01:51
ackness added a commit that referenced this pull request Jul 18, 2026
Def 25-col 431 -> 444 @5% (439 -> 444 @10%), core-8 142 -> 144/144 (100%).
Six clusters closed; the 6 remaining @5% misses are all
mercenary-tactician-wolf-pack (task #13's lane). Reason chain in the
baseline comments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant