Move Scoring & Switch Conditions
Move Scoring & Switch Conditions
Section titled “Move Scoring & Switch Conditions”Move scoring rules modify the score of individual moves during evaluation. Switch conditions control when and how the AI considers switching Pokemon. Together, these two systems handle the fine-grained decision logic that runs before action priorities apply their broader strategic rules.
Move Scoring Rules
Section titled “Move Scoring Rules”Unlike action priorities (which apply once per action type), move scoring rules are evaluated for each move individually. They are the primary way to teach the AI about type effectiveness, immunities, accuracy, and other per-move factors.
{ "move_scoring_rules": [ { "id": "stab_bonus", "condition": "q.move.is_stab", "score_modifier": { "type": "multiply", "value": "1.5" }, "priority": 20 } ]}Move Scoring Fields
Section titled “Move Scoring Fields”| Field | JSON Key | Type | Default | Description |
|---|---|---|---|---|
| ID | id | string | Required | Unique name. |
| Condition | condition | Molang | Required | When this evaluates to >0, the modifier is applied. Use "1" to mean “always.” |
| Move Condition | move_condition | Molang (optional) | null | Additional condition with access to q.move.* queries. |
| Score Modifier | score_modifier | object | Required | How to modify the score. See Score Modifier Types below. |
| Priority | priority | int | 0 | Reserved for future sorting. Currently, rules are applied in definition order. |
Score Modifier Types
Section titled “Score Modifier Types”Each rule’s score_modifier has a type and a value. The value field is a Molang expression, so it can reference queries dynamically.
| Type | Behavior | Example |
|---|---|---|
multiply | new_score = old_score x value | \{"type": "multiply", "value": "1.5"\} |
add | new_score = old_score + value | \{"type": "add", "value": "50"\} |
set | new_score = value (ignores old score) | \{"type": "set", "value": "0"\} |
script | new_score = value (Molang expression returns the final value) | \{"type": "script", "value": "q.move.power * q.move.type_effectiveness"\} |
Common Move Scoring Rules
Section titled “Common Move Scoring Rules”Type Effectiveness — Always factor in type matchups:
{ "id": "type_effectiveness", "condition": "1", "score_modifier": { "type": "multiply", "value": "q.move.type_effectiveness" }, "priority": 10}Immunity Check — Zero out moves that the target is immune to:
{ "id": "immunity_check", "condition": "q.move.type_effectiveness == 0", "score_modifier": { "type": "set", "value": "0" }, "priority": 100}Predicted KO — Heavily boost moves that can knock out the target:
{ "id": "predicted_ko", "condition": "q.move.predicted_damage_percent >= q.target.current_hp_percent", "score_modifier": { "type": "multiply", "value": "3.0" }, "priority": 50}Accuracy Penalty — Penalize inaccurate moves proportionally:
{ "id": "accuracy_penalty", "condition": "q.move.accuracy < 100 && q.move.accuracy > 0", "score_modifier": { "type": "multiply", "value": "q.move.accuracy / 100" }, "priority": 5}Status Redundant — Do not use status moves on already-statused targets:
{ "id": "status_redundant", "condition": "q.move.is_status && q.target.has_status", "score_modifier": { "type": "multiply", "value": "0.05" }, "priority": 60}Ability Immunity — Respect ability-based immunities (e.g., Flash Fire):
{ "id": "flash_fire_check", "condition": "q.target.revealed_ability == 'flashfire' && q.move.type == 'fire'", "score_modifier": { "type": "set", "value": "0" }, "priority": 95}Switch Conditions
Section titled “Switch Conditions”Switch conditions define when and how the AI considers switching Pokemon. They are evaluated during switch scoring — each condition checks the currently active Pokemon and optionally filters which bench Pokemon are valid switch targets.
{ "switch_conditions": [ { "id": "bad_matchup", "condition": "q.pokemon.under_threat > 0.4 && q.pokemon.current_hp_percent > 0.4", "target_condition": "q.switch_candidate.matchup_score > 1", "priority": 60, "bias_multiplier": 1.5 } ]}Switch Condition Fields
Section titled “Switch Condition Fields”| Field | JSON Key | Type | Default | Description |
|---|---|---|---|---|
| ID | id | string | Required | Unique name. |
| Condition | condition | Molang | Required | Evaluated for the currently active Pokemon. Uses q.pokemon.* queries. |
| Target Condition | target_condition | Molang (optional) | null | Evaluated for each switch candidate. Only candidates where this passes are considered. Uses q.switch_candidate.* queries. |
| Priority | priority | int | 0 | Reserved for future sorting. Currently, conditions are applied in definition order. |
| Bias Multiplier | bias_multiplier | double | 1.2 | Multiplied with the switch candidate’s score. Use <1.0 to discourage switching, 0.0 to prevent it entirely. |
Common Switch Conditions
Section titled “Common Switch Conditions”Never Switch When Trapped — Respect trapping effects:
{ "id": "no_switch_trapped", "condition": "q.pokemon.is_trapped", "priority": 200, "bias_multiplier": 0.0}Do Not Abandon Boosted Pokemon — Discourage switching away from Pokemon with significant stat boosts:
{ "id": "no_switch_boosted", "condition": "q.pokemon.stat_boosts.atk >= 2 || q.pokemon.stat_boosts.spa >= 2", "priority": 90, "bias_multiplier": 0.2}Preserve Low HP Pokemon — Encourage switching out a weakened Pokemon that is still under threat, preserving it for later:
{ "id": "preserve_low_hp", "condition": "q.pokemon.current_hp_percent < 0.3 && q.pokemon.under_threat > 0.25", "priority": 75, "bias_multiplier": 1.8}