LazyGrip logoLazyGrip.net
Sign inSign up

How GRIP-EMS works

Before you build a sequence, you need the right mental model. Three things in particular will save you hours of confusion: what WoW's secure execution environment actually restricts, how GRIP-EMS advances through steps, and what WoW does with the macro line on a step once the addon hands it over.

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.

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.

If the proc version is a genuine override of the base spell, write the base spell. If it is a separate spell with its own availability, accept that some presses on that step do nothing, and keep anything else you need on that same step above the proc line, because a /cast that fails on cooldown stops the lines under it.

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.

SequentialDefault

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.

Priority

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.

Reverse Priority

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.

Random

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.

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.

If you are looking for a place to bind SHIFT+1 or CTRL+1 specifically, stop looking. There is no such setting because that is not how modifiers work in GRIP-EMS. One keybind per sequence, modifiers layer on top of it.

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.

If your keybind fires normally but a modifier does not, work through these in order before assuming something is broken in the sequence itself:

1. Check the step itselfOpen the sequence in the editor and confirm the step you expect actually has the [mod:shift] or [mod:ctrl] conditional written on it. A missing tag on the step is indistinguishable from a firing bug until you look.
2. Check CVar HealthRun /gems settings, go to Cvar Health, and confirm it is green. The same key-down requirement that governs your base keybind governs modifier presses too.
3. Check your other WoW keybindsOpen your normal WoW keybind menu, not GRIP-EMS, and search for anything already bound to SHIFT, CTRL, or ALT combined with your sequence key elsewhere in your bindings, action bars, or another addon. A conflicting bind claimed by something else silently eats the modifier press before GRIP-EMS ever sees it. This is a confirmed, recurring cause: several users have fixed dead modifiers entirely by clearing out unrelated modifier-key bindings that had nothing to do with GRIP-EMS on the surface.
4. Reset all your WoW keybindsIf steps 1 through 3 all check out clean and modifiers still are not firing, a full keybind reset in WoW itself (not just GRIP-EMS) has resolved this for other users even when no specific conflicting bind was ever found. It is a blunt fix and you will need to rebind everything afterward, but it works when nothing else does.

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.

The Pause step

GRIP-EMS includes a dedicated Pause step that holds the sequence without attempting a cast. It has three variants and they behave differently depending on what you need.

ClicksHolds for a set number of keypresses before advancing. Good for spacing out high-cost abilities that need a fixed number of GCDs between them.
MillisecondsHolds for a set duration regardless of keypresses. Useful when you need a hard time gate between steps rather than an action count.
GCDHolds for one or more global cooldown cycles. The safest option for finisher spacing since it adapts to your actual GCD rather than a hardcoded time value.

The Pause step is most commonly needed for specs with strict GCD relationships between abilities, for example preventing Steady Shot from firing too close to a proc window in Marksmanship Hunter. If you find a spell clipping something it should not, a one-GCD pause before that step is usually the fix to try first.

Reset conditions

Reset conditions send the sequence back to step 1. GRIP-EMS supports five of them and they can be combined.

Reset on combatResets to step 1 when you leave combat. Most tank and DPS sequences should have this enabled so your opener fires at the start of each pull.
Reset on targetResets when your target changes. Useful for sequences with a target-specific opener that you want to replay on each new target.
Reset on specResets when you change spec. Usually unnecessary if your sequences are spec-specific.
Reset on gearResets on gear swap. Relevant if you use gear sets that change your stat priorities mid-session.
Timer resetResets after a set number of seconds without a keypress. Useful as a fallback to catch sequences that got stuck mid-rotation during an interruption.

Skyriding and mount behavior

Pressing your sequence keybind while skyriding behaves differently depending on whether you have a valid target.

Valid target below youOne press dismounts and fires step 1 in the same action. No separate dismount required.
No valid targetThe press falls through to your skyriding action bar as if GRIP-EMS is not active. Your normal skyriding controls are unaffected.

This requires Auto Dismount in Flight to be enabled in your WoW settings. Druids also need Auto Unshift enabled to exit skyriding Travel Form mid-air with the same single press.

Getting dazed off a skyriding mount mid-pull used to leave your sequence keys dead until you dropped combat. That is fixed. The swap to your ground action bar now happens the moment you land, combat-safe, so your keys are ready the instant you hit the ground.

There was a separate bug on first takeoff of a session where ground binds stayed live mid-air or vehicle keys never woke up at all. That is also fixed. The out-of-combat watchdog now heals the swap at takeoff and restores it on landing, so the first flight of every session behaves the same as every other.

Context switching and multi-version sequences

A single sequence in GRIP-EMS can hold more than one version, and the addon picks which one is live based on what content you are in. GRIP-EMS recognizes dozens of distinct context types across raid difficulty, dungeon difficulty, Mythic+ key ranges, delve tiers, rated PvP, and more, and it checks on zone change, difficulty change, and group roster update. If you have built a separate version of a sequence for, say, Mythic+ versus raid, walking into a dungeon swaps you to that version automatically with no manual intervention.

