Modeling Seal of Insight

Seal of Insight is the last major paladin mechanic that has yet to be added to the simulation. The last piece of the puzzle, as it were. There are a number of reasons I’ve put off adding SoI, some of which I discussed in the lasttwo posts.

SoI is a more complicated beast than effects like Sacred Shield, for starters. It has a lot of “moving parts” as far as the simulation is concerned. While we don’t have to cast it, it requires adding melee swings to the simulation, which means adding another event type. It also adds another buff to track in the form of our fake absorb bubble, and we’ll need a model to calculate the effectiveness of that bubble. And since we’re adding melee swings, we also need to add parry-hasting if the model is to be completely accurate. That doesn’t mean any of the logic is particularly hard, just that it has tendrils in several sections of the simulation, which makes it annoying to implement and bug-check.

It also causes a moderate performance hit. First, from the inclusion of another event type (melee swings), and then from the additional calculation being performed each time that event occurs. There’s also a small performance decrease due to the extra calculations on the SoI absorb bubble. Together, that all added up to be a bit of an issue. Performance had been a problem with the simulation in general even before this point, and now seemed like an appropriate time to fix it.

I enlisted the help of a friend of mine who happens to be a real computer scientist type, and he promptly told me to stop thinking like a physicist and start thinking like a computer scientist. Together we (and by we, I mean he) hashed out a few improvements that would drastically improve performance. To give you an idea of how significant that improvement was, it now runs about five to six times faster than it did before I added Seal of Insight. Runtime dropped from about 400-500 seconds per simulation to around 60 seconds.

So now that it’s implemented, I can spit out lots and lots of data relatively quickly. But first, we need to discuss exactly how we’re modeling Seal of Insight, and provide some justification for that model. That will be the topic of today’s post.

Effectiveness – Logs

The first part of modeling is figuring out exactly what we’re aiming for. One of the big arguments about Seal of Insight is how much of it ends up simply being overhealing. It’s going to be important to get that right, so rather than guess, we go to the logs and see what they say. I scrutinized about 20 different logs from the last month for a variety of guilds ranging from normal-mode to heroic-mode content in both 10- and 25-man categories. While this only gives me a few data points per individual boss, it’s enough to get a rough idea of how much overhealing we expect. Here are the numbers:

Boss

10N

10H

25N

25H

Jin’Rokh

66%

68%

66%

77%

Horridon

53%

62%

74%

74%

Council of Elders

51%

31%

64%

60%

Tortos

54%

N/A

68%

N/A

Megaera

41%

44%

46%

60%

Ji-Kun

62%

52%

65%

77%

Durumu

57%

60%

56%

68%

Primordius

38%

32%

60%

46%

Dark Animus

52%

58%

46%

49%

Iron Qon

47%

61%

46%

60%

Twin Consorts

59%

72%

72%

Lei Shen

51%

60%

That’s a lot of overhealing. This data doesn’t suggest that there’s a huge difference between 10- and 25-mans. And note that there’s a mix of data in here. Some logs are from solo-tanking a boss, while some are from multiple-tanking; some tanks are on boss duty while others are on adds. So there are larger variations to be had on a situational basis.

The lack of distinction between 10- and 25-man seemed a little strange at first. My intuition is that in 25-mans, you’d expect a dedicated tank healer, leading to higher overheal values for SoI. In 10-mans, I’d expect the “tank healer” to split his attention a lot more to help with raid healing, and thus allow SoI to pull more weight. But while there may be a little of that happening, it’s not a large effect. We’re not seeing many cases where we get double the overhealing in 25-mans (Primordius stands out, but I suspect that’s due to 1- vs. 2-tanking distinctions).

To take a look at why that is, I looked a little more carefully at my own healing taken breakdowns. And I was actually a bit surprised by what I found.

First, Sacred Shield and Seal of Insight regularly produce 35%-50% of my total healing taken. That Sacred Shield is consistently 20%-30% isn’t all that surprising – absorption effects are your first line of defense against damage, so they’ll naturally be pretty efficient and will tend to get utilized. But Seal of Insight fairly regularly shows up in second place, accounting for 10%-20%. That’s a bit higher than I expected, to be honest – I thought that when we’re pushing 60%-70% overheal, it would account for much less.

