精华 Aggro算法 [技术贴]

月下独酌

浪子
VIP
注册
2003-06-21
消息
32,110
荣誉分数
4,179
声望点数
373
http://forums.worldofwarcraft.com/thread.aspx?fn=wow-druid&t=700989&p=1&tmp=1#post700989

Edit: Updated!
Jan 19: edited sections 8, 9, 10, to reflect new understanding on Taunt mechanics.
Jan 20: Updated Section 5 (sunder)
Jan 21: Updated Section 2 (10% rule), Section 10

It's often said that we will never be able to work out the way threat and hate lists and mobs' AI works, because it's too complicated and unknowable, that we'll only ever have crude approximations and guesses. I've conducted some decent, rigorous tests, and i have what i believe is a good list of hate values and explanations of gaining and losing aggro and the behaviour of taunt. I am also able to debunk a few myths about how threat works.

1) Definitions

We define "aggro" to be who the mob is attacking. We define "threat" to be a numeric value that each mob has towards each player on it's hate list. Note, as we shall soon see, even for a normal mob, the target who has aggro is not necessarily the player on it's threat list with the most threat.

We define arbitratily that 1 point of unmodified damage gives 1 point of threat.


2) Gaining aggro on a mob Updated Jan 31

Suppose a mob is attacking player 1. In order for the mob to switch to player 2, he must do more than just exceed the threat of player 1. If he is in melee range of the mob, he will draw aggro when he exceeds 110% of player 1's threat. If he is outside melee range of the mob, he will draw aggro when he exceeds 130% of player 1's threat.

E.g. mob is attacking player x. x does 100 damage to mob, then stops. Player y starts hitting the mob. The mob will start attacking y when y does over 110 damage.

Proof: this is easy to demonstrate. Get two players both doing autoattack on a mob (not warriors of rogues; we'll see later they complicate things). Have player 1 do a certain amount of damage, then stop. Have player 2 keep attacking till he gets aggro. You have an upper and lower bound on the threat required to get aggro - 1 attack before he got aggro was not enough, but the attack that he got aggro was at least enough. With low damage attacks (i.e. fists only), you will get a very good value of 10%. Testing for the non-melee range value is the same. Just replace it with a low damage ability such as a low level wand.

If player 2 has exceeded 110% threat but not 130% threat, they will draw aggro immediately if they do a threat-generating ability within melee range of the mob, but proximity alone will not cause the mob to shift to them.

This is only a description of the normal mob targetting. Obviously there are mobs who will attack secondary targets with special abilities, ignoring their current threat / aggro.


3) Threat modifiers from Warrior Stances

In Battle Stance and Berserker Stance, all threat from a Warrior is multiplied by 80%. In defensive stance, the multiplier is 130%. With Defiance, it is 145%.

Proof: a simple modification of the above proof. Get a warrior to do, say, 1000 damage in defensive stance, without defiance. Get a non-warrior to take aggro with white damage. You will find it does not happen before 1430 damage. The warrior's 1000 damage caused 1300 threat in defensive stance, and the 10% barrier means you need more than 1430 to gain aggro.


4) Threat does not decay

Threat never, ever decays. Here is test data. Warrior does 83 damage on mob in battle stance, gains aggro. From above, we know it will take more than 83 * 0.8 * 1.1 = 73.04 threat to gain aggro. Warrior waits for 5 minutes getting beat on. Then mage starts attacking slowly. Mage does 73 damage, but does not gain aggro! Mage does another 2 damage, and does gain aggro. From the warrior's initial hit to losing aggro, the time taken was 496 seconds.

As an upper bound, assume maximal threat decay. i.e. the mage only needed 73.000000001 threat to gain aggro. Then the warrior's threat had decayed to 66.36363636, from 66.4. This means he went down to 99.945% threat in 496 seconds.

At this maximal rate of hate decay, the time taken for the warrior's threat to decay to 90% of the original value would be 26.5 hours. In fact, if a warrior logged in as soon as the server came online after the weekly reset and hit a mob, his threat would not decay to 50% before the server reset next week. I think this is enough to rule out threat decay.


5) Threat values for some warrior abilities Updated Jan 20

the following list is not exhaustive, but includes all the major tanking abilities.

