-
Notifications
You must be signed in to change notification settings - Fork 700
ActionLists
This documentation is a part of the TCI reference.
Is there an error? Something missing? Funky grammar? Do not hesitate to leave a comment.
Actions lists are priorities lists: periodically, Simulationcraft scans your character's actions list, starting with the first action (the highest priority ) and continuing until an available action is found, or to the end otherwise. Actions that are not possible at the moment (cooldown not ready, execute phase only, conditions not met) are just considered as not available and the applications jumps to the next one.
Here is a simplified warrior actions list:
# If the character has no flask already, use a greater draenic strength one
actions=flask,type=greater_draenic_strength_flask
# Otherwise, use a draenic strength potion if the targets health is below 20 percent and recklessness is up, or if the target will die in 25 seconds.
actions+=/potion,name=draenic_strength,if=(target.health.pct<20&buff.recklessness.up)|target.time_to_die<=25
# Otherwise, starts autoattack if not done already.
actions+=/auto_attack
# Otherwise, pops up the "recklessness" 3 min cooldown if ready.
actions+=/recklessness
# Otherwise, uses bloodthirst if ready.
actions+=/bloodthirst
# Otherwise, use colossus smash if ready.
actions+=/colossus_smash
# Otherwise, use execute (only available when target health is below 20% health but it is always implicit)
actions+=/execute
# Otherwise, use raging blow, but only if target is above 20% health
actions+=/raging_blow,if=target.health_pct>=20
A couple pieces of advice for writing actions lists:
- Do not forget, it is priority-based, it's as simple as that!
- Do not try to optimize your actions lists for computations performances. Just focus on correctly modeling the gameplay you want.
- Have doubts? Make Simulationcraft write a combat log for you, with the log option, see Output.
- actions (scope: current character; default: depends on class and spec) is the list of actions your character will follow. It is a multi-line string and a sequence of commands using the "/" separator.
# Note how we use the "/" separator and the "+=" appending operator.
actions=dosomething
actions+=/dosomethingelse
-
auto_attack triggers the auto-attack when it's not already activated. It cannot be used to stopping or resetting auto attacks. Options are:
- sync_weapons (optional, default: 0), when different from zero, will synchronize weapons swings for ambidextrous classes with two weapons with the same swing speed. When zero, the offhand will be delayed by half of its swing time. In game, you always start with your weapons synchronized but target switching and parry rushes often lead you to go unsynchronized. Some mechanics are pretty sensible to weapons being synchronized or note, such as flurry.
# Ensure the player will always auto attack and will start with synched weapons.
actions+=/auto_attack,sync_weapons=1
- snapshot_stats forces simulationcraft to capture your buffed stats values just before the combat actually begins. It has no influence on the simulation itself is it's totally optional. However you need to include it if you want the reports and output to display the correct (non-zero) values for raid-buffed stats. It should be located after all other out-of-combat actions (food, flasks, etc), and BEFORE the first potion.
# Ensure the reports will display correct values for "raid-buffed" stats.
actions+=/snapshot_stats
-
cancel_buff cancels a buff, just like "/cancelaura" would do in game.
- name is the name of the buff to cancel.
# Cancels raging blow buff if 2 stacks are up, which has never been used before in game, but hey, it's an example.
actions+=/cancel_buff,name=raging_blow,if=buff.raging_blow.stack=2
-
use_item triggers the use of an item.
- name is the item's name
- Alternatively, you can also specify an item by the slot or the on-use effect_name
-
Since Simulationcraft 6.1.2-01 In addition, you can also evaluate the type of stat buff the item triggers with the
use_buff.<stat_type>
expression. It evaluates to 1 if the item triggers the expressed stat, 0 otherwise.
# Uses the "shard of woe" trinket
actions+=/use_item,name=shard_of_woe,if=cooldown.evocation.remains>86
-
restore_mana forcefully and instantly restores mana.
- mana (default: 0) is the amount of mana to restore. When left to zero, mana will be restored to its maximum. The purpose of this action is to let you test out infinite mana scenarios or fights with special mana regeneration mechanics. Since this action has no cooldown, it can be performed many times every second.
# This will restore 500 mana anytime it is triggered.
actions+=/restore_mana,mana=500
See the relevant page for each class for more information on non-trivial spells.
Spells are added on a per-class basis. Those keywords are the spells' names, where white spaces are replaced with underscores (_
) and non-alphanumeric characters are ignored. The list would obviously be too long to write and boring to maintain but you can check your class' source code file (sc_mage.cpp for mages for example) for the "create_action" function.
# This will make a feral druid cast Tiger's fury.
actions+=/tigers_fury
- arcane_torrent triggers arcane torrent (blood elf racial)
actions+=/arcane_torrent
- berserking triggers berserking (troll tracial)
actions+=/berserking
- blood_fury triggers blood fury (orc racial)
actions+=/blood_fury
- stoneform triggers stoneform (dwarf racial)
actions+=/stoneform
Pets' actions can be used through a specific syntax: <petname>:<petaction>
. Relevant options are the ones for the specified pet action.
actions+=/spider:wolverine_bite
However most pets actions actually have shortcut keywords you will probably prefer:
actions+=/wolverine_bite
Note that pets come with their own default actions lists! You can modify them as you do with any regular character.
-
food can trigger the use of a food.
- type is the name of the food to use.
actions+=/food,type=blackrock_barbecue
-
flask can trigger the use of a flask.
- type is the name of the flask to use.
actions+=/flask,type=greater_draenic_strength_flask
-
health_stone can trigger the use of a health stone.
- health or trigger is the absolute hp deficit you must suffer to allow the use of the stone.
# If a character has his health 60k below his maximum, he will use the stone
actions+=/health_stone,trigger=60000
- potion can trigger the use of a potion. Only 1 potion may be used in combat.
# Triggers the potion use when out of combat or when bloodlust has just started.
actions+=/potion,name=draenic_strength,if=!in_combat|buff.bloodlust.react
-
augmentation can trigger the use of a Augmentation Rune.
- type is either focus, hyper or stout.
# Triggers Focus Augmentation Rune.
actions+=/augmentation,type=focus
- oralius_whispering_crystal and crystal_of_infinity can trigger the use of the special consumables found in WoW. (Since Simulationcraft 6.0.3-26)
- start_moving triggers a movement phase, it will end only with stop_moving.
- stop_moving ends the movement phase.
# Here are fragments of the shadowpriest rotation. When the target health is below 25%, sw:d deals three times more damages and has a chance to make apparitions spawn. This chance is increased while the sp moves.
# Do not move when sw:d is on cooldown
actions+=/stop_moving,health_percentage<=25,if=cooldown.shadow_word_death.remains>=0.2
# Start moving when the sw:d cooldown is going to end (we need to stand still to fire it)
actions+=/start_moving,health_percentage<=25,if=cooldown.shadow_word_death.remains<=0.1
Actions sequences are sub-actions chains to execute in a given order. Use the following keyword:
-
sequence declares and triggers a sequence of actions to use in the specified order. Actions are separated with ":".
- name (optional, default: "default") is used to name the sequence.
Once one of the sub-actions has been performed, Simulationcraft does not immediately perform the next sub-action in the chain. Instead, it restarts at the beginning of the whole actions list (not the sequence). If the sequence is executed again, then it will trigger the actions which have not been performed yet.
# So, some class has three spells: yellow, blue and red. They all share the global cooldown.
actions+=/yellow
actions+=/sequence,red:blue
# On the first gcd, yellow is not ready, red and blue are: the application will execute "red"
# On the second gcd, all spells are ready: the application will execute "yellow"
# On the third gcd, yellow is not ready, red and blue are: the application will execute "blue"
# From now on, the application will only perform "yellow".
When all spells have been performed, the sequence is not automatically reinitialized and it will be skipped from now on! You need to use the following keyword:
-
restart_sequence will restart the specified sequence.
- name is the name of the sequence to restart.
# Here are fragments of the 4.0.6 mage rotation
actions+=/sequence,name=attack:fire_melee:fire_nova:fire_blast
actions+=/restart_sequence,name=attack,moving=0
Finally, you can use wait_on_ready (default: -1) on a sequence or one of its sub-actions. When equal to 1, it will force the the application to restart at the beginning of the actions list processing if this spell is not ready. Practically, actions below this one will never be executed. However, things are slightly different for sequences:
- If the sequence itself is flagged as wait_on_ready, all spells with wait_on_ready=-1 will be flagged with the value you specified whenever the sequence is restarted.
- The sequence will be considered as flagged whenever the next remaining spell is flagged with wait_on_ready=1.
# Here is a sample of an old death knight sequence. Spells have been replaced with their abbreviations to make things easier.
actions+=/sequence,wait_on_ready=1:PS:IT:BS:BS:SS
actions+=/DC
actions+=/restart_sequence,name=default
# At first, because of wait_on_ready, the application will flag all spells with wait_on_ready=1. It means the application will have to wait on every step and until the sequence has been completed. It will never reach the "DC" line even if one of the spells is not ready yet.
# So, the application will perform PS-IT-BS-BS-SS. Then, as long as it can do DC, it will. Once there is not enough runic power left for DC, the sequence will be restarted.
Do you have headaches already ? Yes, sequences are tricky, they are rarely used. If you do use them, do it with caution.
Strict Sequences are a breed of sequence, except for they do not need to be reset, and when they are started, they cannot be stopped under normal circumstances. A strict sequence requires all actions in the sequence to be ready for the duration of the sequence.
Unlike normal sequences, strict sequences must have a name, there is no default.
# Arms Warrior will perform Recklessness, bloodbath, colossus smash, mortal strike, whirlwind, whirlwind when all are available.
# The name allows you to call this sequence from other parts of the action list.
actions+=/strict_sequence,name=swifty:recklessness:bloodbath:colossus_smash:mortal_strike:whirlwind
-
wait orders the application to stop processing the actions list for a given time. Auto-attacks and such will still be performed.
- sec (default: 1) is the number of seconds to wait. It can be a constant or an expression (see the conditional expressions section).
# This orders Simulationcraft to stop processing the actions list for 5s
actions+=/wait,sec=5
# This orders Simulationcraft to stop processing the actions list until only 2s remains before somebuff expires (if 5s remaining, wait 3s).
actions+=/wait,sec=buff.somebuff.remains-2
-
wait_until_ready orders the player to stop processing the actions list until some cooldown or dot expires. Its only purpose is to improve performances but beware: conditions such as a buff expiration, reaction to heroism/bloodlust, etc, won't be checked.
- sec (default: 1) is the maximum time, in seconds, the player will wait. One second is enough, it reduces the actions list processing cost by an order of magnitude. And since some conditions won't automatically wake up the application, it is advised to keep it low. Just as for wait, this option can be an expression as well as a simple number.
actions+=/wait_until_ready,sec=0.5
-
pool_resource will force the application to stop processing the actions list while the resource is restored. By default, the primary resource of the spec is pooled.
- wait (default: 0.5) is the time, in seconds, to wait. It is advised to keep this value low so that the resource pooling will only occur as long as the application reaches this very action and as its conditions are satisfied.
- for_next (default: 0), when different from 0, will force the application to wait until the player has enough resources for the following action in list. If the following action already satisfies its resource criteria or if it is made unavailable for other reasons than resource starvation (cooldown for example), then pool_resource will be ignored.
- extra_amount (default: 0), must be used with for_next parameter. When different from 0, it will require an additional amount of resource to be generated (in addition to the cost of the next action).
# First example, without using for_next: the application will pool energy while the player has less than 60 energy and slice and dice must soon be refreshed (within 5s).
actions+=/pool_resource,if=energy<60&buff.slice_and_dice.remains<5
actions+=/slice_and_dice,if=combo_points>=3&buff.slice_and_dice.remains<2
# Second example, with for_next: if the player is not stealthed and has less than 5 combo points but the player has less than 85 energy (the only non-satisfied criteria for shadow dance), then the application will pool energy until the player has 85 or more energy. If the player is stealthed or has 5 combo points, both lines will be skipped.
actions+=/pool_resource,for_next=1,extra_amount=85
actions+=/shadow_dance,if=energy>=85&combo_points<5&buff.stealthed.down
APL variables take the general form of variable,name=,<default=>,<value=>,<op=>,<delay=>,<condition=>,<if=> If all optional values are omitted the variable will default to the set operation.
- name is the user assigned name for the variable. This can be used to reference that variable later or to perform additional operations on it.
- default is the initial value of the variable. If not given as an option, 0 will be used.
- value is the value which is to be used for the operation. This supports any string which can be evaluated to a value as well.
-
op is the operation to perform on the variable. Possible values are:
- print prints the current value of the variable to the log. Requires either log=1 or debug=1 to generate a log. a 1 second delay value will be used as default to prevent spooling.
- reset current value is reset to default.
- floor performs the floor operation on value and sets current value to the result.
- ceil performs the ceil operation on value and sets current value to the result. The following operations also require the value to be set:
- set sets the value in the variable to the value in the value parameter
- add adds value to the current value and sets current value to the result.
- sub subtracts value from the current value and sets current value to the result.
- mul multiplies value by the current value and sets current value to the result.
- div divides the current value by value and sets current value to the result. If value is 0 then current value will be set to 0.
- pow raises current value to the power of value and sets current value to the result.
- mod performs the modulo operation on current value with value and sets current value to the result.
- min performs the min operation on current value and value and sets the current value to the result.
- max performs the max operation on current value and value and sets the current value to the result.
- setif Requires the additional parameter value_else. If condition evaluates to a non-zero value then sets current value to value. Else if value evaluates to 0 then sets current value to value_else
- delay is the delay (simulation time) before the variable action can be executed again.
- if allows Conditional expressions to control execution of the variable action.
- apl_variable (scope: current character) is an option that can be used to override the default value of an APL variable.
# override the default value of an APL variable called "aoe_threshold" to 5.
apl_variable.aoe_threshold=5
All actions have additional options, we're listing them here.
-
target (default: "") is the action's target. When empty, it will be the default target (the player himself for healers, the main target for damage dealers and tanks). To force a spell to target yourself, use the syntax
target=self
.
# cast power_infusion on actor named John
actions+=/power_infusion,target=John
# cast holy prism on yourself
actions+=/holy_prism,target=self
- cycle_targets will cycle the action through all available targets when set to 1.
# Use moonfire on any target that does not currently have it.
actions+=/moonfire,cycle_targets=1,if=!ticking
- max_cycle_targets will set a maximum amount of targets to cycle through.
# Cycles through only 3 targets.
actions+=/moonfire,cycle_targets=1,max_cycle_targets=3,if=!ticking
- buff.bloodlust.react (default: 0), when different from zero, will flag the action as usable only when bloodlust (heroism, time warp, etc) is active. When left to zero, the action will be usable anytime.
# Let's use recklessness only under bloodlust.
actions+=/recklessness,if=buff.bloodlust.react=1
- target.debuff.invulnerable.react (default: 0), when different from zero, will flag the action as usable only when the target is invulnerable (happens only when you specified an invulnerability raid event). When left to zero, the action will be usable anytime.
# Using this at the top of the actions list will force the player to wait (through 0.5s steps) and do nothing while the target is invulnerable.
actions+=/wait,sec=0.5,target.debuff.invulnerable.react=1
- target.debuff.vulnerable.react (default: 0), when different from zero, will flag the action as usable only when the target is vulnerable (suffers twice more damages, it happens only when you specified a vulnerability raid event). When left to zero, the action will be usable anytime.
# Let's use recklessness only when the target is vulnerable.
actions+=/recklessness,if=target.debuff.vulnerable.react=1
- target.debuff.flying.react (default: 0), when different from zero, will flag the action as usable only when the target is flying.
# Let's use black arrow only when the target is flying.
actions+=/black_arrow,if=target.debuff.flying.react=1
# Let's use explosive trap only when the target is on the ground.
actions+=/explosive_trap,if=target.debuff.flying.react=0
- moving (default: -1), when different from -1, will flag the action as usable only when the players are moving (moving=1) or not moving (moving=0). When left to -1, the action will be usable anytime. The players happen to move either because of a "movement" raid event, or because of "start_moving" actions. Note that actions which are not usable while moving do not need to be flagged with "move=0", Simulationcraft is already aware of those restrictions.
# Let's use typhoon only when the player is moving.
actions+=/typhoon,moving=1
- prev returns the previous foreground action executed. This will include gcd and non-gcd actions, such as fireball and bloodbath.
# Only use pyroblast when the previous spell used was fireball
actions+=/pyroblast,if=prev.fireball
- prev_gcd returns only the previous action that used a GCD. This will only include actions such as fireball, but not bloodbath.
# Only use whirlwind after mortal strike.
actions+=/whirlwind,if=prev_gcd.whirlwind
- prev_off_gcd returns all off gcd actions that occurred since the previous gcd was executed. So after a warrior uses raging blow, it will track every off-gcd action until another gcd action is executed, then it is reset.
# Only use recklessness if bloodbath was just executed.
actions+=/recklessness,if=prev_off_gcd=bloodbath
- time can be used to make an action usable only when the elapsed time, in seconds, since the beginning of the fight is between specified bounds. It has to be used with the "<=" or ">=" operators. You can specify both an upper and a lower bound. It is especially useful when you want to time an action in respect to your raid events.
# Cast bloodlust 20s after the beginning of the fight
actions+=/bloodlust,if=time>=20
- time_to_Xpct can be used to make an action usable only when the estimated remaining time, in seconds, is between specified bounds. It has to be used with the "<=" or ">=" operators. You can specify both an upper and a lower bound, and you can also set the percent. time_to_die will be converted into time_to_0pct.
# Cast bloodlust 60s before the estimated end the of the fight.
actions+=/bloodlust,if=time_to_die<60
# Cast recklessness if it will be available again for execute range
actions+=/recklessness,if=time_to_20pct>180
- line_cd can be used to force a length of time, in seconds, to pass after executing an action before it can be executed again. In the example below, the second line can execute even while the first line is being delayed because of line_cd.
# Cast soulburn exactly once during dark soul (which has a 20s duration)
actions+=/soulburn,line_cd=20,if=buff.dark_soul.up
# Cast soulburn during the execute phase when UA is on its last tick
actions+=/soulburn,if=target.health.pct<=20&dot.unstable_affliction.ticks_remain<=1
- sync (default: "") can be used to flag an action as unusable while another specified action is not ready. The given value must be the name of the synchronized action. This line will be executed as soon as the specific action is READY, not when the action is necessarily used.
# Warriors tend to pop their cooldowns at the same time. Recklessness has a 4 mins cooldown, death wish has a 2.4 mins cooldown. Let's force recklessness to wait for dw to be ready.
actions+=/recklessness,sync=death_wish
- target.health.pct can be used to make an action usable only when the target's health percentage is between specified bounds. It has to be used with the "<=" or ">=" operators. You can specify both an upper and a lower bound.
# Starts bloodlust when the target's health is below 25%.
actions+=/bloodlust,target.health.pct<25
- interrupt can be used on channeled spells, when set to a non-zero value, to interrupt the channeling when another action with a higher priority is ready. The interrupt will only occur immediately following a tick.
# Stop channeling mind flay when any other action with a higher priority is made available.
actions+=/mind_flay,interrupt=1
- interrupt_if can be used on channeled spells to interrupt the channeling if a higher priority action is ready (the same as interrupt), the global cooldown has elapsed, and the specified conditions are met. The interrupt will only occur immediately following a tick. The conditions are provided using the syntax for conditional expressions.
# Stop channeling when there is less than 1s remaining on the mind blast cooldown.
actions+=/mind_flay,interrupt_if=cooldown.mind_blast.remains<1
- interrupt_immediate can be used on a channeled spell that has an interrupt_if expression to instruct the actor to immediately interrupt the channeled action, even if the global cooldown has not elapsed yet. Added in Simulationcraft 7.0.3, release 1
- chain can be used to re-cast a channeled spell at the beginning of its last tick. This has two advantages over waiting for the channel to complete before re-casting: 1) the gcd finishes sooner, and 2) it avoids the roughly 1/4 second delay between the end of a channel and the beginning of the next cast.
# Chain-cast Mind Flay until a higher priority action is ready
actions+=/mind_flay,chain=1
- early_chain_if has the same effect as chain, but with three differences: 1) it only chains the spell if the given expression is true, 2) it can chain the spell at the beginning of any tick, not just the last, and 3) it will not execute during the gcd.
# Chain-cast Mind Flay Insanity, restarting the cast early if Devouring Plague is about to fall off
actions+=/mind_flay_insanity,interrupt=1,chain=1,early_chain_if=dot.devouring_plague_tick.remains<=tick_time
By default, the sim will only try to perform actions after GCD has elapsed and the actor isn't casting or channeling. Sometimes, it is desirable to use actions during GCD. This only works for actions that do not trigger GCD (such as interrupts) and can be enabled with use_off_gcd
(default: 0).
# Use Water Elemental's Freeze while Ice Lance is in flight
actions+=/freeze,use_off_gcd=1,if=action.ice_lance.in_flight
Some actions can also be used while casting or channeling. This only works for actions that support cast while casting and can be enabled with use_while_casting
(default: 0).
# Use Combustion right before Pyroblast finishes casting
actions+=/combustion,use_while_casting=1,if=action.pyroblast.executing&action.pyroblast.execute_remains<0.5
Note that use_while_casting=1
does not imply use_off_gcd=1
.
- travel_speed (default: ingame flight speed) is the flight speed, in yards per second, of the spell (a fireball for example).
# Let's make our fireballs instant.
actions+=/fireball,travel_speed=0
- wait_on_ready (default: -1), when equal to 1, will force the the application to restart at the beginning of the actions list processing if this spell is not ready. Practically, actions below this one will never be executed. You can use it to quickly make the end of the list inactive but the main purpose of this option is for sequences, see the related section.
# Let's put wait_on_ready=1 on this line near the end of the balance druid's actions list.
actions+=/wrath,wait_on_ready=1,if=eclipse_dir=-1
# Those last lines will never be executed.
actions+=/starfire
actions+=/wild_mushroom,moving=1,if=buff.wild_mushroom.stack<3
actions+=/moonfire,moving=1
actions+=/sunfire,moving=1
- See the article on enemies.
- See the article on Conditional expressions for a in-depth guide on how to conditionally filter actions in a action priority list.
- Features
- Starters guide
- Frequently asked questions
- Common Issues
- Textual configuration interface
- Classes
- Graphical User Interface
- Appendixes
- Developers Corner