How GRIP-EMS works
The secure execution environment
WoW runs addon code that interacts with combat in a restricted sandbox called the secure execution environment. Blizzard built this to prevent addons from automating decisions. Things like casting a spell when health is below 40% or using a cooldown when the boss is casting a specific ability are blocked because they would read arbitrary game state to make combat decisions. Inside a macro or sequence step, a meaningful portion of the Lua API is simply not available.
This catches many new users who come from programming backgrounds and assume they can write logic into their sequences. The most common example is trying to check a resource value like combo points or holy power with UnitPower("player") or timing logic with GetTime(). Both of those calls return nil inside a secure handler because they are part of the restricted API. The sequence does not error gracefully, it crashes.
What you can use inside sequence steps is the standard macro conditional system that Blizzard has explicitly allowed: [combat], [mod:shift], [known:SpellName], [noform:1], [nochanneling], and the rest of the documented macro conditional set. These are not API calls. They are tokens the macro engine parses directly and they are permitted because they do not read arbitrary game state.
GRIP-EMS's Variables system exists partly to work around this limitation. Variables are resolved outside the secure environment before the macro compiles, which means you can use them to make conditional decisions that would be impossible inside a step directly.
The left side crashes a step outright. The right side is either a documented macro conditional or a Variables-resolved value baked in at compile time.
Buffs and debuffs are readable through that Variables system, and it is worth knowing exactly what is safe to check and what is not. HasBuff, HasDebuff, SpellReady, and SpellOnCooldown all hand back clean booleans you can build a variable around. What stays out of reach is anything numeric tied to the secret value system: Holy Power amount, combo point count, how many stacks of a buff you are holding, time remaining on anything. Those come back tagged in a way that throws the moment you compare or do arithmetic on them, and there is no trick around it, the CurveUtil approach some WeakAuras use gets tested against the same tag and fails the same way. If the number you actually want has an aura that only exists at that count, checking for the aura's presence instead of the number underneath it is usually the workaround.
There is a second catch worth knowing before you build around any of this. A variable's value gets baked into your macro text once, at compile time, not read live on every press. Put UNIT_AURA in a variable's Events field and it re-evaluates when your auras change and queues a recompile, but that recompile writes to a secure button, which makes it combat locked, so it sits in the out-of-combat queue until you actually drop combat. A buff check built this way settles correctly at the start of a pull and then stays frozen for the rest of it. It does not chase a proc that comes and goes mid-fight. That makes Variables genuinely useful for anything that holds steady across a pull, a talent build, your spec, a raid buff, and not useful for gating a step on a short proc window.
How the step engine actually advances
GRIP-EMS is a Sequential step engine by default, which means it fires step 1, then step 2, then step 3, advancing one step per keypress and looping back to step 1 after the last step. The advance is unconditional. The engine sets up the step, hands the macro line to WoW, and moves the counter on. Whether the spell went out is not something it checks.
What happens on the press is WoW's business. If a /cast names a spell that is on cooldown, the macro engine stops there and the cast lines below it in that same press never run, so the press produces nothing further. A /castsequence sitting on an entry that is on cooldown does the same thing. This is WoW reading your macro text rather than the sequencer making a decision, and it works identically under any addon that drives a macro. Conditional lines are the exception. A conditional that does not apply is skipped and the line after it still gets its turn.
Both halves matter when you place a defensive. A press that cast nothing is not retried, and the step is spent until the loop comes back around. On a 30 step loop clicked every 150ms that is about 4.5 seconds, long enough for Ironfur to drop while the sequence walks the rest of the loop. Shorten the loop, move the step earlier, or give it a per-step interval.
Proc-gated abilities
A step whose line names a spell you cannot cast right now produces nothing on that press, and the step advances anyway. There is no macro conditional that tests a proc. The documented set covers combat, modifiers, form, channeling, whether a spell is in your book and so on, but nothing that reads a buff, so you cannot write a step that fires only while a proc is up.
Where WoW itself swaps the button to the proc version, name the base spell and the swap happens for you. Warrior's Slam becoming Heroic Strike under Bloodsurge is the old textbook case: /cast Slam gets you Heroic Strike while the proc is up, because WoW substitutes the override on the action and you never spend a press on a spell you do not have. The trap is writing /cast Heroic Strike instead, which casts nothing on every press where the proc is down. Adding a second spell after a semicolon does not rescue it either. A clause with no conditional in front of it is always true, so /cast Heroic Strike; Slam picks Heroic Strike every time and Slam never fires.
/cast that fails on cooldown stops the lines under it.[known:SpellName] is not a safe substitute for the override rule above when the spell in question is only ever granted by a talent or a buff rather than owned outright. It resolves through two different WoW APIs depending on how the game currently considers the spell available, and those two APIs can disagree about the exact same spell at the exact same moment. A step gated on [known:SpellName] for something like a temporarily-granted override can read as known by one check and not known by the other, which shows up as the conditional passing in the editor while the step does nothing in practice, or the reverse. Prefer the override rule, base spell name and let WoW substitute, over gating with [known:] whenever the spell is override-shaped rather than a talent you either have all game or not at all.
One guard worth calling out on its own is [nochanneling], which belongs on finisher steps like Rip or Final Verdict. That conditional is what stops the finisher from clipping a channel. Do not add [combat] on top of it, that causes silent failures.
Step functions
GRIP-EMS supports four step functions that control how the engine decides which step fires next. Sequential is the default and the one you will use for most rotations.
Fires step 1, then 2, then 3, loops to 1. One advance per keypress. This is the correct choice for rotations where order matters, including tank defensive cycling, opener sequences, and anything where a spell at step 5 is supposed to come after the spells at steps 1 through 4.
Weights the loop toward the front. The steps are expanded into a longer cycle in which step 1 appears most often, step 2 slightly less often, and the last step once. Advancement is still one entry per keypress. Good for rotations where the early steps should get most of the presses.
The same weighting inverted, so the last step gets most of the presses and step 1 the fewest. In practice this means the tail of your loop fires far more often than the front of it. Avoid it unless that is genuinely what you want.
Fires a random step each press. Useful for very specific situations like randomizing a proc-based spell into different positions to avoid predictable timing. Not useful for structured rotations.
/cast lines. Priority is a weighting tool for press frequency, not that.A Loop nested inside a Priority sequence does not count as one slot in the outer triangle. The compiler flattens the whole tree first, so a Loop unrolls into plain steps that land in the step list right alongside everything else, and Priority runs afterward over that flat list, it never sees the Loop as a unit. Two actions followed by a Loop of three actions repeating twice flattens to 8 steps, so Priority expands to 8 times 9 divided by 2, 36 slots, with the loop's own three actions graded against each other the same way any other steps would be, not as one weighted band. Set the Loop's own step function to Priority as well and it triangles its children first, feeding those already-weighted steps into the outer triangle on top, which compounds fast and is rarely what anyone actually wants.
Understanding modifiers
Modifiers are the single most common source of confusion for new users, and the confusion is almost always the same one: assuming SHIFT, CTRL, and ALT need their own separate keybinds somewhere. They do not. GRIP-EMS binds exactly one key to a sequence, in the Keybinds tab, and that single key is what you press or hold repeatedly. Modifiers ride on top of that same key rather than needing a bind of their own.
Concretely: if your sequence is bound to the 1 key, you never bind SHIFT+1 or CTRL+1 anywhere. You hold SHIFT while pressing 1, and any step tagged with [mod:shift] fires instead of your normal rotation for that press. Release SHIFT and the next press goes back to firing the sequence normally. The same applies to CTRL and ALT.
The guard pattern that makes this work correctly is [nomod:shift, nomod:ctrl] on your normal rotation steps. Without it, holding SHIFT for an emergency heal would also attempt to fire whatever spell is on that step, since the step has no way to know you only wanted the modifier action. Every regular rotation step should carry this guard if the sequence uses modifiers anywhere. The worked example on the Building sequences page shows this pattern applied consistently across a real 30-step sequence.
![A GRIP-EMS step with the [nomod:shift, nomod:ctrl] guard written on its rotation line](/guide/modifier-guard-steps.png)
A rotation step carrying the [nomod:shift, nomod:ctrl] guard, so a modifier press doesn't also fire this step's spell.
If your keybind fires normally but a modifier does not, work through these in order before assuming something is broken in the sequence itself:
If all four check out and modifiers still are not firing, post in the Discord with your CVar Health status, a screenshot of the step's conditional, and whether you have any other addon that binds modifier keys or touches CVars, so it can be looked at directly rather than retreading the same troubleshooting steps.
One more limit worth knowing since it looks like a modifier bug when it is not: the 255 character cap sits on the combined text, not just the step's own line. Key Press, the step's action line, and Key Release get joined with newlines and the whole thing is measured together, per step. Bust that combined total and the step does not error and does not get dropped either, it falls back to running its own action line alone, with Key Press and Key Release left off for that one step only. Every other step in the sequence keeps them. GRIP-EMS tells you when this happens, a chat line on compile naming how many of your steps actually fit the modifiers, and the editor carries a matching fits-in label, so check for that before assuming a step with dead modifiers is broken. The one case that is a hard save-time error is the step's own action line alone going over 255 with no Key Press involved at all, that fails validation outright and will not save until you shorten it.