Note: the following values are given in raw terms. In reality the warrior must have either a 1.3 or 0.8 or 1.45 modifier on these, depending on his stance and talents.

Note: * All abilities do not include threat generated by their damage. This will be discussed more later.

Sunder: 261 (260.95 - 261.15)
Heroic Strike*: 145 (143.9 - 148.8)
Revenge*: 315 (313.9 - 318.3)
Revenge Stun: 25 (23.4 - 29.1)
Shield Bash*: 180 (175.4 - 180.3)
Shield Slam*: ?? 250 (estimated from Cop's data. More on that later)
Shield Block: 0 (0 - 0. Can be higher - more on this later)
Thunder Clap*: 130 (126.9 - 134.8)
Demo Shout: 43 (42.8 - 43.8)

Note that debuffs associated with abilities are not connected to the threat they generate. Demoralizing shout generates the same amount of threat whether the debuff is on or not. Sunder armor generates the same threat after 5 debuffs are on as when there are 0.

6) Healing, "you gain x ___", etc

Each point of healing, when completely unmodified by talents, gives 0.5 threat. Replace the proof for (2) by the second person only healing.

Note: overhealing doesn't count, only the actual amount healed. This is easy to demonstrate.

Abilities that put "you gain x mana" in the combat log give 0.5 threat per point gained; life is the same. Examples would be drinking potions, but not natural regen, or the Shaman's mana spring totem.

Abilities that put "you gain x rage" in the combat log give 5 threat per point gained. However, this is not modified by warrior stance. Such abilities include bloodrage, improved blocking talent, unbridled wrath, and 5/8 Might.

Like healing, these only give threat if you are below the maximum.


7) Explaining Cop's 4.0 damage to heal ratio

Cop stated that in his tests, each point of damage by the warrior took approximately 4 points of healing by the priest, for the priest to get aggro. Here's how:

Warrior in defensive stance, with defiance: 1.45 multiplier
Gaining aggro from Warrior: 1.1 multiplier
Priest with discipline: 80% threat
Healing: each point gives 0.5 threat

Together, 1.45 * 1.1 / 0.8 / 0.5 = 3.9875. Pretty darn close to 4.


8) Threat from pulling? Updated Jan 19

There is no threat associated with pulling. The smallest amouts of threat we could generate drew aggro from a body pull, no matter how long we waited after the pull. However, there are advantages to having the tank pull, as explained in the next secion.


9) Taunt Updated Jan 19

Casting taunt causes three effects.
A) The warrior is given as much threat as the person who currently has the mob's aggro. Obviously if the warrior has aggro, this will do nothing. Also, this effect will not lower the warriors threat. For example, if player 1 has 100 threat and aggro, a warrior could have 105 but not aggro; after taunt he would still be on 105 threat.
B) The mob recalculates its actual aggro target. If the warrior was on the mob's hatelist before the original aggro target, the mob's actual aggro target will switch to the warrior. Otherwise, the mob will remember it's original target.
C) The normal taunt debuff. The mob is forced to attack the warrior, even if the warrior is not its actual aggro target.

The threat that the warrior gains from (A) is permanent, regardless of the outcome of (B). Note that it will not necessarily give the warrior the equal highest threat on the mob. If player 1 has 100 threat and aggro, Player 2 has 109 threat but not aggro, and the warrior has 0 threat, then the warrior is given 100 threat, not 109, so he could easily lose aggro to Player 2 after taunting.


10) Implications Updated Jan 19. Updated Jan 21. Note this section is just my opinion.

a) Let the tank pull! Then he will be first on all the mobs' hatelists, and his taunts will always return aggro to him.

b) Given that targets at range will only draw aggro when they have more than 130% of the mob's target's current threat, it's important for a tank to keep the mobs well away from the casters. If a healer does draw aggro and you taunt it off him, make sure you also move it away.

c) Heroic Strike should not be used as a primary threat ability. Suppose you are tanking a level 62 mob. Let's give him 8,000 ac raw, and even assume he has 5 sunders stacked, for 5750 final ac, so he will take 48.89% of damage. A 15% crit rate is balanced by the 10% penalty to damage in defensive stance, and a 10% chance of a glancing blow chance for 50% damage. Then you can expect the 138 damage from Heroic Strike to contribute 67.5 damage on average, for a total of 212 unmodified threat. This is still only 82% of the threat a sunder would give. Even with a 1.3 speed weapon, you will still do 94% the threat of sunder per time interval.

