Files
Fractured/contrib/fractured-dev-extras/BALANCE-TODO.md
T
Docker Build b8826370c6 Paragon: cross-class stance exclusivity + cancel, hunter ammo soft-fail, Feral Cat scaling, Pestilence DP spread
Server-side batch following v0.7.18, all gated to Paragon (or applied
server-wide where the design discussion called for it):

* Cross-class stance / form / presence / aspect exclusivity (server-wide).
  New `IsFracturedExclusiveStanceSpell()` (`Unit.cpp`/`Unit.h`) returns
  true for the union of warrior stances + druid forms (combat AND utility:
  Travel, Aquatic, Flight, Swift Flight) + Ghost Wolf + base Stealth +
  Shadowform + Metamorphosis + DK Presences + Hunter Aspects (combat AND
  utility: Cheetah, Pack). `Aura::CanStackWith` (`SpellAuras.cpp`) refuses
  to stack two spells from this set, which routes through
  `_RemoveNoStackAurasDueToAura` to drop the older aura -- the same
  mechanism Battle Elixirs / Curses use. Plugs the stock-AC gap where DK
  Presences and Hunter Aspects (regular auras, just rendered in the
  stance bar) coexisted with engine-shapeshifts.

* Stances / Presences / Aspects cancellable like Druid forms.
  `SpellInfoCorrections.cpp` now zeroes `CategoryEntry` on warrior
  stances, DK presences, and every rank of every hunter aspect (moves
  them out of SpellCategory 47 "Combat States", which gates the client's
  right-click / `/cancelaura` path), AND clears `AttributesEx6` bit
  `0x1000` on warrior stances + DK presences (a second client-UI gate
  surfaced via DBC diff -- aspects don't have it set). Mirrored client-
  side by `_patch_spell_dbc_presences_cancelable.py`. Aspects / presences
  do NOT swap action bars (those are owned by `SPELL_AURA_MOD_SHAPESHIFT`,
  not by Category / AttrEx6) -- only warrior stances and druid forms keep
  the bar swap, matching the design requirement that presences/aspects
  not change the player's action bar.

* Hunter ammo soft-fail (server-wide).
  Replaced both `SPELL_FAILED_NO_AMMO` returns in `Spell::CheckCast` with
  `break;` so ranged + thrown abilities cast through with zero ammo;
  `_ApplyAmmoBonuses` continues to gate the actual arrow/bullet DPS bonus
  on a non-empty stack, so equipping ammo still pays off. New programmatic
  `ApplySpellFix`-style block in `SpellInfoCorrections.cpp` iterates every
  Hunter-family spell whose `EquippedItemClass == ITEM_CLASS_WEAPON` and
  `EquippedItemSubClassMask` includes Bow/Gun/Crossbow and sets
  `EquippedItemClass = -1` (skipping a small DENYLIST of Quiver / Ammo
  Pouch passive haste auras + Aynasha's Bow + Legendary Bow Haste -- those
  are item-equip-driven and must keep gating on the ranged weapon being
  equipped). Server log: ">> Fractured: dropped EquippedItemClass on 196
  hunter shot abilities". Mirrored client-side by the new
  `_patch_spell_dbc_hunter_ammo.py` so the 3.3.5a client preflight stops
  blocking the cast packet with "Ammo needs to be in the paper doll ammo
  slot before it can be fired." `Spell::TakeAmmo` no longer clears
  `PLAYER_AMMO_ID` to 0 when the bag empties (defense in depth so a half-
  deployed pair degrades to soft-fail rather than hard-reject). Adds
  `#include "ItemTemplate.h"` for `ITEM_SUBCLASS_WEAPON_*`.

* Feral Cat scaling (server-wide, cat-only).
  `StatSystem.cpp` `UpdateAttackPowerAndDamage` FORM_CAT branch doubles
  the AGI coefficient (1.0 -> 2.0). `SpellAuraEffects.cpp` Master
  Shapeshifter FORM_CAT branch doubles the talent's bp before triggering
  48420 (R1: 2% -> 4% crit, R2: 4% -> 8%). FORM_BEAR / FORM_DIREBEAR /
  FORM_MOONKIN / FORM_TREE branches all left untouched so bear stays
  "already fine" per the resident Feral expert. Client tooltip drift on
  Cat Form (768) + Master Shapeshifter (48411 / 48412) + Pestilence
  (50842) handled by `_patch_spell_dbc_feral_tooltips.py`.

* Pestilence spreads / refreshes Devouring Plague for Paragon casters.
  `spell_dk.cpp` `spell_dk_pestilence::HandleScriptEffect` now also
  spreads (and Glyph-of-Disease refreshes) Priest Devouring Plague when
  `IsParagonWildcardCaller(caster)`. Uses `GetAuraOfRankedSpell(2944)` so
  the spread copy carries the caster's actual rank. Stock DKs cannot
  cast Devouring Plague at all, so this branch is a no-op for them.

* Dancing Rune Weapon: Paragon copies melee, not casts.
  `spell_dk.cpp` `spell_dk_dancing_rune_weapon::CheckProc` for Paragon
  callers requires `eventInfo.GetDamageInfo()` and
  `spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE`, so the ghostly
  weapon now copies cross-class melee strikes (Hamstring, Sinister Strike,
  Heart Strike, Frost Strike, ...) and auto-attacks instead of re-casting
  the DK's nukes. Stock DK gating below is untouched.

* Maelstrom Weapon: drop Arcane Blast from the allowlist.
  `SpellInfo.cpp` and `spell_shaman.cpp` allowlists now match Fireball
  and Frostbolt only -- Arcane Blast stacked with its own self-buff was
  too potent.

* `BALANCE-TODO.md` added under `contrib/fractured-dev-extras/` to
  capture the resident Feral expert's recommendation, the levers we
  considered, and the cat-only Master-Shapeshifter / AGI-doubling
  resolution we shipped, plus the next-lever knobs if field reports
  still flag cat as weak.

DBC patcher pipeline (lives outside the repo in `fractured-tooling/`)
documented run order: runes -> reagents -> stances -> presences_cancelable
-> hunter_ammo -> feral_tooltips -> _make_paragon_dbc_patch.

No SQL migrations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 23:17:37 -04:00

4.5 KiB

Fractured / Paragon — Balance Backlog

Open balance / scaling questions surfaced by play-testers that have not yet been actioned. Each entry should record the symptom, the suspected cause based on a quick code dive, the option set we discussed, and any links to relevant code. Knock items off as they ship.


Feral Cat scaling feels weak (2026-05-11)

Reporter feedback:

"Weapons don't automatically feature feral AP on this server and nothing is currently rescaled resulting in a super low feral scale. We can either rescale their abilities or add the AP back to all weapons."

Resident Feral expert: "this is not a bear issue unfortunately, I have 11k AP" / "Stam > AP and Armor > AP means this is completely a cat issue."

What's actually happening on the server:

Feral AP is being granted on weapons — ItemTemplate::getFeralBonus (src/server/game/Entities/Item/ItemTemplate.h) synthesises it from the weapon's DPS for any weapon with INVTYPE_WEAPON / 2HWEAPON / WEAPONMAINHAND / WEAPONOFFHAND:

int32 bonus = int32((extraDPS + getDPS()) * 14.0f) - 767;

That's then routed through Player::ApplyFeralAPBonus (Player.cpp ~6896) into m_baseFeralAP, which Player::UpdateAttackPowerAndDamage adds into the cat / bear formulas in src/server/game/Entities/Unit/StatSystem.cpp (~line 477):

case FORM_CAT:
    val2 = (level * mLevelMult) + STR*2 + AGI - 20 + weapon_bonus + m_baseFeralAP;
    break;
case FORM_BEAR:
case FORM_DIREBEAR:
    val2 = (level * mLevelMult) + STR*2          - 20 + weapon_bonus + m_baseFeralAP;
    break;

So bear and cat get the same m_baseFeralAP — the only delta is + AGI for cat. The "bears feel fine, cats feel weak" complaint is real; it's because bear damage is rage / proc / mitigation driven (Lacerate stack, Savage Defense, Pulverize-style talents) while cat damage is much more AP-coefficient driven (Shred, Mangle, Rake, Rip, FB).

Options discussed (pick when we revisit):

ID Lever Pros Cons
A Bump the cat AP formula (e.g. + AGI*1.5) Cleanest, very tunable, hits both auto-attacks and abilities Blunt instrument, also affects PvP
B Boost cat-form ability coefficients (Shred / Rake / Rip / Mangle / FB) via spellmod auras Most retail-faithful, surgical More moving parts, harder to communicate
C Increase getFeralBonus payout for druid weapons (e.g. * 18.0f or drop the -767 floor) Single-line change Buffs bears too — bears are already fine, would over-buff
D New Cat-only passive "Predator's Edge" = +X% physical damage in Cat Form Easy to balance, easy to communicate, easy to undo Adds another aura to track

Recommendation when we pick this back up: start with D + small A — D is the readable "+15-20% cat damage" knob, A is a backup if AP-scaling abilities (Mangle / FB) still feel weak relative to bleeds. Both are trivially tunable via a single config knob during play-testing.

Do not pick C — it over-buffs bears, which the Feral expert explicitly said are already fine.

Resolution (2026-05-11, second pass): Per the resident Feral expert ("instead of adding a new passive, you could probably just increase Cat Form's Master Shapeshifter value along with its tooltip, alongside buffing the agi scaling") we shipped a hybrid of A and a cat-only knob that sits next to D but reuses an existing aura instead of inventing a new one:

  • StatSystem.cpp UpdateAttackPowerAndDamage FORM_CAT branch now reads + GetStat(STAT_AGILITY) * 2.0f (stock 1.0). FORM_BEAR / FORM_DIREBEAR / FORM_MOONKIN are untouched, so bear's "already fine" state is preserved.
  • SpellAuraEffects.cpp Master Shapeshifter FORM_CAT branch multiplies the talent's value by 2 before triggering 48420 (cat-form aura). Talent ranks: 2% -> 4% (R1), 4% -> 8% (R2) crit chance in Cat Form. Bear / Moonkin / Tree branches still pass bp through unchanged.
  • Client tooltip drift handled by fractured-tooling/from-workspace-root/_patch_spell_dbc_feral_tooltips.py, which appends a [Fractured] paragraph to the Description column of Cat Form (768) and Master Shapeshifter ranks (48411 / 48412).

If field reports after this lands still say cat is weak, the next levers are (in order): bump 2.0f to 2.5f in StatSystem.cpp, then bump the Master Shapeshifter cat multiplier from * 2 to * 3 in SpellAuraEffects.cpp, then -- only if those are exhausted -- revisit B (per-ability spellmod coefficients).