Skip to content

Action Priorities

Action priorities are the most powerful tool for defining trainer behavior. They are conditional rules that boost or penalize specific actions based on the current battle state. Want a trainer that always sets up Swords Dance when safe? Switches out when threatened? Uses Toxic against walls? Action priorities make it happen.

After all moves, switches, and items have been scored through the base scoring system, action priority rules are evaluated. Each rule checks a Molang condition against the current battle state. When the condition passes, the rule modifies the score of matching actions using a multiplier and an additive bonus.

Rules are evaluated from highest to lowest priority value. Higher-priority rules are applied first.

FieldJSON KeyTypeDefaultDescription
IDidstringRequiredUnique name for this rule. Shown in debug logs.
ConditionconditionMolangRequiredWhen this evaluates to >0, the rule triggers.
Action Typeaction_typestringRequiredWhich action types this applies to: "move", "switch", "item", "gimmick", "pass".
Move Filtermove_filterobjectnullOnly for action_type: "move". Filters which moves this rule applies to. See Move Filters.
Prioritypriorityint0Rules are evaluated from highest to lowest priority. Higher-priority rules are applied first.
Bias Multiplierbias_multiplierdouble1.5Multiplied with the action’s current score. Use >1.0 to boost, <1.0 to penalize, 0.0 to completely prevent.
Score Bonusscore_bonusdouble0.0Added to the action’s score after the multiplier. Critical for making status moves, setup moves, and items competitive with attack moves.

This is the single most important concept for writing effective action priorities.

Move scores start from base power. Earthquake starts at 100, Flamethrower at 90, Thunderbolt at 90. Status moves have 0 base power, so their starting score is approximately 1.0. No matter how large your bias_multiplier is, multiplying a tiny number still gives a tiny number:

Status move with multiplier only:
1.0 x 5.0 = 5.0 (still loses to every attack)
Attack move with no boost:
100 x 1.0 = 100.0 (wins easily)

score_bonus is additive — it gets added after the multiplier, which is what makes status moves competitive:

Status move with multiplier AND score_bonus:
1.0 x 3.0 + 120.0 = 123.0 (now it competes!)
Attack move with no boost:
100 x 1.0 + 0.0 = 100.0 (status move wins)
Score BonusEffect
40—60Mild preference. Often still loses to strong attacks.
80—100Moderate preference. Competitive with most attacks.
120—150Strong preference. Beats most attacks unless they are super effective.
200+Overwhelming preference. Almost always chosen.

The priority field determines evaluation order. Use these tiers as a guide:

Priority RangeTierUse Case
200+EmergencyHard overrides: stop boosting at max stats, never use blocked moves
100—199CriticalCore strategy: must-use setup moves, heal-or-die decisions
70—99HighStrong preferences: switch under threat, toxic against walls
30—69MediumTactical choices: priority finishing, weather setup
5—20SituationalLow-impact nudges: slight accuracy preference, overkill penalty

When action_type is "move", the optional move_filter narrows which moves the rule applies to. All filter fields are optional — omitting a field means “match any.”

{
"move_filter": {
"categories": ["heal", "buff"],
"types": ["fire", "water"],
"names": ["swordsdance", "dragondance"],
"move_ids": ["earthquake"],
"condition": "q.move.power > 80"
}
}
FieldTypeDescription
categoriesstring[]Match moves with any of these AI categories.
typesstring[]Match moves of any of these elemental types.
namesstring[]Match specific move names (Showdown IDs).
move_idsstring[]Same as names — both fields are checked.
conditionMolangAdditional Molang condition with access to q.move.*.

When multiple fields are specified, all fields must match (AND logic). Within a single field, any value matches (OR logic).

Boost Swords Dance when the AI’s Pokemon is healthy and not under significant threat:

{
"id": "swords_dance_when_safe",
"condition": "q.pokemon.current_hp_percent > 0.8 && q.pokemon.under_threat < 0.3",
"action_type": "move",
"move_filter": {
"names": ["swordsdance"]
},
"priority": 90,
"bias_multiplier": 3.0,
"score_bonus": 120.0
}

The condition ensures the Pokemon is above 80% HP and not heavily threatened. The score_bonus of 120 makes Swords Dance competitive with super effective attacks (which typically score 120—200 after STAB and type multipliers). The high bias_multiplier of 3.0 further amplifies the base score, though the bonus does most of the heavy lifting.

Encourage switching when the active Pokemon is in danger but still has enough HP to take a hit on the way out:

{
"id": "switch_under_threat",
"condition": "q.pokemon.under_threat > 0.5 && q.pokemon.current_hp_percent > 0.3",
"action_type": "switch",
"priority": 70,
"bias_multiplier": 2.5,
"score_bonus": 60.0
}

The under_threat > 0.5 check means the opponent has significant super effective coverage. The current_hp_percent > 0.3 check avoids switching out a Pokemon that is already too low — at that point, it might as well attack. Switch base scores start at 15.0, so 15.0 x 2.5 + 60.0 = 97.5, which is competitive with neutral attacks but loses to super effective STAB moves.

Use Toxic against defensive Pokemon that do not already have a status condition:

{
"id": "toxic_on_walls",
"condition": "!q.target.has_status && q.target.defence > 100 && q.target.special_defence > 100",
"action_type": "move",
"move_filter": {
"names": ["toxic"]
},
"priority": 85,
"bias_multiplier": 3.0,
"score_bonus": 100.0
}

The condition checks that the target has no status (Toxic would fail or be redundant) and has high defensive stats (indicating a wall that is hard to break through with damage alone). With score_bonus: 100, Toxic scores 1.0 x 3.0 + 100.0 = 103.0, beating most neutral attacks.

Stop using boosting moves once the AI already has +4 Attack or Special Attack:

{
"id": "stop_boosting_at_plus_4",
"condition": "q.pokemon.stat_boosts.atk >= 4 || q.pokemon.stat_boosts.spa >= 4",
"action_type": "move",
"move_filter": {
"categories": ["buff"]
},
"priority": 200,
"bias_multiplier": 0.0,
"score_bonus": -200.0
}

This uses priority 200 (emergency tier) to ensure it overrides any other rule that might boost setup moves. The bias_multiplier: 0.0 zeroes out the current score, and the negative score_bonus makes it nearly impossible for the AI to pick another boost.

When a child config specifies action_priorities:

  • Child rules are prepended to parent rules — child rules come first and are evaluated first
  • Set action_priorities to [] (empty array) to clear all parent rules and start fresh
  • Omit action_priorities entirely to inherit the parent’s rules unchanged

This means you can add a few specialized rules on top of a preset’s existing behavior without rewriting everything.