But what’s more surprising is the sheer amount of healing that’s coming from passive sources. When I totaled up the amount of healing coming from “passive” sources, including HoTs and incidental absorbs, it was 75%-80% of all healing I received. Only 20%-25% is due to “direct” healing, like Holy Light, Divine Light, Nourish, Healing Touch, etc.

Now, that’s considering all healing done, including overhealing. You might assume that the passive sources show a much higher amount of overhealing than the direct sources. And to a limited degree, that intuition seems correct. But even the direct heals are seeing a large amount of overheal. Holy Light and Nourish regularly clocked 60%-80% overheal in my logs. Big heals like Healing Touch and Divine Light tended to be lower, ranging from 30% to 50% from boss to boss.

From all of that, we can draw a few conclusions. First, we’re a long way from the “spam Holy Light on the tank” healing model of Wrath. The triage model seems to be working correctly, with healers dropping efficient, low-cost heals (HoTs, Holy Light) on the tank when the situation is relatively safe, and only resorting to big or fast direct heals when they’re needed. This also explains the similarities between the 10- and 25-man data; in both cases, a dedicated “tank-spamming” healer really isn’t necessary most of the time.

Second, I think it reinforces this idea that spike damage is the only dangerous damage. We’re blanketed with an incredible amount of healing from passive sources, so low-throughput sections of an encounter will rarely cause a death. It’s really those situations where we take a sudden spike of damage that our healers even reach into their toolkit for the big, fast heals. And the best thing we can do to survive is to reduce the number of times they need to do that and buy them as much time as possible in the cases where they do.

But most importantly, it’s somewhat amazing how much self-healing we really do. In many cases, we’re not even receiving direct heals, and just being kept afloat by HoTs and our own healing contributions. It also means that it’s probably not fair to toss aside SoI as irrelevant because of the sheer amount of overhealing it does. A lot of that overhealing happens during the stable, low-throughput situations that we don’t care that much about. But during a spike, the amount of overheal will be very small. And while it’s not guaranteed healing since SoI is a proc mechanism, it’s still going to give us some degree of buffer against those spikes because it’s passive. There’s no reaction time involved – it just happens when it happens, which means some of the time it will be there exactly when it needs to be.

Overhealing and Effective Overhealing

The other thing to consider is that this isn’t the entire story. This is the overhealing that World of Logs registers, but it’s not representative of the effective overhealing. To explain that thought, consider the following situation. You take 30k damage, and within the next second you get a 30k SoI proc, a 30k Rejuvenation tick, and a 60k Holy Light. Any one of them brings you up to full health individually, so which one overhealed?

The game and World of Logs will register the first heal received as being effective, while the latter two will be recorded as overhealing. But that’s not very realistic – for example, if the SoI proc hadn’t happened, the Rejuvenation tick would have healed you to full anyway. So you end up in the same state whether the SoI proc occurred or not. In some sense, the SoI proc was completely irrelevant, because it didn’t do anything effective for your survivability in that situation thanks to the competing heals. Right?

Well, you could make the same argument about the Rejuvenation, or the Holy Light. It’s not entirely clear which of the three should get credited with overhealing, because any two of the three are irrelevant depending on your perspective. But they weren’t all irrelevant, because clearly one of them did something.

This is one problem with logging. It will always credit the early heals, but can’t easily figure out how much overhealing those heals create later on. In the case of Seal of Insight and Rejuvenation, I think you could argue that the difference comes out in the wash. It’s probably about equally likely that the Rejuv tick follows the SoI proc as it is for the reverse to happen. So the logs probably already account for this interaction between passive effects. But when it comes to the direct heals that have a cast time, these periodic ticks and procs eat away at the effectiveness. You may have benefited from the entire Holy Light at the time the cast started, but half of it may be overheal by the time the cast finishes.

So while we might see 60% overhealing for Seal of Insight in a given log, it’s likely that it’s created some non-trivial amount of overhealing in our direct heal accrual. It’s very hard to say exactly how much that will be without looking at specific logs, and it’s likely to vary significantly based on healer composition. A tank being healed by a Restoration Druid and a Holy Paladin’s Beacon of Light is going to have a very different amount of direct heal contribution than, say, a Restoration Shaman and an Atonement/Discipline priest.

