I'm using some rather strange "operators" here, because I don't want to get confused between "sum of possibilities" and "sequence of operations". (I did in fact get confused by this in my early breakdowns.) So I'll introduce the concepts first.
The ";" operator is a "sequence" operator. "x; y" means "first x happens, then y happens". Sequence is not reflexive: the order matters. "x; y" is not the same as "y; x", for example.
The "&" operator is a bit more complicated. This operator denotes multiple possibilities, each of which has some probability. So "0.3 x & 0.7 y" means that there's a 30% chance that x happens and a 70% chance that y happens. The probabilities involved must sum to 1.0 within a single sequence of "&"s. So "0.3 x & 0.3 y & 0.4 z" is a valid expression, but "0.3 x & 0.3 y" on its own is not, because the probabilities don't sum to 100%.
Parenthesis serve the purpose you expect they serve: They group things up so you don't get confused about whether ";" or "&" takes priority. 
Now, an example of manipulating these a little bit. Let's pretend we have two abilities "X" and "Y". These abilities are a little weird. X starts cooled down, and is the ability we prefer to use. X doesn't cool down on its own--there's a 30% chance of it becoming available after we use ability Y. Hopefully, you can see how this is a toy problem in the same general family as the Sword and Board proc. Anyway, here's how we would write that out:
Code:
p = X; q
q = Y; 0.3p & 0.7q
Here, we start out by defining a state "p", which is our base state: ability X is available. We use X, obviously. Now, X is no longer available, so we use another state to represent the new situation. In this state "q", we must use ability "Y". Afterwards, there's a 30% chance that X has become available (and we return to state p), and a 70% chance that X is still not available, and we remain in state q.
The above two formulas completely describe the system, except for the "base state" part. Now, the next step is that we wish to simplify the above formulas in order to understand things better. How can we manipulate them?
Well, the main things we can do are "substitution" (putting the value of q in place of the symbol q) and "distribution" where we distribute the probabilities of an "inner" sub-expression out in order to see the mix of whole chains of events. That explanation is going to be totally unclear to most people, so let me give an example:
Code:
p = X; q
q = Y; 0.3p & 0.7q
Here are our two equations from before. Let's try substituting the definition of q into the definition of p:
Code:
p = X; Y; 0.3p & 0.7q
So here we've substituted in the value of q in place of the symbol q. Doing so makes things a bit messy, so we use the "distribution" mechanism to simplify a bit:
Code:
p = 0.3 (X; Y; p) &
0.7 (X; Y; q)
We've moved the probabilities all the way to the outside of the equation here, to show the separate possible sequences of events. Unfortunately, this isn't a very interesting result--it hasn't simplified things at all. But what if we instead substitute the definition of "p" into the definition of "q"?
Code:
q = Y; 0.3 (X; q) & 0.7 q
This is a bit interesting. p isn't part of the equation at all any more. We've gotten rid of it completely. Let's simplify:
Code:
q = 0.3 (Y; X; q) &
0.7 (Y; q)
So 30% of the time, we use Y and then follow it with X, and then continue as normal. 70% of the time, we use Y and then just keep going. That's a bit nicer.
Okay. So, that's the basics out of the way. Now on to the real deal.
New notation: When I write "S(x, y)" below, that represents a state. That state is "there are x seconds left on Shield Slam's cooldown and there are y seconds left on Revenge's cooldown". I've done this so you can see the exact reasoning going on. Each state also has a letter assigned, and that "name" for the state will be used later (since it's a lot shorter!)
Note that you'll never see S(6.0, x) for the state. That's because the state we transition to after using an ability is the state after the end of the GCD. So right after we use SS, we go to S(4.5, 0.0): There are 4.5s left on the cooldown of Shield Slam when we get our next opportunity to do anything at all after Shield Slam is used.
Of course, all of the following states are defined assuming that we always wish to use SS in preference to Rev in preference to Dev. And they ignore other abilities.
So here are out states, with S(0.0, 0.0) (both Revenge and Shield Slam are cool) being the base state. The states are listed in order of cooldown left to go:
Code:
SS Rev
S(0.0, 0.0) = a = SS; S(4.5, 0.0)
S(0.0, 0.5) = b = SS; S(4.5, 0.0)
S(0.0, 2.0) = c = SS; S(4.5, 0.5)
S(0.0, 3.5) = d = SS; S(4.5, 2.0)
S(1.5, 0.0) = e = Rev; S(0.0, 3.5)
S(1.5, 2.0) = f = Dev; S(0.0, 0.5)
S(1.5, 3.5) = g = Dev; S(0.0, 2.0)
S(3.0, 0.0) = h = Rev; 0.3 S(0.0, 3.5) & 0.7 S(1.5, 3.5)
S(3.0, 0.5) = i = Dev; 0.3 S(0.0, 0.0) & 0.7 S(1.5, 0.0)
S(3.0, 3.5) = j = Dev; 0.3 S(0.0, 2.0) & 0.7 S(1.5, 2.0)
S(4.5, 0.0) = k = Rev; 0.3 S(0.0, 3.5) & 0.7 S(3.0, 3.5)
S(4.5, 0.5) = l = Dev; 0.3 S(0.0, 0.0) & 0.7 S(3.0, 0.0)
S(4.5, 2.0) = m = Dev; 0.3 S(0.0, 0.5) & 0.7 S(3.0, 0.5)
Now let's list those out using just the letter designations and then we'll start simplifying.
Code:
a = SS; k
b = SS; k
c = SS; l
d = SS; m
e = Rev; d
f = Dev; b
g = Dev; c
h = Rev; 0.3 d & 0.7 g
i = Dev; 0.3 a & 0.7 e
j = Dev; 0.3 c & 0.7 f
k = Rev; 0.3 d & 0.7 j
l = Dev; 0.3 a & 0.7 h
m = Dev; 0.3 b & 0.7 i
The first thing to notice is that we can eliminate one of these because it's identical to another. a and b both have the same behavior--in both of them, we use Shield Slam next, and in both of them Revenge is cool on the next GCD. We remove b and replace b with a everywhere. So with that first pass of simplifications:
Code:
a = SS; k
c = SS; l
d = SS; m
e = Rev; d
f = Dev; a
g = Dev; c
h = Rev; 0.3 d & 0.7 g
i = Dev; 0.3 a & 0.7 e
j = Dev; 0.3 c & 0.7 f
k = Rev; 0.3 d & 0.7 j
l = Dev; 0.3 a & 0.7 h
m = Dev; 0.3 a & 0.7 i
The next step is to start substituting and distributing a bit. I will always distribute fully after this point, because otherwise things start to get really confusing. Let's start with that.
Code:
a = SS; k
c = SS; l
d = SS; m
e = Rev; d
f = Dev; a
g = Dev; c
h = 0.3 (Rev; d) & 0.7 (Rev; g)
i = 0.3 (Dev; a) & 0.7 (Dev; e)
j = 0.3 (Dev; c) & 0.7 (Dev; f)
k = 0.3 (Rev; d) & 0.7 (Rev; j)
l = 0.3 (Dev; a) & 0.7 (Dev; h)
m = 0.3 (Dev; a) & 0.7 (Dev; i)
And now let's do some subtitutions. We'll distribute at the same time. Our first set of substitutions will be putting k, l, and m into a, c, and d, because those are the only places that k, l, and m occur. That way we can remove those equations completely.
Code:
a = 0.3 (SS; Rev; d) & 0.7 (SS; Rev; j)
c = 0.3 (SS; Dev; a) & 0.7 (SS; Dev; h)
d = 0.3 (SS; Dev; a) & 0.7 (SS; Dev; i)
e = Rev; d
f = Dev; a
g = Dev; c
h = 0.3 (Rev; d) & 0.7 (Rev; g)
i = 0.3 (Dev; a) & 0.7 (Dev; e)
j = 0.3 (Dev; c) & 0.7 (Dev; f)
Next we'll substitute e, f, and g into h, i, and j. These are very simple, and again it allows us to eliminate more equations:
Code:
a = 0.3 (SS; Rev; d) & 0.7 (SS; Rev; j)
c = 0.3 (SS; Dev; a) & 0.7 (SS; Dev; h)
d = 0.3 (SS; Dev; a) & 0.7 (SS; Dev; i)
h = 0.3 (Rev; d) & 0.7 (Rev; Dev; c)
i = 0.3 (Dev; a) & 0.7 (Dev; Rev; d)
j = 0.3 (Dev; c) & 0.7 (Dev; Dev; a)
And now we'll put h, i, and j into a, c, and d. And this should show you why I've been distributing the probabilities this whole time, because it starts to get a bit hairy.
Code:
a = 0.3 (SS; Rev; d) &
0.7 (SS; Rev; 0.3 (Dev; c) &
0.7 (Dev; Dev; a))
c = 0.3 (SS; Dev; a) &
0.7 (SS; Dev; 0.3 (Rev; d) &
0.7 (Rev; Dev; c))
d = 0.3 (SS; Dev; a) &
0.7 (SS; Dev; 0.3 (Dev; a) &
0.7 (Dev; Rev; d))
That's with it un-distributed. And once we distribute it out:
Code:
a = 0.30 (SS; Rev; d) &
0.21 (SS; Rev; Dev; c) &
0.49 (SS; Rev; Dev; Dev; a)
c = 0.30 (SS; Dev; a) &
0.21 (SS; Dev; Rev; d) &
0.49 (SS; Dev; Rev; Dev; c)
d = 0.30 (SS; Dev; a) &
0.21 (SS; Dev; Dev; a) &
0.49 (SS; Dev; Dev; Rev; d)
Now, here's the interesting thing. Remember the "p" and "q" example way back? We were able to simplify the "rotation" down to a single state, q, and describe the long-term behavior of the system in terms of just that one state (even though it wasn't our start state.)
But with this, we can't do that: these three states above are impossible to unify into a single state--each of them is defined in terms of itself and the others at the same time. And, if we look closely, we can see why no further simplification is possible.
What these three states represent is "to what degree are the cooldowns for Shield Slam and Revenge 'out of phase' with each other?" State "a" occurs when Revenge will be ready immediately after performing a Shield Slam. State "b" occurs when Revenge will be ready one GCD after performing a shield slam. State "d" occurs when Revenge will be ready two GCDs after performing a shield slam. The transitions to the different states occur depending when the S&B proc happens (or doesn't happen.)
In the cases of states "a" and "c", a "one GCD early" shield slam will move to the next state in line, and a "two GCD early" shield slam will move two states forward. In the case of "d", both varieties will move to "a" because in the "two GCD early" case, the Shield Slam itself will eat up the necessary time to get Revenge ready. (And that's the same reason we ended up eliminating state "b": The Shield Slam always ate up the necessary 0.5 seconds in that state, leaving it identical to state "a".)
Okay, so that was long and convoluted. What can we learn from this?
The first thing is that our "four GCD rotation" is totally gone. The procs from S&B will cause early Shield Slams in 51% of Shield Slam cooldown periods. Because this behavior is now the same across both Devastate and Revenge, we can calculate the average cooldown of Shield Slam: 0.3 * 3.0 + 0.21 * 4.5 + 0.49 * 6.0 = 4.785. So with S&B, we'll get to hit Shield Slam on average every 4.785 seconds.
The second thing is that Revenge will get used a bit less often than it used to be. Why? Not because we want to avoid it in favor of Devastate, but because Shield Slam will occasionally become ready at the same time as Revenge. Specifically, in the first case of state "c" and the second case of state "d" this will occur. I don't think this is a bad thing: It just arises from the priority of which skill produces the most powerful threat, and the fact that the two abilities will go in and out of phase from each other based on random procs. If it's any consolation, Devastate use is reduced even more. And the "missed uses" from both abilities are of course going to Shield Slams instead, which is a net win.
The third thing to note is that state "a" will be in effect somewhat more often than the other states. I haven't figured out how to calculate the actual proportion of times spent in each state, yet (a simulation could estimate this pretty easily, though), but... Here's the deal. First, state "d" will never transition to state "c". Second, state "a" will transition to state "d" more often than to state "c", and state "c" will transition to state "a" more often than to state "d". The end result is that state "a" will happen a bit more often than the other states.
I invite anybody who wish to use these state definitions to calculate the actual time spent in each state (which will automatically imply the relative numbers of uses of each ability, since it's easy to calculate the probabilities within a single state.)
Bookmarks