Перейти к содержимому

Pattern examples

Updated October 18, 2026

Each pattern is a small but complete rotation: the KRC text on the left, the same JSON on the right. Paste it into the builder (Text and JSON — Paste) to see how it looks on the Slots and Rules pages. The spell IDs are real, from Wowhead. At the end: complete rotations.

A DoT refreshed in the pandemic window#

Apply a DoT when it's missing and refresh it when 30% or less is left: refreshing within that window loses nothing. An absent aura has 0 left, so the refresh is a separate group with .up.

KRC text
rotation "Pattern: DoT with the pandemic window"

buff1	Garrote_DoT = "Garrote on target [703]"
slot1	Garrote = "Garrote"
slot4	Mutilate = "Mutilate"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Garrote when  # Garrote
	Garrote_DoT.down  # no DoT
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30  # pandemic

use Mutilate when  # Mutilate
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: DoT with the pandemic window",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrote on target [703]", "spell": 703}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrote", "spell": 703},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329}
  ],
  "rules": [
    {"use": "Garrote", "name": "Garrote", "when": [
      {"all": ["Garrote_DoT.down"], "comment": "no DoT"},
      {"all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"], "comment": "pandemic"}
    ]},
    {"use": "Mutilate", "name": "Mutilate"}
  ]
}
  • To avoid a new DoT on a target about to die on 3+ targets, add TargetHP >= 50 to the "no DoT" group and a separate group Garrote_DoT.down and enemies <= 2 for one or two targets.
  • A long DoT with a variable duration (Rupture: 4 s + 4 s per combo point) works the same way: the percentages are of that application's duration.

Builder and spender by combo points#

Spend at 5+ combo points out of 7, build below that. The thresholds sit halfway between the steps, see the combo point table.

KRC text
rotation "Pattern: builder and spender"

slot3	Envenom = "Envenom"
slot4	Mutilate = "Mutilate"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenom
	Combo_Points >= 70  # 5+ CP

use Mutilate when  # Mutilate
	Combo_Points < 70  # below 5 CP
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: builder and spender",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenom", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenom", "when": [
      {"all": ["Combo_Points >= 70"], "comment": "5+ CP"}
    ]},
    {"use": "Mutilate", "name": "Mutilate", "when": [
      {"all": ["Combo_Points < 70"], "comment": "below 5 CP"}
    ]}
  ]
}

A builder with Combo_Points < 70 doesn't overflow combo points: at 5+ it stays silent even if the spender isn't ready yet (not enough energy), and KeyRota waits.

Resource pooling#

Don't spend at once; keep the buff up and pool energy: Envenom when its buff is running out, under Deathmark, or when energy is high. The rest of the time no rule fits at 5+ combo points, and KeyRota waits for more energy: that's pooling.

KRC text
rotation "Pattern: energy pooling"

buff3	Envenom_Buff = "Envenom [32645]"
buff4	Deathmark_DoT = "Deathmark on target [360194]"
slot3	Envenom = "Envenom"
slot4	Mutilate = "Mutilate"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenom
	Combo_Points >= 70 and Envenom_Buff.down  # no buff
	or
	Combo_Points >= 70 and Envenom_Buff.duration <= 20  # buff running out
	or
	Combo_Points >= 70 and Deathmark_DoT.up  # under Deathmark
	or
	Combo_Points >= 70 and Energy >= 70  # don't cap energy

use Mutilate when  # Mutilate
	Combo_Points < 70
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: energy pooling",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 3, "alias": "Envenom_Buff", "label": "Envenom [32645]", "spell": 32645},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Deathmark on target [360194]", "spell": 360194}
  ],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenom", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenom", "when": [
      {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "no buff"},
      {"all": ["Combo_Points >= 70", "Envenom_Buff.duration <= 20"], "comment": "buff running out"},
      {"all": ["Combo_Points >= 70", "Deathmark_DoT.up"], "comment": "under Deathmark"},
      {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "don't cap energy"}
    ]},
    {"use": "Mutilate", "name": "Mutilate", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}
  • The Energy >= 70 threshold keeps energy from capping.
  • The Envenom_Buff.duration <= 20 group also fires without the buff (0 left); the .down group is there for clarity.
  • To tune pooling change only the energy threshold: lower spends earlier, higher pools longer.

Single target and multiple targets#

The player sets the target mode with the target mode key (it cycles Auto, Single, Multiple); in Auto the rules decide by the enemy count. Each AoE rule gets two groups, "Multiple mode" and "Auto with 2+ enemies"; the single-target rule gets "Single mode" and "Auto with at most one enemy".

KRC text
rotation "Pattern: single and multiple targets"

slot3	Envenom = "Envenom"
slot4	Mutilate = "Mutilate"
slot6	Fan_of_Knives = "Fan of Knives"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenom
	Combo_Points >= 70