But this raises some obvious questions about how to accurately model SoI. Do we try and model it with the overheal values given by World of Logs? Do we aim a little higher to account for heal-sniping? If so, how much higher? And how exactly do we implement that overhealing?

Overhealing Implementations

I’ve had a number of conversations about this topic over the past week, and gotten a lot of different answers. If you recall, we model heals in the code by granting small absorption bubbles that last for a limited amount of time. We model overhealing by adjusting the size of these bubbles.

Of course, there’s the simple method that we’ve used previously with Word of Glory, which is to just reduce the size of every single heal by a certain amount to account for overhealing. In other words, if we want approximately 50% overhealing, we just halve the size of each SoI proc. The downside is that this version doesn’t adapt to damage intake, so an SoI proc occurring after a few avoids gives us the same absorb bubble as one occuring after three full melee hits in a row, even though the latter is far less likely to be overhealing than the former.

We could be a little more sophisticated and include a degree of randomness to the size of the overheal bubbles. Rather than using a half-sized bubble to represent 50% overhealing, we could just roll the dice for each proc. We’d grant a full-sized bubble 50% of the time, and no bubble the other 50% of the time. That “random binary” model would probably mimic the randomness of heal-sniping pretty well, but it still doesn’t give us a method that adapts to damage intake. In the comments of a previous blog post, Weeby and I discussed using a discrete set of different probability distributions, dynamically choosing which one we use based on prior damage intake.

The method I originally thought about using was to implement an adaptive overhealing function. Basically, every time we got an SoI proc we would calculate the amount of overheal for that proc based on the previous few boss attacks. The functional form is a little bit arbitrary, but the essential characteristics I had in mind were as follows:

If we took very little damage in the last few attacks, then the SoI proc should do basically nothing, because passive heals from other sources will top us off.

If we took a lot of damage in the last few seconds, the SoI proc should be 100% effective, as we can use all the healing we can get.

In between those extremes we should have a continuous variation in effectiveness.

The function I had in mind is one encountered commonly in solid-state physics: the Fermi-Dirac distribution, or “Fermi function” for short. The Fermi function is actually the inverse of what we want – it takes on a value of one for small $x$ and a value of 0 for large $x$, and we want the reverse, so the modified form I used is this:

$$\large f(x)=\frac{1}{1+e^{-(x-x_0)/\sigma}} $$

where $x_0$ and $\sigma$ control the size and shape of the transition. If we plot this function, it looks something like this:

Example of the fermi function for $x_0=1.5$ and $\sigma = 0.15$.

On the y-axis we have the effectiveness of Seal of Insight, while the x-axis it the sum of the damage from the last three boss attacks. By setting the halfway point at $x_0=1.5$ we end up with about 75% overheal, which is a little on the high end of our estimates. But we can tweak $x_0$ and $\sigma$ to match the function to whatever level of overheal we’d like.

There are a few problems with this method, though. It’s very deterministic by design, so if you take 2-3 full attacks in a row, you’re always going to get full strength SoI proc. But there are situations where that isn’t an accurate model. For example, if you receive a Lay on Hands immediately after the third attack, any subsequent SoI procs are basically useless. And on the other extreme, if you only take a few very weak hits in a row while your healer is distracted, those SoI procs will just heal you up and allow the healer to focus on whatever they’re doing.

So while I like this idea, I also think it introduces a lot of complexity without really accomplishing much. We could probably get a similar effect by just assuming a flat amount of overhealing on every SoI proc or using one of our random models (binary or discrete set).

One school of thought is to not include overhealing interactions at all – every SoI acts at full strength, no matter what. The reasoning is pretty simple: we can’t turn it off. It’ll be there when it occurs no matter what, regardless of what or how many healers you have. The healers can choose to use that GCD in another way, but our only choice is to swap seals to a mediocre DPS seal.

There’s another argument for full-strength SoI. We care most about the high-damage spikes, and those are situations where SoI tends to do less overhealing. We care about healing during that critical time between the start of the spike and our healers reacting and dumping heals on us, and pretty much every SoI heals for its full amount during that window. So by assuming SoI is full strength, we probably get a fairly accurate representation of how it works during the danger periods that we care about most. The downside is that during low-damage periods, we’ll be overestimating its value during the low-damage periods, which will skew our TDR metrics. But if we’re not that concerned about those low-damage periods anyway, maybe that’s OK.

