combat: relabel DamageReduct comments to match calcDamage player-defender direction

Review follow-up on the caster-floor rebaseline: the survival-half doc in
casterBlasterFloor described an HP add the code never makes (Defense only),
and the pre-existing Druid *0.95 rider still read as a damage cut when, for a
player-defender through calcDamage, DamageReduct<1 raises damage taken. Comment
-only; no runtime change, guardrail test unaffected.
This commit is contained in:
prosolis
2026-07-17 17:22:06 -07:00
parent 1f62a8e842
commit b29dcf4360
2 changed files with 12 additions and 7 deletions

View File

@@ -139,9 +139,10 @@ func cantripDice(level int) int {
// the primary lever is damage. Multiplicative form — the spell modifier // the primary lever is damage. Multiplicative form — the spell modifier
// (INT for Mage, CHA for Sorcerer/Warlock) rides EVERY die, matching 5e // (INT for Mage, CHA for Sorcerer/Warlock) rides EVERY die, matching 5e
// Agonizing Blast. cantripDice scales 1→4 across levels. // Agonizing Blast. cantripDice scales 1→4 across levels.
// - Survival: just enough HP/Def (scaled by level) that the caster lives long // - Survival: just enough Defense (scaled by level) that the caster lives long
// enough for the cantrip to connect the kill — NOT a tank rider. calcDamage // enough for the cantrip to connect the kill — NOT a tank rider. This adds
// defense has diminishing returns, so this leans on HP. // Defense only (no HP add); calcDamage's diminishing returns keep the L20
// +20 Def from becoming a wall.
// //
// casterCantripBase / casterDefPerLevel are the caster tuning dials; see the // casterCantripBase / casterDefPerLevel are the caster tuning dials; see the
// rebaseline plan for the sweep that set them. The cantrip floor only becomes a // rebaseline plan for the sweep that set them. The cantrip floor only becomes a
@@ -246,9 +247,13 @@ func applyClassPassives(stats *CombatStats, mods *CombatModifiers, c *DnDCharact
mods.ExtraAttacks += 1 mods.ExtraAttacks += 1
} }
case ClassDruid: case ClassDruid:
// Wild Resilience — multiplicative, so it stacks cleanly with the // Multiplicative, so it stacks cleanly with the subclass DamageReduct
// subclass DamageReduct riders. DamageReduct is initialized to 1.0 // riders (DamageReduct is initialized to 1.0 by DerivePlayerStats before
// by DerivePlayerStats before passives run. // passives run). NOTE the player-defender direction: DamageReduct feeds
// calcDamage as a defense multiplier, so <1 = MORE damage taken. This
// line is therefore a mild survival trim in the same direction as the
// rebaseline *0.2 below — not the damage cut the "Wild Resilience" name
// suggests. Left as-is because the rebaseline sweep is tuned to it.
mods.DamageReduct *= 0.95 mods.DamageReduct *= 0.95
// rebaseline: the Druid wins T5 rooms on the survival tiebreak, immune to // rebaseline: the Druid wins T5 rooms on the survival tiebreak, immune to
// every damage lever. DamageReduct is a defense multiplier (calcDamage) — // every damage lever. DamageReduct is a defense multiplier (calcDamage) —

View File

@@ -229,7 +229,7 @@ func TestApplyClassPassives(t *testing.T) {
// -3 to-hit trim (both offset a new 2nd swing gated at L5, not seen here); // -3 to-hit trim (both offset a new 2nd swing gated at L5, not seen here);
// Druid took a survival trim (DR 0.95→0.19) + -0.20 damage; Bard a DR 0.4 // Druid took a survival trim (DR 0.95→0.19) + -0.20 damage; Bard a DR 0.4
// survival trim; Sorcerer a +1 to-hit to match the blasters; Paladin a // survival trim; Sorcerer a +1 to-hit to match the blasters; Paladin a
// 0.9 DR survival trim. Caster CantripPerRound / MaxHP / Defense adds are // 0.9 DR survival trim. Caster CantripPerRound / Defense adds are
// not asserted here. // not asserted here.
{ClassFighter, 0.05, -2, false, 0, 1.0, 0, 0}, {ClassFighter, 0.05, -2, false, 0, 1.0, 0, 0},
// Phase 2 class-balance rebalance: rogue picked up +5% damage, // Phase 2 class-balance rebalance: rogue picked up +5% damage,