use Fan_of_Knives when  # Fan of Knives: 2+ targets
	aoe == 1 and Combo_Points < 70  # Multiple mode
	or
	st == 0 and enemies >= 2 and Combo_Points < 70  # Auto mode, 2+ enemies

use Mutilate when  # Mutilate: single target
	st == 1 and Combo_Points < 70  # Single mode
	or
	aoe == 0 and enemies <= 1 and Combo_Points < 70  # Auto mode, one enemy
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: single and multiple targets",
  "specID": 259,
  "enemies": {"range": 8, "combatOnly": true},
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenom", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329},
    {"n": 6, "alias": "Fan_of_Knives", "label": "Fan of Knives", "spell": 51723}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenom", "when": [
      {"all": ["Combo_Points >= 70"]}
    ]},
    {"use": "Fan_of_Knives", "name": "Fan of Knives: 2+ targets", "when": [
      {"all": ["aoe == 1", "Combo_Points < 70"], "comment": "Multiple mode"},
      {"all": ["st == 0", "enemies >= 2", "Combo_Points < 70"], "comment": "Auto mode, 2+ enemies"}
    ]},
    {"use": "Mutilate", "name": "Mutilate: single target", "when": [
      {"all": ["st == 1", "Combo_Points < 70"], "comment": "Single mode"},
      {"all": ["aoe == 0", "enemies <= 1", "Combo_Points < 70"], "comment": "Auto mode, one enemy"}
    ]}
  ]
}
  • st == 0 and enemies >= 2 means "not Single mode": in Multiple mode the rule fires through its first group anyway.
  • enemies <= 1 is safer than enemies == 1: on a single target the enemy may not be counted.
  • Take the counter radius (enemies.range) from your AoE ability: Fan of Knives hits within 8 yards.

Cooldowns on Burst and "only under the cooldown"#

cd == 1 is the Burst button. A big cooldown is pressed only while Burst is on, and you hold it by turning Burst off, for example before a phase where the boss is immune. Whatever strengthens the cooldown window is pressed only under it: here Vanish only while Deathmark is on the target, and Kingsbane under Deathmark or when Deathmark is far away.

KRC text
rotation "Pattern: Burst"

buff1	Garrote_DoT = "Garrote on target [703]"
buff2	Rupture_DoT = "Rupture on target [1943]"
buff4	Deathmark_DoT = "Deathmark on target [360194]"
buff10	Vanish_Buff = "Vanish [11327]"
slot1	Garrote = "Garrote"
slot4	Mutilate = "Mutilate"
slot8	Deathmark = "Deathmark"
slot9	Kingsbane = "Kingsbane"
slot10	Vanish = "Vanish"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Garrote when  # Garrote from Stealth
	Vanish_Buff.up

use Deathmark when  # Deathmark
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up  # Burst on, DoTs up

use Kingsbane when  # Kingsbane
	cd == 1 and Deathmark_DoT.up and Combo_Points < 50  # under Deathmark, 0-3 CP
	or
	cd == 1 and Deathmark.cd >= 44 and Combo_Points < 50  # Deathmark more than 52 s away

use Vanish when  # Vanish
	Deathmark_DoT.up and Combo_Points < 65  # under Deathmark, 0-4 CP