Best practice is to spam sunder, and use HS in between to soak up excess rage.

d) Revenge ftw. You can expect to do about 345 unmodified threat with Revenge, including damage, against the mob in the example above, which is exceptional for the low rage cost, even throwing in 10 for a shield block. However, there is a rage cost of shield block, in that you will block more attacks, so take less damage, so gain less rage from damage. Two blocks for 180 damage and you can say goodbye to another 4 rage.

e) Demo Shout ftl. Demoralising shout does one sixth the threat of a sunder. Even spammed in defensive stance with defiance, you're doing no more threat than 42dps on each mob. Besides picking up whelps in Onyxia and tanking panthers in the Panther boss encounter in ZG, i can't see a compelling reason to use this.

f) Shield Slam ftl. Given the 6 second cooldown, there is no improvement in threat per second by using shield slam. With shield slam: 3 sunders and 1 shield slam every 6 seconds. About 212 threat per second, unmodified. With the 30 rage from the shield slam you can cast 1 sunder and about 1.2 heroic strikes, assuming you have the talents (which you would with any shield slam build), and are losing 3 rage per Heroic Strike from lost white damage rage (i.e. assuming 90 modified damage per hit). The 4 sunders and 1.2 heroic strikes every 6 seconds gives about 215 threat per second.

The only improvement is if you are spamming both sunder and HS, and want even more threat. Suppose we have a 2.0 speed weapon, HS spam and sunder spam. That's about 280 unmodified tps. Changing one sunder for a shield slam gives us 318 unmodified. However, the same effect would be achieved by changing to a 1.4 speed weapon and casting HS more often. And these values aren't taking into account autoattack damage, which makes the margins comparatively smaller.

g) There's no amazing super secret randomised blizzard aggro algorithm. The concepts are simple and the values can be fitted with nice numbers. Even formulas for threat-reducing knockbacks can conceivably be worked out, if threat values are carefully monitored.


Well, i hope some of you are still awake, and are feeling somewhat enlightened. And if you skipped to the bottom, i can't exactly blame you after my essay above.
 
Formulae:
1 dmg = 1 * (1+threat modifier) threat
1 point healed (actual healing) = 0.5 * (1+threat modifier) threat
1 point of mana gained = 0.5 threat (mana potions, etc)

To gain aggro from current aggro-holder:
Target within close proximity (Melee range probably): 1.1 * current threat value of aggro-holder.
Target at range: 1.3 * current threat value of aggro holder

Taunting:
- Immediately raises warrior's threat value to that of the current aggro-holder.
- Causes mob AI to initiate a new calculation to determine who's the aggro-holder. Warrior will get aggro if he was a prior entry on the mob's hatelist than the current aggro-holder.
- Forces mob to attack warrior IF the debuff was not resisted.

Special Abilities that generate threat: (Numbers are approximates)

Warrior:

Attack Name Base Threat Generated (regardless of damage, ability must connect)
Heroic Strike 145
Sunder Armor 261
Revenge 315
Revenge Stun Debuff 25
Shield Bash 180
Shield Slam 250
Thunder Clap 130
Demoralizing Shout 43
 
作为一个战士,感觉楼主所转贴的系统不太完全。

这样的事情发生好几次了:

只有在和比较强的人一起的时候才发生;(没有SB的盗贼)

去lbrs;(whereever)

拉6个怪(4个elite,2个nonelite);

用demoralizing shout;

所有的怪都来打我;

吃health stone;

队里的3个DPS总是攻击同一个怪。

这种情况下,我hold 所有六个怪的aggro完全
可能;

对每个怪轮流用加aggro的技能或攻击就可以了。
(taunt有关的细节怎么做应该是很明显的。。。)

但是,这和楼主的转贴不吻合。

我所被加的血肯定远远的高出我对任意一个不被dps的怪所属出的仇恨的4倍。


不过,的确,楼主的系统在大部分时候的确是够用了。
 
一直不明白为什么破甲那么容易获得仇恨值
 
好难噢...

看起来好深奥的...

T_T...

先放弃了...

以后再说...
 
后退
顶部