4.5 KiB
Hostile NPC threat boundary audit — 2026-10-06
Decision
The hostile-NPC outgoing threat item in
ACTIVE_CLASS_MECHANICS_BACKLOG.md is not
a missing consumer for the current hostile-mob combat path. HealerMan stores
each hostile mob's incoming target threat on that mob, keyed by the player,
party, online-player, or summon actors that the mob can currently attack. Its
enemy target selector has no hostile mob candidates, and the enemy-hit path
does not write threat into the attacking mob's table. The current model has no
NPC-versus-NPC target boundary to port.
Keep this source-parity item scoped as a future boundary. If hostile creatures later attack other threat-list-capable creatures, record the attacker in the recipient creature's threat list after checking that recipient's eligibility. Do not add outgoing threat to the source mob's own target table.
AzerothCore holder and direction rules
The read-only behavior reference is AzerothCore HEAD
e822d718322289dd036fb2daf8867ba41283bf9a. Its ThreatManager.cpp SHA-256 is
5f8ee4d9c8d9e6d41896b29769f0df315f62d789f2defa29df0a9912002f537b; its
Unit.cpp SHA-256 is
b7c0c68daee09ec1f863f9a8d6c4972c1adbe35fa5ec230a8887399395db1ed5.
ThreatManager::CanHaveThreatList requires a creature. It excludes pets,
totems, triggers, and player-summoned minions or guardians. Unit::CanHaveThreatList
also rejects dead units and vehicles in battlegrounds or arenas. Players
therefore do not own creature threat lists. These are rules about the list
holder, not about who may appear as a target in a creature's list: a hostile
creature can still track threat against a player or pet.
In Unit.cpp:1276, damage to a non-player victim calls
victim->AddThreat(attacker, damage, ...). Unit::AddThreat checks the
recipient (victim) with CanHaveThreatList() and adds the attacker to that
recipient's threat manager. ThreatManager::CalculateModifiedThreat applies
the threat aura multiplier from the threat target passed to that manager,
which is the damage source in this call. Thus damage threat belongs to the
recipient list and is scaled by source-side threat modifiers.
Current HealerMan path
MobCombatState carries threatByActor, targetActorId, and forcedTarget.
eligibleAggroActorIds builds candidates from the living local player, living
PartyMember records, live online-player actors, and living combat summons;
each must have a position within the hostile mob's leash. actorPosition
resolves positions from those same actor sources. The candidate builder does
not enumerate other MobCombatState records.
Party records are playable-character builds with class, specialization, role,
level, gear, and talent data. companionActorFromMember projects them as
kind: "companion", and advanceDungeonPartyCombat runs their combat actions.
They are managed party actors, not unowned AzerothCore creature AI instances.
CombatSummon records likewise carry an ownerActorId and a pet, totem, or
summon kind. They are valid hostile-mob targets here; that does not make them
threat-list holders.
When a party actor damages a mob, damageMobInWork adds threat under the
source actor ID to that damaged mob's threatByActor. Healing adds source
threat to each engaged living mob's table. The local threat aura lookup uses
the source actor's aura set before the value is added. advanceMobCombat
prunes each mob table to the eligible actors above and resolves that mob's
target from those entries. Enemy attacks then resolve against that selected
actor. The hit handling updates damage, health, and presentation state; it
does not add threat to the attacking mob's own table.
Hostile NPC helpers are also stored as MobCombatState entries, distinct from
player or party CombatSummon entries. A helper spawn records summonedBy;
call-for-help seeds the helper's own table with the same selected party target.
This preserves the current party-versus-hostile-mob model without adding a
mob-to-mob target path.
Backlog boundary
The current backlog phrase should remain future-facing or be narrowed when the backlog is next edited: source-side outgoing threat is only relevant to an enemy-versus-enemy consumer if that consumer models a living recipient creature with a threat list and a real target relationship. At that point, threat goes on the recipient and the holder gate applies there. Do not model it by inverting signs, mutating the attacker mob's table, or treating a playable party build as an ordinary unowned creature.
No runtime code, catalog, or backlog file was changed for this audit.