This used to have a real failure mode. Swapping versions by zoning into a dungeon or arena could drop a sequence's loop and branch grouping, and it would stay broken until you ran a manual /reload. That is fixed. The self-heal that rebuilds loop and branch structure now runs on the context switch itself, not just on a reload, so grouping survives the swap the moment it happens.

If you want to override the automatic pick, you can pin a specific version as the live one regardless of what your current content or talents would otherwise select. The pin holds until you clear it, and the version list shows a badge next to whichever version is actually firing. Useful if you are deliberately running an off-spec version of a sequence, or testing a version before letting it take over automatically for its intended content.

Keybind recovery

GRIP-EMS includes automatic keybind monitoring. If your sequence keybinds go missing after a login, a loadout swap, or a deleted loadout eating its own binds, the addon detects it and tells you. Running /gems binds restore puts your last working set back immediately.

The addon snapshots your binds on every clean load, so recovery is reliable even across sessions. If you see a warning about missing binds, run the restore command before assuming something is broken in your sequence.

If your keys ever stop responding and you are not in a vehicle, a pet battle, or a cutscene, run /gems binds restore first. It takes two seconds and covers the most common cause of unexplained dead keys.

Per-step Disable and the sequence tracker

Individual steps can be disabled inside the editor without deleting them. A disabled step is skipped entirely by the engine, which means you can comment out a step for testing purposes without losing the macro text. Re-enable it and the engine picks it up again on the next keypress.

Disabled sequences are hidden from the tracker overlay and from your action bar. A sequence that is toggled off does not occupy a visible tracker slot, which keeps the display clean when you have multiple sequences loaded but only some of them active.

Interleave / Weave

Interleave lets you set an interval on any action so it fires every N steps automatically, without you having to manually place it throughout your sequence. Set an action's interval to 5, for example, and the compiler weaves that action into your rotation every fifth step, on top of whatever else is already there.

This is the right tool for maintenance buffs, trinket procs, or cooldowns you want firing on a regular cadence without disrupting your main rotation flow. Rather than manually inserting the same spell at steps 5, 10, 15, and 20, you set one interleave interval and the compiler places it for you at every one of those points, correctly, even if you later add or remove steps elsewhere in the sequence.

The interval range is 2 to 50 steps. Interleave also works inside Loop blocks, and the editor marks any interleaved row with an [IL:N] indicator so you can see at a glance which steps are woven in versus part of your authored rotation.

If your interval is larger than the block it lives in, the action never gets a chance to fire and compiles to nothing. GRIP-EMS now warns you when this happens, names the action, tells you the block's actual step count, and suggests an interval or Repeat count that would make it fit. If a trinket or buff you set up on interleave never seems to go off, check for this warning first before assuming the trinket itself is broken.

Plugin support

GRIP-EMS exposes a public plugin API so other addons can extend it without touching its source. Everything goes through one frozen entry point, GRIPEMS.API, and it is owner-scoped and isolated per plugin, so a bug in someone else's plugin breaks their plugin, not your sequences. Anything a plugin adds is owned by its plugin id and reverts cleanly the moment that plugin is disabled, no leftovers in your settings or your sequences.

This is the kind of thing you will only ever notice if you run an addon that uses it. If a plugin adds a new export format, it shows up alongside the built-in one in the export window's format picker. If a plugin adds settings, they appear inside its own panel rather than scattered through GRIP-EMS's existing menus. None of this changes default behavior for anyone who is not running a plugin.

As of v2.3.0, the API extends to action bars specifically. A plugin can put one of your sequences directly on an action button, reading per-step spell data, creating and picking up that sequence's macro, and registering its own /gems subcommand to go with it. Same rule applies: nothing changes unless you are running a plugin built against this.

If you build addons and want to extend GRIP-EMS yourself, the full API reference, including the security model and every method by access tier, lives at jesperlive.github.io/GRIP-EMS-PluginAPI. That documentation is the authoritative source for plugin development, this guide is written for sequence builders rather than addon authors.

The visual display layer versus what actually executes

This is worth knowing because it causes real confusion in the Discord regularly. GRIP-EMS has two separate things: the visual preview of your sequence in the editor, and the compiled macro output that actually runs when you press your keybind. They are not the same thing.

The visual layer renders steps it can match against known spells in its database. Steps it cannot match, including certain raw macro lines, some conditional constructs, and hero talent override spells under specific conditions, do not show in the preview. But they still exist in the compiled output and WoW's macro engine executes them correctly. A step that is invisible in the editor is not a broken step.

This passthrough behavior is intentional and is how GRIP-EMS supports custom macro syntax that the addon's parser does not explicitly recognize. If you see fewer steps in the preview than you built and your sequence is otherwise working, this is almost certainly why.