use Mutilate when  # Mutilate
	Combo_Points < 70
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: Burst",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrote on target [703]", "spell": 703},
    {"n": 2, "alias": "Rupture_DoT", "label": "Rupture on target [1943]", "spell": 1943},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Deathmark on target [360194]", "spell": 360194},
    {"n": 10, "alias": "Vanish_Buff", "label": "Vanish [11327]", "spell": 11327}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrote", "spell": 703},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329},
    {"n": 8, "alias": "Deathmark", "label": "Deathmark", "spell": 360194},
    {"n": 9, "alias": "Kingsbane", "label": "Kingsbane", "spell": 385627},
    {"n": 10, "alias": "Vanish", "label": "Vanish", "spell": 1856, "offGcd": true, "queue": true}
  ],
  "rules": [
    {"use": "Garrote", "name": "Garrote from Stealth", "when": [
      {"all": ["Vanish_Buff.up"]}
    ]},
    {"use": "Deathmark", "name": "Deathmark", "when": [
      {"all": ["cd == 1", "Garrote_DoT.up", "Rupture_DoT.up"], "comment": "Burst on, DoTs up"}
    ]},
    {"use": "Kingsbane", "name": "Kingsbane", "when": [
      {"all": ["cd == 1", "Deathmark_DoT.up", "Combo_Points < 50"], "comment": "under Deathmark, 0-3 CP"},
      {"all": ["cd == 1", "Deathmark.cd >= 44", "Combo_Points < 50"], "comment": "Deathmark more than 52 s away"}
    ]},
    {"use": "Vanish", "name": "Vanish", "when": [
      {"all": ["Deathmark_DoT.up", "Combo_Points < 65"], "comment": "under Deathmark, 0-4 CP"}
    ]},
    {"use": "Mutilate", "name": "Mutilate", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}
  • Vanish is off the GCD but has In the queue window too (O + Q): otherwise it would be pressed mid-GCD right after Kingsbane, before Kingsbane's combo points arrive, and would check the old count.
  • Turn Burst off and Deathmark and Kingsbane wait; Vanish waits for Deathmark.
  • Kingsbane at 0–3 combo points: 5 more arrive after it, and none are wasted.

Channel protection#

The game ends some channels slightly before the last hit, and the next press cuts it off. The protection is the channel's own aura: while more than 8% of it is left, no rule holds. The condition goes into every group of every rule. Flag C on the channel's slot keeps it from being pressed twice at the start.

KRC text
rotation "Pattern: channel protection"

buff10	Killing_Spree_Buff = "Killing Spree, channel [51690]"
slot8	Killing_Spree = "Killing Spree"
slot9	Dispatch = "Dispatch"
slot11	Sinister_Strike = "Sinister Strike"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Killing_Spree when  # Killing Spree
	Combo_Points >= 80 and Killing_Spree_Buff.duration <= 8

use Dispatch when  # Dispatch
	Combo_Points >= 80 and Killing_Spree_Buff.duration <= 8

use Sinister_Strike when  # Sinister Strike
	Combo_Points < 80 and Killing_Spree_Buff.duration <= 8
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: channel protection",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 10, "alias": "Killing_Spree_Buff", "label": "Killing Spree, channel [51690]", "spell": 51690}
  ],
  "slots": [
    {"n": 8, "alias": "Killing_Spree", "label": "Killing Spree", "spell": 51690, "channel": true},
    {"n": 9, "alias": "Dispatch", "label": "Dispatch", "spell": 2098},
    {"n": 11, "alias": "Sinister_Strike", "label": "Sinister Strike", "spell": 193315}
  ],
  "rules": [
    {"use": "Killing_Spree", "name": "Killing Spree", "when": [
      {"all": ["Combo_Points >= 80", "Killing_Spree_Buff.duration <= 8"]}
    ]},
    {"use": "Dispatch", "name": "Dispatch", "when": [
      {"all": ["Combo_Points >= 80", "Killing_Spree_Buff.duration <= 8"]}
    ]},
    {"use": "Sinister_Strike", "name": "Sinister Strike", "when": [
      {"all": ["Combo_Points < 80", "Killing_Spree_Buff.duration <= 8"]}
    ]}
  ]
}
  • Why <= 8 and not .down: without the channel the aura has 0 left and the condition holds; during the channel it waits only for the last 8%, not for extra fractions of a second after the end.
  • If the aura isn't read, the condition is false in every rule and KeyRota presses nothing: better to skip a press than to cut the channel. So the channel's aura must be in the Better Assistant profile.

An off-GCD macro in the queue window#

Two kinds of "off the GCD":

  • O: the button is pressed at once, even mid-GCD. That's how Keep It Rolling (extending Roll the Bones) loses no time.
  • O + Q: the button is off the GCD, but its macro or its result depends on the GCD. The Adrenaline Rush macro with Killing Spree as the second line (Killing Spree is on the GCD) is pressed in the queue window at the end of the GCD, and Killing Spree goes off right after Adrenaline Rush.
The macro in the game (slot 1)
#showtooltip Adrenaline Rush
/cast Adrenaline Rush
/cast Killing Spree
KRC text
rotation "Pattern: off the GCD"

buff2	Triple_Threat = "Roll the Bones, level 3 [1214935]"
buff3	Jackpot = "Roll the Bones, level 4 [1214937]"
buff6	Adrenaline_Rush_Buff = "Adrenaline Rush [13750]"
slot1	Adrenaline_Rush = "Adrenaline Rush + Killing Spree (macro)"
slot4	Keep_It_Rolling = "Keep It Rolling"
slot11	Sinister_Strike = "Sinister Strike"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Adrenaline_Rush when  # Adrenaline Rush (+ Killing Spree by the macro)
	Adrenaline_Rush_Buff.down and Combo_Points >= 7 and Combo_Points < 80  # 1-5 CP: at 0 the macro's Killing Spree doesn't cast

use Keep_It_Rolling when  # Keep It Rolling
	Triple_Threat.up
	or
	Jackpot.up

