If anyone has been following the Healing forums recently they will have noticed that Ghostcrawler replied to a thread complaining about tracking absorbs (generally attributed to the last cast absorb player rather than the actual player) saying that this was relatively difficult to actually do. He did however give us a call for armchair programmers to try and solve it, so I thought I should look at the problem. The thread is here for anyone interested.

The Problem

Firstly we need to clarify our problem, "absorbs aren't reported" is a very large issue with little breakdown. We can break this down into:

  • Absorbs aren't reported accurately
  • Absorbs aren't attributed to a specific player

Secondly, lets see what Ghostcrawler actually said.
Quote From: Ghostcrawler (source)
"We're still working on showing absorbs. It's technically very challenging. It's not information we currently pass down to the client, and while passing that information down isn't too tricky itself, making sure we can share it without affecting your performance is less trivial."

Tracking Healing

Tracking healing is easy as each heal event is discrete, even residual heal type effects like Prayer of Mending generate discrete healing events. We can break these events down as:

Player casts heal
Server compares current health, heal value, crit, then returns response
Player sees awesome heal, logs show healer is awesome

Tracking Absorbs

In contrast absorbs are only resolved on damage, the cast itself is an independent event. This means we have to track a group of absorbs on the target:

Absorb 1
Absorb 2
Absorb 3
Player Health

Firstly we need to worry about ordering the absorbs, first come first served, first in last out, shortest duration first? Then we need to consider usage, if a PW:S has already lost 50% of its strength, should it be displaced by a new absorb making it more likely the disc priest won't get the bonus mana for the shield consumption before it lapses?

Ok, so we need a working assumption for this. I would say sensibly it should go in shortest duration first (giving us the maximum absorption over time). This means when an absorb is applied we need to store:

Absorb ID - Strength - PlayerID

Each time a hit is resolved, we then have to resolve each of these effects in turn as a discrete, but simultaneous event:

{Damage -> Absorb 1 -> Response / Effects
Apply Effects}

{Damage -> Absorb 2 -> Response / Effects
Apply Effects}

{Damage -> Absorb 3 -> Response / Effects
Apply Effects}

{Damage -> Health -> Response / Effects
Apply Effects}

This makes an absorb far more costly in terms of processing to deal with as a single hit can trigger multiple player's effects on the target as well as multiple absorption calculations, and we need to create multiple responses (though these could be aggregated).

So what does this look like?

Each player / enemy / object now maintains an absorb list sorted in the order we wish to have them handled(95% chance this exists currently, or is handled by buff code)

Each player / enemy / object must now maintain a list of who applied the buff (90% chance this already exists, addons can typically see "playerid"s associated with buffs)

Each hit must now trigger multiple responses (100% chance this doesn't exist or this problem wouldn't exist).

So it should be relatively simple to implement tracking these. The combat log would look like:


20/09 12:00:00 SPELL_ABSORB, 0x00, "Alice", 0x00, 0x01, "Bob", 0x00, 00001, "Power Word: Shield", 0x01, 1000
20/09 12:00:00 SPELL_ABSORB, 0x00, "Alice", 0x00, 0x02, "Clarisa", 0x00, 00001, "Power Word: Shield", 0x01, 10000
20/09 12:00:00 SPELL_ABSORB, 0x00, "Alice", 0x00, 0x03, "Dave", 0x00, 00001, "Power Word: Shield", 0x01, 200
20/09 12:00:00 SPELL_DAMAGE, 0x00, "Alice", 0x00, 0x05, "Evil Dude", 0x00, 00002, "Hitty Spell", 0x01, 0

4 Events each considered concurrent with 3 absorbs and the final player takes 0 damage.

My Conclusions

As an armchair programmer (actually a really nice comfortable leather office chair but ignore that) I don't see why this should be problematic. Absorbs already cannot be simply treated as an additive absorption source (since they are removed over time) meaning the system must track individual absorbs. Each absorb effect should track its owner (to allow for one absorb per caster functionality) meaning our attribution system is present. This means that all the system currently lacks is the reporting mechanism, which is in place but not utilised.

Assuming everything is in place, a few hours coding to get the message responses in place and tested (since something always goes wrong) along the lines of:

@absorb_code / buff_handler
report(..., absorb strength, absorb remaining)

Assuming we lack attribution of identifiers, a few days coding to get it in place since the framework already exists for other buffs so it is a design, port, test scenario.


Larísa said...

Hi there and greetings!

It's been ages since you last posted. Hope you'll get back into it again!


2nd Nin said...

Problem is finding content that interests me :).

Thanks for the read though Larisa, thought you had forgotten me :).

Larísa said...

Hm...I'd say the same... You've forgotten me? You used to write text wall comments, remember?

Don't worry so much abut what to write... just... write!

You don't have to be so damned informative all the time.

What have you been up to in game?
You used to be a bit miserable and desillusioned towards the end of your blogging. Have you settled somewhere and got a renewed interest?

2nd Nin said...

Alas not really, I suddenly developed Altitis... 3 Tanks, 2 Healers, 1 DPS (and possibly a third healer coming up), all in ICC.

Its still ridiculously dull pugging ICC, the expansion as a whole has lacked the feeling of older ones, thought thats perhaps because I have been more at the cutting edge (lol) so have spent far more time farming than otherwise.

I still occasionally write long posts, just I tend to delete them because I feel they don't say enough :).