Backwards-Facing vs. Forward-Facing Modeling

There’s another issue that I’ve been wrestling with for the past few weeks, which is how to model healing more effectively. The absorb bubble method I’ve been using is a little artificial, in that it makes healing apply to future attacks rather than previous attacks. But of course, in practice healing replaces damage that’s already occurred. I think you could make a good argument that healing is essentially giving you extra hit points that future attacks need to chew through. But it’s also not a very intuitive model for most people.

Instead of this “forward-facing” method, we could use what I call a “backward-facing” method. For example, when we get an SoI proc, we just apply it to a previous attack and reduce the damage that attack did retroactively. This better matches peoples intuition for how healing works, and doesn’t end up to be much more computationally expensive than the forward-modeling method.

In a pure stochastic sense, it shouldn’t matter which we do as long as the size of the SoI proc doesn’t depend on the attacks surrounding it. We’re just as likely to avoid the attack before an SoI proc as we are to avoid the attack afterward. But when you start putting any sort of time dependency into the simulation you get some subtle differences in the results the two modeling methods give you. And we have a lot of that going on in our system.

For example, SotR itself biases the results. SotR is a proc trigger for Seal of Insight, and the attack after a SotR cast is about 50% smaller on average than the attack before a SotR cast. As a result, if you use the forward-facing model, you’ll get more overhealing overall because those procs are being applied to smaller attacks. The backward-facing model doesn’t have that same bias. Parry-hasting causes a similar effect, but in reverse: a parry results in 0 damage taken and increases the likelihood of a proc, which causes slightly higher overhealing in the backwards-facing model.

Dynamic overhealing models and Sacred Shield absorbs can enhance or suppress some of those effects, causing further perturbations. And the SH finisher models create even more complicated interactions between all of those components, because they moderate SotR usage based on damage taken in the last few attacks. Thus, SoI procs can suppress SotR casts in the backwards-facing model or exacerbate the overhealing caused in the forward-facing model.

I’ve modified the code to be able to handle both methods, but I think I’m probably going to transition to the backwards-modeling case. It’s easier to explain, for starters, and I think it’s a little more intuitive. But most importantly, I think it tends to be a little more realistic due to the interactions with SotR, especially for conditional finisher queues. I’ll probably convert WoG over to the backwards model as well so that I can more naturally incorporate the effects of overhealing, and even come up with queues that only use WoG if it will not be wasted.

Going Forward (But Healing Backward!)

Now that the code’s been updated, we just have to settle on the correct way to do the modeling. We have a lot of options, but despite all of the sophisticated techniques we have to employ overheal modeling, I’m actually leaning towards the “no-overheal” method, where every SoI proc occurs at full strength. If we’re mostly concerned with large damage spikes, then this model seems like it would do the best job of accurately representing how SoI affects those peaks. It does come at the cost of reducing the accuracy of our information during the low-damage periods, though.

It’s possible we could use the Fermi function to adjust for that by setting a fairly low threshold $(x_0)$. But I’m a little hesitant to do that, because the whole thing feels fairly artificial to me. It might give us the behavior we think we want, but it’s hard to trust data if we’re not sure we trust the model. At least with the “full-strength” SoI model, we’re aware that we may be over-estimating its effectiveness in certain situations, as well as which situations those are in particular. And the backward-facing SoI method tends to reduce the impact of dynamic overhealing modeling anyway, so maybe it’s unnecessary.

Even with the “full-strength” SoI model, we get a fair bit of overhealing. For starters, we’re only applying Seal of Insight to adjacent melee attacks – in other words, with the backward-facing model we only look one attack into the past. So if we avoided the previous attack, that SoI proc is all overhealing, because there’s no damage to remove. The same can be said of the forward-facing model if we avoid the following attack.