use Sinister_Strike when  # Sinister Strike
	Combo_Points < 80
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: off the GCD",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 2, "alias": "Triple_Threat", "label": "Roll the Bones, level 3 [1214935]", "spell": 1214935},
    {"n": 3, "alias": "Jackpot", "label": "Roll the Bones, level 4 [1214937]", "spell": 1214937},
    {"n": 6, "alias": "Adrenaline_Rush_Buff", "label": "Adrenaline Rush [13750]", "spell": 13750}
  ],
  "slots": [
    {"n": 1, "alias": "Adrenaline_Rush", "label": "Adrenaline Rush + Killing Spree (macro)", "spell": 13750, "offGcd": true, "queue": true},
    {"n": 4, "alias": "Keep_It_Rolling", "label": "Keep It Rolling", "spell": 381989, "offGcd": true},
    {"n": 11, "alias": "Sinister_Strike", "label": "Sinister Strike", "spell": 193315}
  ],
  "rules": [
    {"use": "Adrenaline_Rush", "name": "Adrenaline Rush (+ Killing Spree by the macro)", "when": [
      {"all": ["Adrenaline_Rush_Buff.down", "Combo_Points >= 7", "Combo_Points < 80"], "comment": "1-5 CP: at 0 the macro's Killing Spree doesn't cast"}
    ]},
    {"use": "Keep_It_Rolling", "name": "Keep It Rolling", "when": [
      {"all": ["Triple_Threat.up"]},
      {"all": ["Jackpot.up"]}
    ]},
    {"use": "Sinister_Strike", "name": "Sinister Strike", "when": [
      {"all": ["Combo_Points < 80"]}
    ]}
  ]
}

A macro slot's ID is the ID of the macro's main spell (Adrenaline Rush, 13750): Better Assistant uses it to put the macro's spell into the slot, and KeyRota takes the key from the macro button on your bar.

A defensive by health#

Healing or a defensive below a health threshold, only when Healing / defense is on in the panel. The slot is shown in combat (In combat, "show": "combat") so that it works without a target. The rule goes first: at low health it matters more than damage.

KRC text
rotation "Pattern: a defensive by health"

slot4	Mutilate = "Mutilate"
slot11	Crimson_Vial = "Crimson Vial"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Crimson_Vial when  # Crimson Vial
	defensives == 1 and PlayerHP <= 40  # HP 40% or lower

use Mutilate when  # Mutilate
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: a defensive by health",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329},
    {"n": 11, "alias": "Crimson_Vial", "label": "Crimson Vial", "spell": 185311, "show": "combat"}
  ],
  "rules": [
    {"use": "Crimson_Vial", "name": "Crimson Vial", "when": [
      {"all": ["defensives == 1", "PlayerHP <= 40"], "comment": "HP 40% or lower"}
    ]},
    {"use": "Mutilate", "name": "Mutilate"}
  ]
}

Healing / defense is off by default: turn it on in the quick settings panel when you want automatic defensives.

Procs: by buff or by glow#

Check a proc by its buff: in the Assassination raid rotation the Blindside buff (Blindside.up) allows the Ambush rule. If the game highlights the button on a proc, a rule can read the glow (Ambush.glow), but only if you actually see that glow on your bar.

KRC text
rotation "Pattern: a proc"

buff7	Blindside = "Blindside [121153]"
slot4	Mutilate = "Mutilate"
slot5	Ambush = "Ambush"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Ambush when  # Ambush (Blindside)
	Blindside.up and Combo_Points < 70

use Mutilate when  # Mutilate
	Combo_Points < 70
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: a proc",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 7, "alias": "Blindside", "label": "Blindside [121153]", "spell": 121153}
  ],
  "slots": [
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329},
    {"n": 5, "alias": "Ambush", "label": "Ambush", "spell": 8676}
  ],
  "rules": [
    {"use": "Ambush", "name": "Ambush (Blindside)", "when": [
      {"all": ["Blindside.up", "Combo_Points < 70"]}
    ]},
    {"use": "Mutilate", "name": "Mutilate", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}

Charges#

A spell with charges is pressed at two charges or when the second is almost back, so that its recharge never idles. Example: the hunter's Barbed Shot (2 charges).

KRC text
rotation "Pattern: charges"

slot1	Barbed_Shot = "Barbed Shot"
slot2	Kill_Command = "Kill Command"
resource1	PlayerHP
resource2	TargetHP
resource3	Focus

use Barbed_Shot when  # Barbed Shot
	Barbed_Shot.charges >= 2  # both charges
	or
	Barbed_Shot.charges == 1 and Barbed_Shot.cd <= 20  # the second one is almost back

use Kill_Command when  # Kill Command
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: charges",
  "specID": 253,
  "resources": ["PlayerHP", "TargetHP", "Focus"],
  "slots": [
    {"n": 1, "alias": "Barbed_Shot", "label": "Barbed Shot", "spell": 217200},
    {"n": 2, "alias": "Kill_Command", "label": "Kill Command", "spell": 34026}
  ],
  "rules": [
    {"use": "Barbed_Shot", "name": "Barbed Shot", "when": [
      {"all": ["Barbed_Shot.charges >= 2"], "comment": "both charges"},
      {"all": ["Barbed_Shot.charges == 1", "Barbed_Shot.cd <= 20"], "comment": "the second one is almost back"}
    ]},
    {"use": "Kill_Command", "name": "Kill Command"}
  ]
}

