Skip to content

Move Category Files

Move categories map move names to strategic categories that the AI uses for filtering. When you write a move filter like \{ "categories": ["heal"] \} in an action priority, the AI looks up which moves belong to the heal category using these files.

Move category files are loaded from:

data/<namespace>/move_categories/<category>.json

For example, a custom heal category override would be placed at:

data/mypack/move_categories/heal.json

Categories reload when you run /reload.

Each move category file has three fields:

{
"category": "heal",
"replace": false,
"moves": ["recover", "roost", "softboiled", "moonlight", "gigadrain"]
}
FieldTypeDescription
categorystringOne of the built-in category names (see table below), or a custom category name.
replaceboolfalse = merge with existing moves for this category. true = replace all existing moves with only the ones listed here.
movesstring[]Showdown move IDs (lowercase, no spaces). E.g., "swordsdance", "flamethrower".

Smart Trainers includes 17 built-in move categories out of the box:

CategoryDescriptionExample Moves
damageDirect damage-dealing moves(most attacking moves)
statusStatus-inflicting (burn, para, sleep, etc.)thunderwave, willowisp, spore
healHP recoveryrecover, roost, softboiled, gigadrain
cureStatus curingaromatherapy, healbell
buffSelf/ally stat boostingswordsdance, calmmind, dragondance
malusOpponent stat loweringgrowl, charm, screech
hazardEntry hazardsstealthrock, spikes, toxicspikes
hazard_controlHazard removalrapidspin, defog
weatherWeather-settingraindance, sunnyday, sandstorm
terrainTerrain-settingelectricterrain, grassyterrain
priorityIncreased priority movesquickattack, extremespeed, machpunch
pivotDamage + switchuturn, voltswitch, flipturn
protectionProtect/Detect familyprotect, detect, kingsshield
trapTrappingmeanlook, block, spiritshackle
phazeForced switch-outroar, whirlwind, dragontail
redirectionMove redirectionfollowme, ragepowder
speed_controlSpeed manipulationtailwind, trickroom, icywind
supportMiscellaneous supporthelpinghand, lightscreen, reflect
flinchFlinch-inducingfakeout, ironhead, rockslide

The replace field controls how your category file interacts with existing moves in that category:

Merge mode ("replace": false) — Your moves are added to the existing list. This is the default and most common approach. Use this to extend a built-in category with additional moves.

{
"category": "heal",
"replace": false,
"moves": ["strengthsap", "junglehealing", "lifedew"]
}

This adds Strength Sap, Jungle Healing, and Life Dew to the existing heal category without removing Recover, Roost, or any other built-in heal moves.

Replace mode ("replace": true) — All existing moves for this category are removed, and only the moves listed in your file are used. Use this when you want full control over a category’s contents.

{
"category": "heal",
"replace": true,
"moves": ["recover", "roost", "softboiled"]
}

This replaces the entire heal category with only Recover, Roost, and Soft-Boiled. Any other moves that were previously in the category are removed.

You can create your own categories by using a category name that does not match any built-in name. The AI will recognize it in move filters.

For example, to create a “anti_stall” category:

{
"category": "anti_stall",
"replace": false,
"moves": ["taunt", "trick", "encore", "torment", "knockoff"]
}

Then use it in action priorities:

{
"id": "anti_stall_vs_walls",
"condition": "q.target.is_support && !q.target.has_status",
"action_type": "move",
"move_filter": { "categories": ["anti_stall"] },
"priority": 75,
"bias_multiplier": 2.5,
"score_bonus": 90.0
}

You can also check custom categories in MoLang conditions using q.move.has_category('anti_stall').

When multiple datapacks define move category files for the same category, the behavior depends on the replace field:

  • If all files use "replace": false — all move lists are merged together
  • If any file uses "replace": true — that file’s moves replace all previous entries for the category (load order dependent)