And on top of that, we get some overhealing due to other mitigation effects. Multiple SoI procs, for example, can reduce a blocked or mitigated attack to zero damage. Keep in mind that each SoI proc is approximately 20% of a boss attack, making it almost as large as a block. Three SoI procs following a SotR-mitigated block is enough to null out all of that damage. And in a high-haste set, we get about 25% more SoI procs than we do boss attacks, so we expect about least one SoI proc per attack, and often get clumps of 3 (melee+SotR+CS all falling within 1.5 seconds).

When you throw Sacred Shield absorbs into the mix, you can get situations where even a single SoI proc is predominantly overheal. In my testing, with Sacred Shield turned off we get about 19% overhealing due to our ~19% avoidance, but with Sacred Shield turned on we rocket up to about 33% overhealing. About 6% of that difference is due to full absorbs via Sacred Shield, but the last 8% is due to multiple SoI procs.

I think that it’s worth dwelling on the block analogy here. In the past, we’ve discussed how mastery gives us an active benefit (SotR mitigation) and a passive benefit (block chance), while haste primarily gives us an active benefit. But if we include Seal of Insight, that’s not really the case. Haste also gives us more passive SoI procs, which act like slightly smaller blocks. So both stats give us a fairly significant passive benefit, though in haste’s case it does still rely on us following a rotation and attacking the target.

In any event, I think that many people, myself included, haven’t been giving Seal of Insight enough credit. I’ve generally written it off as a fairly small effect, and didn’t think too much about it because of the sheer amount of overhealing involved. But if you asked me if I’d like a bunch of free 20% mitigation blocks, I certainly wouldn’t pass that off as irrelevant. As long as some of them are occurring during a spike period, I’d care. And given how frequently we get procs in a haste set, we’re almost guaranteed to have at least $N$ procs within any given string of $N$ attacks.

I hope to have some data ready to publish later this week, as things are finally starting to slow down in real life. I may put up a post comparing and contrasting several of the different SoI modeling techniques to see what, if any, difference they make in the overall data. It’s possible that for all of my agonizing over the different models, they all give more or less the same results, at which point maybe we don’t need to worry as much about scrutinizing the model in the first place.

15 Responses to Modeling Seal of Insight

This post reminds me of how my wife and I interact with code. She’s the engineer/matlab coder, and I am the Computer Science/professional coder. We’ve had similar encounters where she’ll send me slow code to have me optimize it for a near order of magnitude speed increase.

I completely agree with your “SOI full strenght” choice. The real situations where SOI is usefull occur when we get spike damage and I´m saying this cause I´m playing Holy on the free times, and Paladin´s Eternal Flame Hot is very strong, almost getting me free to worry about damage on tank during normal damage times. So, what I want know is how much SOI smooth our damage intake, than, your modelling, I think, is going to the right way. Congratulations for the great job! Note: My guild is not hardcore (2/12N) so, in 505~ gear average (myself prot 510), I´m finishing on the knees of the Healing team, so, SOI effect on the entire group is not negligibe, despite that is not the main concern of your study, but a point to note on the advantages to the C/Haste build. Anyways, sorry for the bad english!

Isn’t leaving it always on going to mess with the numbers? Aren’t you simulating how many times certain bad situations would occur ( like a 90% spike for instance ), and wouldn’t they occur less if it always procced? Especially with the backwards method.

Besides it would be a shame to start messing with the TRD numbers. Since they where quite accurate before. Even though we don’t care about them much, it was still nice to see where your secondary ( or lower ) worry ended up at.

Yeah, the proc chance is included (i.e. it’s not guaranteed on every melee swing). All I’m saying is that in practice, procs that occur while you’re avoiding 3 attacks in a row are meaningless, because you’re probably already at full health. To model that here, we’d need a dynamic overhealing function to weaken the value of procs during those periods and leave the ones that occur during dangerous spikes alone.

Which we could do, but it’s a lot of work for not much benefit. It won’t have any effect on the top three or four levels of representation anyway, which is all we look at. It will thin out the numbers below that, but we ignore them anyway.

As far as TDR, it won’t change that much. Overall damage taken will be lower, obviously, and specs with smoother damage will probably see a little lower TDR than they “should” if more of those procs were overheal. But even that is subjective, since it forces the assumption that you overheal a lot. When in reality, your healers could spend those GCDs elsewhere.