For a spell with charges .cd is the next charge's recharge: Barbed_Shot.cd <= 20 means at most 20% of its recharge is left.

Distance to the target#

When the target is out of melee range but within range of a ranged ability, press that instead of idling. Without a target the distance is unknown and the rule stays silent.

KRC text
rotation "Pattern: distance"

slot10	Pistol_Shot = "Pistol Shot"
slot11	Sinister_Strike = "Sinister Strike"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Pistol_Shot when  # Pistol Shot: the target is far
	target.distance >= 10 and target.distance <= 20 and Combo_Points < 80

use Sinister_Strike when  # Sinister Strike
	Combo_Points < 80
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: distance",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 10, "alias": "Pistol_Shot", "label": "Pistol Shot", "spell": 185763},
    {"n": 11, "alias": "Sinister_Strike", "label": "Sinister Strike", "spell": 193315}
  ],
  "rules": [
    {"use": "Pistol_Shot", "name": "Pistol Shot: the target is far", "when": [
      {"all": ["target.distance >= 10", "target.distance <= 20", "Combo_Points < 80"]}
    ]},
    {"use": "Sinister_Strike", "name": "Sinister Strike", "when": [
      {"all": ["Combo_Points < 80"]}
    ]}
  ]
}

A melee rule doesn't need to check the distance: if the target is too far, the spell can't be used, and KeyRota moves on to the next rule by itself.

Movement#

The Movement panel button is your signal to the rotation: "I'll have to run now". The rotation decides what to do, for example switch to a ranged ability.

KRC text
rotation "Pattern: movement"

slot10	Pistol_Shot = "Pistol Shot"
slot11	Sinister_Strike = "Sinister Strike"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Pistol_Shot when  # Pistol Shot while moving
	movement == 1 and Combo_Points < 80

use Sinister_Strike when  # Sinister Strike
	movement == 0 and Combo_Points < 80
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: movement",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 10, "alias": "Pistol_Shot", "label": "Pistol Shot", "spell": 185763},
    {"n": 11, "alias": "Sinister_Strike", "label": "Sinister Strike", "spell": 193315}
  ],
  "rules": [
    {"use": "Pistol_Shot", "name": "Pistol Shot while moving", "when": [
      {"all": ["movement == 1", "Combo_Points < 80"]}
    ]},
    {"use": "Sinister_Strike", "name": "Sinister Strike", "when": [
      {"all": ["movement == 0", "Combo_Points < 80"]}
    ]}
  ]
}

Ground-targeted spells#

The Ground button allows spells that are placed on the ground. KeyRota only presses a key, so the macro sets the place: [@player] at your feet, [@cursor] under the cursor.

The macro in the game
#showtooltip Death and Decay
/cast [@player] Death and Decay
KRC text
rotation "Pattern: ground spells"

slot1	Death_and_Decay = "Death and Decay (macro @player)"
resource1	PlayerHP
resource2	TargetHP
resource3	Runes
resource4	Runic_Power

use Death_and_Decay when  # Death and Decay
	ground_spells == 1 and enemies >= 2  # Ground on, 2+ enemies
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Pattern: ground spells",
  "specID": 250,
  "resources": ["PlayerHP", "TargetHP", "Runes", "Runic_Power"],
  "slots": [
    {"n": 1, "alias": "Death_and_Decay", "label": "Death and Decay (macro @player)", "spell": 43265}
  ],
  "rules": [
    {"use": "Death_and_Decay", "name": "Death and Decay", "when": [
      {"all": ["ground_spells == 1", "enemies >= 2"], "comment": "Ground on, 2+ enemies"}
    ]}
  ]
}

The complete starter rotation#

The rotation from the builder example: two DoTs, a builder, a spender with pooling, a defensive and Deathmark on Burst.

KRC text
rotation "Assassination: example v1"

# Example from the KeyRota documentation: two bleeds, a builder, a spender with energy pooling,
# a defensive at low health and Deathmark on the Burst button.
# Combo points in percent of 7: 5 points = 71%, threshold 70 = 5+.

buff1	Garrote_DoT = "Garrote on target [703]"
buff2	Rupture_DoT = "Rupture on target [1943]"
buff3	Envenom_Buff = "Envenom [32645]"
buff4	Deathmark_DoT = "Deathmark on target [360194]"
slot1	Garrote = "Garrote"
slot2	Rupture = "Rupture"
slot3	Envenom = "Envenom"
slot4	Mutilate = "Mutilate"
slot5	Deathmark = "Deathmark"
slot6	Crimson_Vial = "Crimson Vial"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

# --- Defensive: only with Healing / defense on ---
use Crimson_Vial when  # Crimson Vial
	defensives == 1 and PlayerHP <= 40  # health 40% or lower

