Scoring Deep Dive
Scoring Deep Dive
Section titled “Scoring Deep Dive”This page covers the complete decision-making pipeline, traces through a concrete scoring example, and walks through building a Gym Leader AI step by step.
Decision Flow
Section titled “Decision Flow”Every turn, the AI follows this 8-step pipeline in order:
-
Skill Check Roll against the skill level. If the roll fails, pick a random move and skip everything below. Skill level 5 never fails. Skill level 0 always fails (pure random).
-
Score Moves For each available move:
- If
use_damage_calcis enabled: score = estimated damage % x 100 - Otherwise: score = base power (minimum 1.0 for status moves)
- Apply
status_move_biasif the move is a status move - Apply
move_scoring_rules(in definition order) - Final: score x
move_bias
- If
-
Score Switches For each available switch-in:
- Base score = 15.0
- Add matchup bonus (type advantage vs current opponent)
- Add HP bonus (healthier candidates score higher)
- Apply
switch_conditions(in definition order) - Final: score x
switch_bias
-
Score Items For each available bag item x eligible target:
- Base score = item’s
baseScore - Apply healing urgency (HP-based multiplier)
- Apply revive bonus, status cure bonus
- Apply item usage rules from bag config
- Final: score x
item_bias
- Base score = item’s
-
Apply Action Priorities For each scored action x each priority rule (sorted by priority, highest first):
- Check condition (MoLang)
- Check action type match
- Check move filter (if applicable)
- If all pass: score = score x
bias_multiplier+score_bonus
-
Evaluate Gimmick Rules For each gimmick rule (sorted by priority, first match wins):
- Check gimmick is available (Mega/Tera/Dynamax/Z-Move)
- Evaluate condition (MoLang)
- If passes: apply
bias_multiplierto moves (filtered bymove_filterif set) - Attach gimmick ID to the final move response
-
Apply Personality Modifiers
- Aggression: boost/penalize damaging vs status moves
- Risk Tolerance: boost/penalize risky moves (low accuracy, recoil)
- Setup Preference: boost/penalize setup moves
- Switchiness: boost/penalize switch actions
- Item Conservatism: penalize item usage
-
Select Best Action
- Find the highest score
- Collect all actions within
max_select_marginof the best - Weighted random pick (higher-scoring candidates are more likely)
Scoring Math: Worked Example
Section titled “Scoring Math: Worked Example”Let’s trace through a concrete example. Garchomp (Dragon/Ground) has Earthquake, Dragon Claw, Swords Dance, and Stone Edge against a Tyranitar (Rock/Dark).
Config: gen4_cynthia (skill 5, use_damage_calc: true, move_bias: 1.1, status_move_bias: 1.0)
Earthquake (Ground, BP 100)
Section titled “Earthquake (Ground, BP 100)”1. Base score with damage calc: ~55% damage -> 55.02. Move scoring rules: - STAB bonus (is_stab = true): 55.0 x 1.5 = 82.5 - Type effectiveness (Ground vs Rock/Dark = 2.0): 82.5 x 2.0 = 165.0 - Accuracy (100): no change3. Move bias: 165.0 x 1.1 = 181.54. Action priorities: no special rules match5. Personality: slight aggression boostFinal: ~185Earthquake scores very high because it has STAB (Garchomp is Ground-type) and is super effective against Tyranitar (Ground hits Rock for 2x). The damage calc estimates 55% damage, and multipliers stack on top.
Swords Dance (Status, BP 0)
Section titled “Swords Dance (Status, BP 0)”1. Base score: 1.0 (status moves start at 1.0)2. Move scoring rules: - STAB: no (status move) - Type effectiveness: neutral (doesn't apply meaningfully) - Status redundant: no (not status-inflicting)3. Status move bias: 1.0 x 1.0 = 1.04. Move bias: 1.0 x 1.1 = 1.15. Action priorities: - "cynthia_swords_dance": HP > 80%? yes. under_threat < 0.3? yes. - Score: 1.1 x 3.5 + 130.0 = 133.856. Personality: setup preference boostFinal: ~140Despite the massive score_bonus of 130.0, Swords Dance still scores below Earthquake. This is the correct behavior — when Garchomp has a super effective STAB move that deals over half the opponent’s HP, it should attack rather than set up.
Result
Section titled “Result”Earthquake wins (185 > 140). The AI attacks because Earthquake deals super effective STAB damage. But if the opponent were a neutral matchup with lower damage output, Swords Dance could win — the conditions (HP > 80%, under_threat < 0.3) would still pass, and without the 2x type effectiveness multiplier on Earthquake, the scores would be much closer.
Worked Example: Building a Gym Leader AI
Section titled “Worked Example: Building a Gym Leader AI”Let’s build a Fire-type Gym Leader AI step by step, starting from a preset and adding custom behavior.
Step 1: Create the Config File
Section titled “Step 1: Create the Config File”Create data/mypack/battle_ai/fire_gym.json:
{ "parent": "smart_trainers:hard", "max_select_margin": 0.2, "personality": { "enabled": true, "base_personality": { "aggression": 0.75, "risk_tolerance": 0.5, "setup_preference": 0.6, "switchiness": 0.3, "item_conservatism": 0.4 }, "trait_variance": 0.1 }}This inherits from hard (skill 4, type awareness, hazard setup) and adds an aggressive personality that likes setup moves. The max_select_margin of 0.2 means the AI picks from actions within 20% of the best score, giving it a slight unpredictability while still playing well.
What this inherits from hard:
- Skill level 4 (only random 5% of the time)
- Full type effectiveness scoring
- Hazard awareness
- Ability immunity checks
- All of
hard’s action priorities, move scoring rules, and switch conditions
Step 2: Add Custom Action Priorities
Section titled “Step 2: Add Custom Action Priorities”Now add rules that make this feel like a Fire-type specialist:
{ "parent": "smart_trainers:hard", "max_select_margin": 0.2, "personality": { "enabled": true, "base_personality": { "aggression": 0.75, "setup_preference": 0.6, "switchiness": 0.3 }, "trait_variance": 0.1 }, "action_priorities": [ { "id": "setup_sunny_day", "condition": "!q.field.has_weather('SunnyDay') && q.pokemon.current_hp_percent > 0.7", "action_type": "move", "move_filter": { "names": ["sunnyday"] }, "priority": 85, "bias_multiplier": 3.0, "score_bonus": 100.0 }, { "id": "solar_beam_in_sun", "condition": "q.field.has_weather('SunnyDay')", "action_type": "move", "move_filter": { "names": ["solarbeam"] }, "priority": 80, "bias_multiplier": 2.5, "score_bonus": 80.0 }, { "id": "will_o_wisp_physical", "condition": "q.target.is_physical_attacker && !q.target.has_status", "action_type": "move", "move_filter": { "names": ["willowisp"] }, "priority": 75, "bias_multiplier": 2.0, "score_bonus": 70.0 } ]}What these rules do:
- setup_sunny_day (priority 85): When the sun isn’t up and we’re healthy (>70% HP), strongly prefer Sunny Day. The
score_bonus: 100.0makes this status move competitive with attacks. - solar_beam_in_sun (priority 80): Once Sunny Day is active, boost Solar Beam’s score. It fires instantly in sun and provides Grass-type coverage against Water/Ground/Rock types that threaten Fire Pokemon.
- will_o_wisp_physical (priority 75): Burn physical attackers that don’t already have a status condition. Cuts their Attack in half, which is extremely valuable for a Fire Gym Leader.
Because action_priorities is a non-empty array, these three rules are prepended to hard’s existing rules. The Gym Leader gets all of hard’s strategic behavior plus these Fire-specific priorities.
Step 3: Create a Battle Bag
Section titled “Step 3: Create a Battle Bag”Create data/mypack/battle_bags/fire_gym.json:
{ "enabled": true, "maxItemsPerBattle": 2, "items": [ { "itemId": "cobblemon:hyper_potion", "quantity": 2, "category": "HEALING", "baseScore": 3.0 } ], "usageRules": [ { "id": "heal_ace", "condition": "q.pokemon.current_hp_percent < 0.35", "itemFilter": { "categories": ["HEALING"] }, "priority": 20, "biasMultiplier": 4.0, "scoreBonus": 140.0 } ]}The Gym Leader carries 2 Hyper Potions and can use up to 2 items per battle. The usage rule gives a massive scoreBonus of 140.0 when the active Pokemon drops below 35% HP, making the heal competitive with attacking moves. This creates the classic Gym Leader behavior of healing their ace Pokemon at a critical moment.
Step 4: Assign to NPC
Section titled “Step 4: Assign to NPC”Set the NPC’s AI config to mypack:fire_gym and battle bag to mypack:fire_gym.
The Gym Leader now:
- Plays at skill level 4 with full type awareness (inherited from
hard) - Sets up Sunny Day when healthy
- Uses Solar Beam for coverage in sun
- Burns physical attackers with Will-o-Wisp
- Heals its Pokemon when they drop below 35% HP
- Has an aggressive, setup-oriented personality with slight variance between battles