Another question. Going a bit off topic here but this has been on my mind for a while. It concerns the metrics in general, but this post reminded me of it.

In the simulations we mainly look at spike damage and not at sustained damage. I remember a while back in icecrown there was a discussion about armor and we ended up concluding that there was spike damage, and slow death ( trickly down death ) . Now I am going to asume ( I have missed a bit ) that since then the slow death has been incorporated and is represented by the long spikes here ( 6 or 7 hits ) . So that should be covered.

However that doesn’t have me fully convinced that throughput alltogether isn’t an issue at all. We know mana isn’t, but is hps? The whole slow death idea was about the fact that if a healer can’t keep you topped during a long spike, that the extra health was useless and should be converted into mitigation ( not avoidance ) .

Now this post makes it very clear that throughput in general isn’t an issue at all. But what about during long spikes. I am especially wondering this since in this post you again brought up the possibility of underestimating extra heals during spikes. And extra hps is comparable to mitigation.

In the end we could wonder if we have any mitigation alternatives to health. There are plenty of stats but nothing is always on. There is no real effective health increase like armor.

I hope the question makes sence like this. I have a bit of trouble figuring how to put it. It is quite possible this was already answered and I missed it.

The “slow death” or “trickle-down death” concept was not so much that a healer *couldn’t* keep up with the throughput of a long spike, but that they didn’t. I would argue that while most tank deaths are probably trickle-down deaths, it’s not because healers are incapable of the amount of throughput required.

Rather, it’s a switching time argument. They can’t keep high throughput up all fight, of course, nor do they need to. Instead, they use high-efficiency heals like HoTs to handle the low-throughput phases, and then switch into high-throughput mode when they see the tank dip significantly. The speed at which they make that switch dictates whether you live or die – if they do it instantly, you’re safe and topped off; if not, you might be in trouble.

Both mitigation and stamina extend that time. I think the “extra health was useless” argument was heavily overplayed even in ICC – extra health is rarely useless, not the least of which because bosses do not hit for fixed amounts. Boss melee swings have a pretty broad range of damage values, and then there’s magical/environmental damage to consider.

The simulation covers most (all?) of the mitigation choices we actually have. Reducing spike size increases the average time healers have to react, so looking at spike data essentially ranks the stamina and mitigation options in those terms.

Just did some testing, and with the SoI model in the post that’s going live in about an hour, a set that trades all 12000 haste for 12000 STR trails C/Av, but still leads the pure avoidance set by a good bit. Note that this is also being generous with the conversion ratio, since if you’re doing this with gemming it would be 12k haste for 6k STR, making it even worse.

In that sense, STR is worse than avoidance. Comparing it 1:1 to parry, it would be a little better, but comparing it 1:2 it’s worse because most of the value comes from the avoidance, and you only get half as much.

Theck, I just saw a twitter post by Ghostcrawler that they are thinking about implementing a major change in the Vengeance cap: 30% of health in 10s and 50% in 25s. Obviously that is highly speculative, and they may change the numbers or decide not to make the change at all. I personally think they are going to make some kind of change; I think the idea of tanks leading the dps is something they want to squish, at least a little. Will this further nerf haste builds? I know from a survivability aspect the dps doesn’t matter, but less attack power would mean weaker SoI and SS, right?

It’s of no consequence, because both of those are above the Vengeance levels that you normally see in content. If we were regularly exceeding 50% of our health in Vengeance, then it would act as a limiting valve. Ironically, that would just strengthen Stamina even more.

I only raid 10 man so I’m looking at the 30% value which has me a little concerned.
For most fights on heroic 10m it’ll make no difference but looking through some of my fraps there’s a few fight’s where it’ll be quite a large nerf.

During the last phase of Horridon I get 220-300k veng which is well above the proposed cap with the 674k fully buffed hp I had on early kills.

Solo tanking Tortos I never drop below 180k veng and while bats are up I stay between 250-280k (bats are on me 80% ish) that’s with 740k hp.

On Iron Qon i’ll end up with 260k veng while all 3 dogs are up and only 680k hp.

Those are edge cases but even so they make me a little worried if they go with 30% cap for 10 man.
To me it also seems like there could be a bigger jump in boss damage next tier than our hp making it easier to hit a 30% cap.