# --- Cooldown: only with Burst on ---
use Deathmark when  # Deathmark
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up  # Burst on, bleeds and Envenom up

# --- Bleeds ---
use Garrote when  # Garrote
	Garrote_DoT.down  # no bleed
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30  # pandemic window: 30% or less left

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # 5+ combo points, no bleed
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 30  # 5+ combo points, pandemic window

# --- Spender: 5+ combo points, pooling energy ---
use Envenom when  # Envenom
	Combo_Points >= 70 and Envenom_Buff.down  # no buff
	or
	Combo_Points >= 70 and Envenom_Buff.up and Envenom_Buff.duration <= 20  # buff running out
	or
	Combo_Points >= 70 and Energy >= 70  # don't cap energy
	or
	Combo_Points >= 70 and Deathmark_DoT.up  # Deathmark on the target

# --- Builder: below 5 combo points ---
use Mutilate when  # Mutilate
	Combo_Points < 70  # below 5 combo points
JSON
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Assassination: example v1",
  "specID": 259,
  "ignoreMainIcon": true,
  "enemies": {"range": 8, "combatOnly": true},
  "notes": [
    "Example from the KeyRota documentation: two bleeds, a builder, a spender with energy pooling,",
    "a defensive at low health and Deathmark on the Burst button.",
    "Combo points in percent of 7: 5 points = 71%, threshold 70 = 5+."
  ],
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrote on target [703]", "spell": 703},
    {"n": 2, "alias": "Rupture_DoT", "label": "Rupture on target [1943]", "spell": 1943},
    {"n": 3, "alias": "Envenom_Buff", "label": "Envenom [32645]", "spell": 32645},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Deathmark on target [360194]", "spell": 360194}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrote", "spell": 703, "show": "target"},
    {"n": 2, "alias": "Rupture", "label": "Rupture", "spell": 1943, "show": "target"},
    {"n": 3, "alias": "Envenom", "label": "Envenom", "spell": 32645, "show": "target"},
    {"n": 4, "alias": "Mutilate", "label": "Mutilate", "spell": 1329, "show": "target"},
    {"n": 5, "alias": "Deathmark", "label": "Deathmark", "spell": 360194, "show": "target"},
    {"n": 6, "alias": "Crimson_Vial", "label": "Crimson Vial", "spell": 185311, "show": "combat"}
  ],
  "rules": [
    {
      "use": "Crimson_Vial",
      "name": "Crimson Vial",
      "note": ["--- Defensive: only with Healing / defense on ---"],
      "when": [{"all": ["defensives == 1", "PlayerHP <= 40"], "comment": "health 40% or lower"}]
    },
    {
      "use": "Deathmark",
      "name": "Deathmark",
      "note": ["--- Cooldown: only with Burst on ---"],
      "when": [
        {
          "all": ["cd == 1", "Garrote_DoT.up", "Rupture_DoT.up", "Envenom_Buff.up"],
          "comment": "Burst on, bleeds and Envenom up"
        }
      ]
    },
    {
      "use": "Garrote",
      "name": "Garrote",
      "note": ["--- Bleeds ---"],
      "when": [
        {"all": ["Garrote_DoT.down"], "comment": "no bleed"},
        {
          "all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"],
          "comment": "pandemic window: 30% or less left"
        }
      ]
    },
    {
      "use": "Rupture",
      "name": "Rupture",
      "when": [
        {"all": ["Combo_Points >= 70", "Rupture_DoT.down"], "comment": "5+ combo points, no bleed"},
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.up", "Rupture_DoT.duration <= 30"],
          "comment": "5+ combo points, pandemic window"
        }
      ]
    },
    {
      "use": "Envenom",
      "name": "Envenom",
      "note": ["--- Spender: 5+ combo points, pooling energy ---"],
      "when": [
        {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "no buff"},
        {
          "all": ["Combo_Points >= 70", "Envenom_Buff.up", "Envenom_Buff.duration <= 20"],
          "comment": "buff running out"
        },
        {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "don't cap energy"},
        {"all": ["Combo_Points >= 70", "Deathmark_DoT.up"], "comment": "Deathmark on the target"}
      ]
    },
    {
      "use": "Mutilate",
      "name": "Mutilate",
      "note": ["--- Builder: below 5 combo points ---"],
      "when": [{"all": ["Combo_Points < 70"], "comment": "below 5 combo points"}]
    }
  ]
}

A complete raid rotation#

A real Assassination raid rotation (Fatebound): 15 rules, Burst, Vanish under Deathmark, copying DoTs with Crimson Tempest, AoE and single target, energy pooling.

KRC text: Assassination, raid
KRC text
rotation "Assassination, raid v2.8: Burst button, Method 12.1, SimulationCraft, top logs"

