Full Field Reference
Full Field Reference
Section titled “Full Field Reference”Every field ShowdownActions supports, in one place. The bundled 00_bible.conf is the in-tree version of this reference — it has every field with the same descriptions, ready to copy from. This page is the same content arranged for browsing on the docs site.
For narrative explanations of how the fields combine, read Action Files, Match Clause, and Apply Clause.
Top-Level Fields
Section titled “Top-Level Fields”| Field | Type | Default | Re-evaluated? | Notes |
|---|---|---|---|---|
id | String | filename without .conf | — | Stable identifier. Used by /showdownactions info <id> and command tab-completion. |
displayName | String | "" | — | Free-form label shown in admin GUIs/logs and as the condition’s name in Showdown. No behavioral effect. |
enabled | Boolean | true | — | When false, the file is loaded but skipped at every match attempt. Treat as “comment out without deleting”. |
priority | Int | 0 | — | Higher priority is evaluated first when several actions match the same (actor, pokemon). Mostly relevant inside a mutexGroup. |
target | enum | SELF | — | Which side+slot the resulting Showdown effect is registered against. See Targeting. |
chance | Double | 1.0 | per battle | Probability gate in [0, 1]. Rolled once per battle, before the effect is registered. |
oncePerBattle | Boolean | false | — | Fire at most once per battle. Implemented via a battle-scoped flag map keyed by action id. |
permission | String? | null | per battle | Optional permission node. When set, the matching player must satisfy it via fabric-permissions-api. |
mutexGroup | String? | null | per battle | Mutual-exclusion key. Within one battle and trainer, only the highest-priority matching action whose mutexGroup equals this string fires. |
target accepts SELF, ALLIES, FOES, EVERYONE, FIELD. See Targeting for the semantics of each.
match { } — Property Fields
Section titled “match { } — Property Fields”Direct checks against the Pokémon’s stats and identity. Evaluated server-side as plain comparisons.
| Field | Type | Re-checked on switch-in? | Compares against |
|---|---|---|---|
species | String? | Yes | Cobblemon species id ("lycanroc"). |
form | String? | Yes | Form name ("midday", "midnight"). |
type | String? | Yes | One of the Pokémon’s elemental types (lowercase, "water"). |
ability | String? | Yes | Cobblemon ability id (Showdown lowercase, "swiftswim"). |
heldItem | String? | Yes | Full namespaced item id ("cobblemon:choice_band"). |
aspect | String? | No | Required aspect tag ("shiny", "dusk"). |
nature | String? | No | Nature id (lowercase, "modest"). |
teraType | String? | Yes | Tera type (lowercase, "fire"). Re-checked because Terastallization can change it. |
gender | String? | No | "male", "female", or "genderless". |
minLevel | Int? | Yes | Inclusive lower bound (1..100). |
maxLevel | Int? | Yes | Inclusive upper bound (1..100). |
minFriendship | Int? | No | Inclusive lower bound (0..255). |
isLegendary | Boolean? | No | Tri-state. true requires the species to be labeled legendary; false requires it not to be; null ignores. |
The “re-checked on switch-in” column is enforced by an auto-applied guard inside the switch-in hook for target = SELF | ALLIES | EVERYONE actions. Static fields aren’t re-checked because their values can’t change mid-battle.
Tier-3 showdown {} blocks don’t get an auto-guard — you control the entire effect, including any identity check.
match.sugar { } — World Predicates
Section titled “match.sugar { } — World Predicates”Compile to Molang at load time, ANDed with whenMolang.
| Field | Type | Values | Compiles to |
|---|---|---|---|
time | String? | morning, day, noon, evening, dusk, night, midnight | q.world.is_time('<bucket>') |
weather | String? | clear, rain, thunder, snow | q.world.is_raining, q.world.is_thundering, q.world.is_snowing, or the negation. |
biome | String? | Biome id or biome tag | q.world.biome == '...' or q.world.biome_in_tag('...') (with # prefix for tags). |
dimension | String? | Dimension id ("minecraft:overworld") | q.world.dimension == '...' |
Sugar predicates are evaluated once at battle start, against the player’s current world position. Not re-checked on switch-in.
Time bucket boundaries
Section titled “Time bucket boundaries”| Bucket | Tick range (mod 24000) |
|---|---|
morning | 0..2999 |
day | 0..11999 |
noon | 5000..7000 |
evening | 9000..11999 |
dusk | 12000..13000 |
night | 13000..23999 |
midnight | 17500..18500 |
day and morning overlap; night and midnight overlap. Pick the bucket that matches the intent of your gate.
match.whenMolang
Section titled “match.whenMolang”Optional raw Molang expression. ANDed with the rest of the match clause. Truthy (non-zero) means match.
match { whenMolang = "q.pokemon.hp_ratio < 0.25 && q.world.is_thundering"}Available bindings: q.pokemon, q.player, q.world, q.battle. ShowdownActions extras: q.world.is_time(...), q.world.dimension_string. Full surface and dump command at Molang Predicates.
Evaluated once at battle start. Not re-checked on switch-in.
apply { } — Cobblemon-Side Effects
Section titled “apply { } — Cobblemon-Side Effects”Run synchronously at battle start when the action matches. Don’t go through Showdown.
| Field | Type | Effect |
|---|---|---|
aspect | String? | Adds an aspect to the matched Pokémon’s aspect set. Persists until something else removes it. |
command | String? | Server console command, run as the server. {player} is replaced with the trainer’s username. |
apply { } — Showdown-Side Effects (Sugar)
Section titled “apply { } — Showdown-Side Effects (Sugar)”These compose into an auto-applied onStart hook on a generated condition, applied as a volatile when the matched Pokémon switches in.
| Field | Type | Effect |
|---|---|---|
boosts | Block | Stat-stage boosts. See sub-table below. Plays the standard Cobblemon stat-up/down animation. |
status | String? | Apply a major status. Showdown ids: brn, psn, tox, par, slp, frz. |
removeStatus | Boolean | Cure any active major status on switch-in. Default false. |
heal | String? | Heal HP. Accepts "25%" (of max HP) or "50" (flat amount). Anything else is dropped with a log. |
volatile | String? | Add an arbitrary Showdown volatile by id (anything in Dex.data.Conditions). |
weather | String? | Set field weather. Showdown ids: sunnyday, raindance, snow, sandstorm. |
terrain | String? | Set field terrain. Showdown ids: electricterrain, grassyterrain, psychicterrain, mistyterrain. |
message | String? | Yellow battle-chat broadcast. {name} is replaced with the host’s species name at fire time. MiniMessage tags are stripped. |
apply.boosts { }
Section titled “apply.boosts { }”| Field | Type | Range | Stat |
|---|---|---|---|
atk | Int | -6..6 | Atk stage delta |
def | Int | -6..6 | Def stage delta |
spa | Int | -6..6 | Special Atk stage delta |
spd | Int | -6..6 | Special Def stage delta |
spe | Int | -6..6 | Speed stage delta |
accuracy | Int | -6..6 | Accuracy stage delta |
evasion | Int | -6..6 | Evasion stage delta |
All seven default to 0. Zeroes are skipped when compiling the this.boost(...) call. If every value is 0 and no other Showdown-side effect is set, ShowdownActions doesn’t synthesize a Showdown condition at all.
Synthesized onStart order
Section titled “Synthesized onStart order”When apply { } produces a Showdown condition, the generated hook runs effects in this fixed order:
- Auto-generated match guard (for
SELF/ALLIES/EVERYONEonly). oncePerBattleflag check.removeStatus—pokemon.cureStatus().boosts—this.boost({...}, pokemon).status—pokemon.trySetStatus('<id>', pokemon).heal—pokemon.heal(amount).weather—this.field.setWeather('<id>', pokemon).terrain—this.field.setTerrain('<id>', pokemon).volatile—pokemon.addVolatile('<id>').message—this.add('-message', '<text>').
showdown { } — Tier-3 Escape Hatch
Section titled “showdown { } — Tier-3 Escape Hatch”Optional. When present, registered verbatim into Dex.data.Conditions and applied as a volatile when the action fires.
| Field | Type | Default | Notes |
|---|---|---|---|
conditionId | String | required | Showdown condition id. Lowercase alphanumeric (Showdown’s toID() rules). The registry normalizes anything else. |
conditionName | String | conditionId | Display name shown in debug tooling. |
scope | String | "volatile" | "volatile", "side", "field". Currently informational. |
turnDuration | Int? | null | Auto-remove after N turns. null = permanent. |
hooks | Map<String, String> | {} | Showdown event handlers, keyed by handler name. Values are raw JS function strings. |
extras | Map<String, String> | {} | Extra raw JS properties merged into the condition object literal. |
When a showdown {} block is present, no auto-generated species/form guard is added. You control the entire effect.
Convenience-named hooks
Section titled “Convenience-named hooks”These are the slots that map to typed fields on ShowdownCondition. Anything outside this set is forwarded by name.
| Hook | When it fires |
|---|---|
onStart | The volatile attaches (and on every switch-in). |
onEnd | The volatile is removed. |
onResidual | Every turn during the residual phase. |
onRestart | The volatile is reapplied to a host that already has it. |
onModifyAtk | Something asks for the host’s Atk. Returning a number replaces it. |
onModifyDef | Same, for Def. |
onModifySpA | Special Atk. |
onModifySpD | Special Def. |
onModifySpe | Speed. |
For non-named hooks (onAnyDamage, onTryHit, onAfterMoveSecondary, onSwitchOut, onBeforeMove, etc.), use the same hook map — the key is forwarded verbatim to Showdown. See Raw Showdown Hooks for the broader catalogue and Showdown Research for guidance on writing them.
Every hook is auto-wrapped so fires and errors land in the Showdown log as [ShowdownActions][<conditionId>] <hookName> fired/ERROR: … with debug = true.
config.conf
Section titled “config.conf”Mod-level settings. Lives at config/showdown_actions/config.conf, separate from the per-action files.
| Field | Type | Default | Effect |
|---|---|---|---|
enabled | Boolean | true | Master switch. When false, the battle-start hook is a no-op. |
applyInPvp | Boolean | true | Whether actions evaluate in player-vs-player battles. |
applyInPve | Boolean | true | Whether actions evaluate in player-vs-wild and player-vs-NPC battles. |
applyInNpcOnly | Boolean | false | Whether actions evaluate in NPC-vs-NPC battles. |
debug | Boolean | false | Enables verbose [ShowdownActions] log output. |
See Configuration for the narrative version.
Re-Evaluation Summary
Section titled “Re-Evaluation Summary”The single most-common author confusion is “when is X re-checked?”. The summary, by category:
| Evaluated… | Fields |
|---|---|
| Once per battle, at start | All sugar predicates, whenMolang, aspect, nature, gender, minFriendship, isLegendary, chance, permission, mutexGroup. |
| On every switch-in (via auto-guard) | species, form, type, ability, heldItem, teraType, minLevel, maxLevel. |
The auto-guard exists because the patched runSwitch in this environment re-fires onStart on every switch-in, not just the first. Without the guard, an effect targeted at Pikachu would re-fire on Bulbasaur after a swap.
oncePerBattle = true adds another gate: even if the host swaps out and back in and the guard passes, the switch-in hook bails after the first fire of that battle.
Tier-3 showdown {} blocks don’t get an auto-guard — if your hook needs a per-switch identity check, write it inline.
See Also
Section titled “See Also”- The bundled
00_bible.confinconfig/showdown_actions/actions/. Same content, in-tree, ready to copy from. - Action Files — the narrative companion to this reference.
- Match Clause and Apply Clause — the long-form discussion of each block.
- Recipes — worked examples that combine the fields.