# Assassination, raid. Based on the Method guide (patch 12.1), the SimulationCraft action list and the top Warcraft Logs players.
# Ignore main icon: on. Deathmark and Kingsbane only with Burst on; Vanish only while Deathmark is on the target.
# Combo points in percent of 7: 3 = 43%, 4 = 57%, 5 = 71%, 6 = 86%, 7 = 100%.

# v2.4: Kingsbane only at 0–3 combo points (Implacable Strikes then add 5), Vanish at 0–4 (Garrote from stealth adds 3).
# v2.5: Crimson Tempest only when just one of the two bleeds is fresh; before that it was pressed several times in a row.
# v2.6: with Burst on and Deathmark ready or already on the target, Garrote and Rupture go on a target at any health.
# v2.7 and v2.8: a new target without bleeds, Burst on, Deathmark ready, 2+ enemies nearby: Crimson Tempest copies the bleeds first (at any combo points), then Deathmark.

buff1	Garrote_DoT = "Garrote on target [703]"
buff2	Rupture_DoT = "Rupture on target [1943]"
buff3	Envenom_Buff = "Envenom [32645]"
buff4	Deathmark_DoT = "Deathmark on target [360194]"
buff5	Improved_Garrote = "Improved Garrote [392401]"
buff6	Darkest_Night = "Darkest Night [457280]"
buff7	Blindside = "Blindside [121153]"
buff8	Stealth_Buff = "Stealth [1784]"
buff9	Stealth_Sub = "Stealth (Subterfuge) [115191]"
buff10	Vanish_Buff = "Vanish [11327]"
slot1	Garrote = "Garrote"
slot2	Rupture = "Rupture"
slot3	Envenom = "Envenom"
slot4	Mutilate = "Mutilate"
slot5	Ambush = "Ambush"
slot6	Fan_of_Knives = "Fan of Knives"
slot7	Crimson_Tempest = "Crimson Tempest"
slot8	Deathmark = "Deathmark"
slot9	Kingsbane = "Kingsbane"
slot10	Vanish = "Vanish"
slot11	Crimson_Vial = "Crimson Vial"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

# --- Defensive: only with Healing / defense on ---
use Crimson_Vial when  # Crimson Vial
	defensives == 1 and PlayerHP <= 40  # health 40% or lower

# === Stealth ===
use Garrote when  # Garrote from stealth
	Stealth_Buff.up  # in stealth
	or
	Stealth_Sub.up  # in stealth (Subterfuge)
	or
	Vanish_Buff.up  # right after Vanish

use Garrote when  # Garrote: the Improved Garrote window
	Improved_Garrote.up and Garrote_DoT.down  # the window is open, no Garrote on the target
	or
	Improved_Garrote.up and Garrote_DoT.duration <= 78  # SimulationCraft: refresh with 14 of 18 seconds left

# === Cooldowns (Burst button) ===
use Deathmark when  # Deathmark
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Kingsbane.cd <= 3 and Envenom_Buff.duration >= 35 and Stealth_Buff.down and Stealth_Sub.down  # Burst on, bleeds up, Kingsbane ready, Envenom for 2+ more seconds

use Kingsbane when  # Kingsbane
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up and Deathmark_DoT.up and Combo_Points < 50 and Stealth_Buff.down and Stealth_Sub.down  # Burst on, Deathmark on the target, 0–3 combo points
	or
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up and Deathmark.cd >= 44 and Combo_Points < 50 and Stealth_Buff.down and Stealth_Sub.down  # Burst on, Deathmark more than 52 s away, 0–3 combo points

use Vanish when  # Vanish
	Deathmark_DoT.up and Improved_Garrote.down and Combo_Points < 65 and Stealth_Buff.down and Stealth_Sub.down  # Deathmark on the target, 0–4 combo points (Garrote from stealth adds 3)

# === Bleeds ===
use Crimson_Tempest when  # Crimson Tempest: copy the bleeds to a new target for Deathmark
	cd == 1 and Deathmark.cd <= 3 and Garrote_DoT.down and Rupture_DoT.down and Envenom_Buff.up and enemies >= 2  # combo points don't matter

# No new bleed on adds about to die (like SimulationCraft’s “the target lives 12+ more seconds”): on 1–2 targets and in Single mode always;
# on 3+ targets only if the target has 50%+ health, or Burst is on and Deathmark is ready, or Deathmark is already on the target.
use Garrote when  # Garrote: upkeep
	Garrote_DoT.down and Combo_Points < 95 and enemies <= 2
	or
	Garrote_DoT.down and Combo_Points < 95 and st == 1
	or
	Garrote_DoT.down and Combo_Points < 95 and TargetHP >= 50  # 3+ targets: only a target that will live
	or
	Garrote_DoT.down and Combo_Points < 95 and cd == 1 and Deathmark.cd <= 3  # Burst on and Deathmark ready: health doesn't matter
	or
	Garrote_DoT.down and Combo_Points < 95 and Deathmark_DoT.up  # Deathmark on the target (copied bleeds)
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30 and Combo_Points < 95  # pandemic window (already up)

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down and enemies <= 2
	or
	Combo_Points >= 70 and Rupture_DoT.down and st == 1
	or
	Combo_Points >= 70 and Rupture_DoT.down and TargetHP >= 50  # 3+ targets: only a target that will live
	or
	Combo_Points >= 70 and Rupture_DoT.down and cd == 1 and Deathmark.cd <= 3  # Burst on and Deathmark ready
	or
	Combo_Points >= 70 and Rupture_DoT.down and Deathmark_DoT.up  # Deathmark on the target
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 25 and Darkest_Night.down  # refresh; don't spend the 7 combo points of Darkest Night on it

# === Builders: up to 5 combo points, up to 7 with Darkest Night ===

# Crimson Tempest once right after a fresh Rupture (on 4+ targets also after a fresh Garrote); otherwise Fan of Knives.
# Only one of the two may be fresh (94%+): right after Crimson Tempest both are fresh, so the next one waits.
use Crimson_Tempest when  # Crimson Tempest: spread the bleeds right after a fresh Rupture or Garrote
	aoe == 1 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 2 and enemies <= 3 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94  # 2–3 targets: only after a fresh Rupture
	or
	st == 0 and enemies >= 2 and enemies <= 3 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94  # 2–3 targets: only after a fresh Rupture

use Fan_of_Knives when  # Fan of Knives: single target, Darkest Night, one combo point short
	st == 1 and Darkest_Night.up and Combo_Points >= 80 and Combo_Points < 95
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points >= 80 and Combo_Points < 95

use Fan_of_Knives when  # Fan of Knives: 2+ targets
	aoe == 1 and Darkest_Night.down and Combo_Points < 70
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95
	or
	st == 0 and enemies >= 2 and Darkest_Night.down and Combo_Points < 70
	or
	st == 0 and enemies >= 2 and Darkest_Night.up and Combo_Points < 95

use Ambush when  # Ambush (Blindside)
	Blindside.up and st == 1 and Darkest_Night.down and Combo_Points < 70
	or
	Blindside.up and st == 1 and Darkest_Night.up and Combo_Points < 95
	or
	Blindside.up and aoe == 0 and enemies <= 1 and Darkest_Night.down and Combo_Points < 70
	or
	Blindside.up and aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points < 95

use Mutilate when  # Mutilate
	st == 1 and Darkest_Night.down and Combo_Points < 70
	or
	st == 1 and Darkest_Night.up and Combo_Points < 95
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.down and Combo_Points < 70
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points < 95

# === Spender: 5+ combo points (7 with Darkest Night) ===
# SimulationCraft: keep Envenom up rather than pressing it at once: in the buff's last second, while Deathmark is on the target, before energy caps, earlier on 4+ targets.
use Envenom when  # Envenom
	Darkest_Night.down and Combo_Points >= 70 and Envenom_Buff.down
	or
	Darkest_Night.down and Combo_Points >= 70 and Envenom_Buff.duration <= 20  # about 1 s left
	or
	Darkest_Night.down and Combo_Points >= 70 and Deathmark_DoT.up
	or
	Darkest_Night.down and Combo_Points >= 70 and Energy >= 70  # don't cap energy
	or
	Darkest_Night.down and Combo_Points >= 70 and Energy >= 30 and enemies >= 4
	or
	Darkest_Night.up and Combo_Points >= 95 and Envenom_Buff.down
	or
	Darkest_Night.up and Combo_Points >= 95 and Envenom_Buff.duration <= 20
	or
	Darkest_Night.up and Combo_Points >= 95 and Deathmark_DoT.up
	or
	Darkest_Night.up and Combo_Points >= 95 and Energy >= 70
	or
	Darkest_Night.up and Combo_Points >= 95 and Energy >= 30 and enemies >= 4

Its JSON is in the files below. The second rotation is Outlaw (Trickster) with the Adrenaline Rush macro (O + Q), Keep It Rolling (O), Killing Spree (C) and channel protection in every rule.

Example files#

ExampleFiles
The starter Assassination rotation from the builder exampleJSON, KRC text
Assassination, raid: 15 rulesJSON, KRC text
Outlaw, raid and Mythic+: 13 rules, flags O, OQ, CJSON, KRC text
The shortest useful rotationJSON, KRC text
A syntax sample: every condition and flag (no IDs, not for combat)JSON, KRC text

Every example exists in all the site's languages: the labels, rules and comments are translated, while the conditions, spell IDs and flags are the same. The language is in the file name: .en, .ru, .de, .fr, .es, .it, .pt, .ko, .zh, .zh-TW.

To open a file: New — From file… in the main window, or Open… on the builder's Text and JSON page.