27 KiB
Simulator protocol
Pokémon Showdown's simulator protocol is implemented as a newline-and-pipe-delimited text stream. For details on how to read to or write from the text stream, see README.md.
Receiving messages
Battle initialization
The beginning of a battle will look something like this:
|player|p1|Anonycat|60
|player|p2|Anonybird|113
|teamsize|p1|4
|teamsize|p2|5
|gametype|doubles
|gen|7
|tier|[Gen 7] Doubles Ubers
|rule|Species Clause: Limit one of each Pokémon
|rule|OHKO Clause: OHKO moves are banned
|rule|Moody Clause: Moody is banned
|rule|Evasion Abilities Clause: Evasion abilities are banned
|rule|Evasion Moves Clause: Evasion moves are banned
|rule|Endless Battle Clause: Forcing endless battles is banned
|rule|HP Percentage Mod: HP is shown in percentages
|clearpoke
|poke|p1|Pikachu, L59, F|item
|poke|p1|Kecleon, M|item
|poke|p1|Jynx, F|item
|poke|p1|Mewtwo|item
|poke|p2|Hoopa-Unbound|
|poke|p2|Smeargle, L1, F|item
|poke|p2|Forretress, L31, F|
|poke|p2|Groudon, L60|item
|poke|p2|Feebas, L1, M|
|teampreview
|
|start
|player|PLAYER|USERNAME|AVATAR
Player details.
PLAYERisp1orp2PLAYERmay also bep3orp4in 4 player battlesUSERNAMEis the usernameAVATARis the player's avatar identifier (usually a number, but other values can be used for custom avatars)
|teamsize|PLAYER|NUMBER
PLAYERisp1,p2,p3, orp4NUMBERis the number of Pokémon your opponent starts with. In games without Team Preview, you don't know which Pokémon your opponent has, but you at least know how many there are.
|gametype|GAMETYPE
GAMETYPEissingles,doubles,triples,multi, orfree-for-all.
|gen|GENNUM
Generation number, from 1 to 7. Stadium counts as its respective gens; Let's Go counts as 7, and modded formats count as whatever gen they were based on.
|tier|FORMATNAME
The name of the format being played.
|rated
Will be sent if the game will affect the player's ladder rating (Elo score).
|rated|MESSAGE
Will be sent if the game is official in some other way, such as being a tournament game. Does not actually mean the game is rated.
|rule|RULE: DESCRIPTION
Will appear multiple times, one for each
|clearpoke
|poke|PLAYER|DETAILS|ITEM
|poke|PLAYER|DETAILS|ITEM
...
|teampreview
These messages appear if you're playing a format that uses team previews.
|clearpoke
Marks the start of Team Preview
|poke|PLAYER|DETAILS|ITEM
Declares a Pokémon for Team Preview.
PLAYERis the player ID (see|player|)DETAILSdescribes the pokemon (see "Identifying Pokémon" below)ITEMwill beitemif the Pokémon is holding an item, or blank if it isn't.Note that forme and shininess are hidden on this, unlike on the
|switch|details message.
|start
Indicates that the game has started.
Battle progress
|
Clears the message-bar, and add a spacer to the battle history. This is usually done automatically by detecting the message-type, but can also be forced to happen with this.
|request|REQUEST
Gives a JSON object containing a request for a choice (to move or switch). To assist in your decision,
REQUEST.activehas information about your active Pokémon, andREQUEST.sidehas information about your your team as a whole.REQUEST.rqidis an optional request ID (see "Sending decisions" for details).
|inactive|MESSAGE or |inactiveoff|MESSAGE
A message related to the battle timer has been sent. The official client displays these messages in red.
inactivemeans that the timer is on at the time the message was sent, whileinactiveoffmeans that the timer is off.
|upkeep
Signals the upkeep phase of the turn where the number of turns left for field conditions are updated.
|turn|NUMBER
It is now turn
NUMBER.
|win|USER
USERhas won the battle.
|tie
The battle has ended in a tie.
Identifying Pokémon
Pokémon will be identified by a Pokémon ID (generally labeled POKEMON in
this document), and, in certain cases, also a details string (generally
labeled DETAILS).
A Pokémon ID is in the form POSITION: NAME.
POSITIONis the spot that the Pokémon is in: it consists of thePLAYERof the player (see|player|), followed by a position letter (ain singles).
An inactive Pokémon will not have a position letter.
In doubles and triples battles, a will refer to the leftmost Pokémon
from its trainer's perspective (so the leftmost on your team, and the
rightmost on your opponent's team, so p1a faces p2c, etc).
So the layout looks like:
Doubles, player 1's perspective:
p2b p2a
p1a p1b
Doubles, player 2's perspective:
p1b p1a
p2a p2b
In multi and free-for-all battles, players are grouped by parity. That is,
p1 and p3 share a side, as do p2 and p4. The position letters still
follow the same conventions as in double battles, so the layout looks like:
Multi, player 1's perspective
p4b p2a
p1a p3b
NAMEis the nickname of the Pokémon (or the species name, if no nickname is given).
For example: p1a: Sparky could be a Charizard named Sparky.
p1: Dragonite could be an inactive Dragonite being healed by Heal Bell.
DETAILSis a comma-separated list of all information about a pokemon visible on the battle screen: species, shininess, gender, and level. So it starts withSPECIES, adding, shinyif it's shiny,, Mif it's male,, Fif it's female,, L##if it's not level 100.
So, for instance, Deoxys-Speed is a level 100 non-shiny genderless
Deoxys (Speed forme). Sawsbuck, shiny, F, L50 is a level 50 shiny female
Sawsbuck (Spring form).
In Team Preview, DETAILS will not include information not available in
Team Preview (in particular, level and shininess will be left off), and
for Pokémon whose forme isn't revealed in Team Preview, it will be given as
-*. So, for instance, an Arceus in Team Preview would have the details
string Arceus-*, no matter what kind of Arceus it is.
For most commands, you can just use the position information in the
Pokémon ID to identify the Pokémon. Only a few commands actually change the
Pokémon in that position (|switch| switching, |replace| illusion dropping,
|drag| phazing, and |detailschange| permanent forme changes), and these
all specify DETAILS for you to perform updates with.
Major actions
In battle, most Pokémon actions come in the form |ACTION|POKEMON|DETAILS
followed by a few messages detailing what happens after the action occurs.
Battle actions (especially minor actions) often come with tags such as
|[from] EFFECT|[of] SOURCE. EFFECT will be an effect (move, ability,
item, status, etc), and SOURCE will be a Pokémon. These can affect the
message or animation displayed, but do not affect anything else. Other
tags include |[still] (suppress animation) and |[silent] (suppress
message).
|move|POKEMON|MOVE|TARGET
The specified Pokémon has used move
MOVEatTARGET. If a move has multiple targets or no target,TARGETshould be ignored. If a move targets a side,TARGETwill be a (possibly fainted) Pokémon on that side.If
|[miss]is present, the move missed.If
|[still]is present, the move should not animate
|[anim] MOVE2tells the client to use the animation ofMOVE2instead ofMOVEwhen displaying to the client.
|switch|POKEMON|DETAILS|HP STATUS or |drag|POKEMON|DETAILS|HP STATUS
A Pokémon identified by
POKEMONhas switched in (if there was an old Pokémon in that position, it is switched out).For the DETAILS format, see "Identifying Pokémon" above.
POKEMON|DETAILSrepresents all the information that can be used to tell Pokémon apart. If two pokemon have the samePOKEMON|DETAILS(which will never happen in any format with Species Clause), you usually won't be able to tell if the same pokemon switched in or a different pokemon switched in.The switched Pokémon has HP
HP, and statusSTATUS.HPis specified as a fraction; if it is your own Pokémon then it will beCURRENT/MAX, if not, it will be/100if HP Percentage Mod is in effect and/48otherwise.STATUScan be left blank, or it can beslp,par, etc.
switchmeans it was intentional, whiledragmeans it was unintentional (forced by Whirlwind, Roar, etc).
|detailschange|POKEMON|DETAILS|HP STATUS or
|-formechange|POKEMON|SPECIES|HP STATUS
The specified Pokémon has changed formes (via Mega Evolution, ability, etc.) to
SPECIES. If the forme change is permanent (Mega Evolution or a Shaymin-Sky that is frozen), thendetailschangewill appear; otherwise, the client will send-formechange.Syntax is the same as
|switch|above.
|replace|POKEMON|DETAILS|HP STATUS
Illusion has ended for the specified Pokémon. Syntax is the same as
|switch|above, but remember that everything you thought you knew about the previous Pokémon is now wrong.
POKEMONwill be the NEW Pokémon ID - i.e. it will have the nickname of the Zoroark (or other Illusion user).
|swap|POKEMON|POSITION
Moves already active
POKEMONto active fieldPOSITIONwhere the leftmost position is 0 and each position to the right counts up by 1.
|cant|POKEMON|REASON or |cant|POKEMON|REASON|MOVE
The Pokémon
POKEMONcould not perform a move because of the indicatedREASON(such as paralysis, Disable, etc). Sometimes, the move it was trying to use is given.
|faint|POKEMON
The Pokémon
POKEMONhas fainted.
Minor actions
Minor actions are less important than major actions. In the official client, they're usually displayed in small font if they have a message. Pretty much anything that happens in a battle other than a switch or the fact that a move was used is a minor action. So yes, the effects of a move such as damage or stat boosts are minor actions.
|-fail|POKEMON|ACTION
The specified
ACTIONhas failed against thePOKEMONtargetted. TheACTIONin question can be a move that fails, or a stat drop blocked by an ability like Hyper Cutter, in which caseACTIONwill beunboost|STAT, whereSTATindicates where the ability prevents stat drops. (For abilities that block all stat drops, like Clear Body,|STATdoes not appear.)
|-notarget|POKEMON
A move has failed due to their being no target Pokémon
POKEMON.POKEMONis not present in Generation 1. This action is specific to Generations 1-4 as in later Generations a failed move will display using-fail.
|-miss|SOURCE|TARGET
The move used by the
SOURCEPokémon missed (maybe absent) theTARGETPokémon.
|-damage|POKEMON|HP STATUS
The specified Pokémon
POKEMONhas taken damage, and is now atHP STATUS(see|switch|for details).If
HPis 0,STATUSshould be ignored. The current behavior is forSTATUSto befnt, but this may change and should not be relied upon.
|-heal|POKEMON|HP STATUS
Same as
-damage, but the Pokémon has healed damage instead.
|-status|POKEMON|STATUS
The Pokémon
POKEMONhas been inflicted withSTATUS.
|-curestatus|POKEMON|STATUS
The Pokémon
POKEMONhas recovered fromSTATUS.
|-cureteam|POKEMON
The Pokémon
POKEMONhas used a move that cures its team of status effects, like Heal Bell.
|-boost|POKEMON|STAT|AMOUNT
The specified Pokémon
POKEMONhas gainedAMOUNTinSTAT, using the standard rules for Pokémon stat changes in-battle.STATis a standard three-letter abbreviation fot the stat in question, so Speed will bespe, Special Defense will bespd, etc.
|-unboost|POKEMON|STAT|AMOUNT
Same as
-boost, but for negative stat changes instead.
|-setboost|POKEMON|STAT|AMOUNT
Same as
-boostand-unboost, butSTATis set toAMOUNTinstead of boosted byAMOUNT. (For example: Anger Point, Belly Drum)
|-swapboost|SOURCE|TARGET|STATS
Swaps the boosts from
STATSbetween theSOURCEPokémon andTARGET Pokémon.STATStakes the form of a comma-separated list ofSTATabbreviations as described in-boost`. (For example: Guard Swap, Heart Swap).
|-invertboost|POKEMON
Invert the boosts of the target Pokémon
POKEMON. (For example: Topsy-Turvy).
|-clearboost|POKEMON
Clears all of the boosts of the target
POKEMON. (For example: Clear Smog).
|-clearallboost
Clears all boosts from all Pokémon on both sides. (For example: Haze).
|-clearpositiveboost|TARGET|POKEMON|EFFECT
Clear the positive boosts from the
TARGETPokémon due to anEFFECTof thePOKEMONPokémon. (For example: 'move: Spectral Thief').
|-clearnegativeboost|POKEMON
Clear the negative boosts from the target Pokémon
POKEMON. (For example: usually as the result of a[zeffect]).
|-copyboost|SOURCE|TARGET
Copy the boosts from
SOURCEPokémon toTARGETPokémon (For example: Psych Up).
|-weather|WEATHER
Indicates the weather that is currently in effect. If
|[upkeep]is present, it means thatWEATHERwas active previously and is still in effect that turn. Otherwise, it means that the weather has changed due to a move or ability, or has expired, in which caseWEATHERwill benone.
|-fieldstart|CONDITION
The field condition
CONDITIONhas started. Field conditions are all effects that affect the entire field and aren't a weather. (For example: Trick Room, Grassy Terrain)
|-fieldend|CONDITION
Indicates that the field condition
CONDITIONhas ended.
|-sidestart|SIDE|CONDITION
A side condition
CONDITIONhas started onSIDE. Side conditions are all effects that affect one side of the field. (For example: Tailwind, Stealth Rock, Reflect)
|-sideend|SIDE|CONDITION
Indicates that the side condition
CONDITIONended for the givenSIDE.
|-start|POKEMON|EFFECT
A volatile status has been inflicted on the
POKEMONPokémon byEFFECT. (For example: confusion, Taunt, Substitute).
|-end|POKEMON|EFFECT
The volatile status from
EFFECTinflicted on thePOKEMONPokémon has ended.
|-crit|POKEMON
A move has dealt a critical hit against the
POKEMON.
|-supereffective|POKEMON
A move was super effective against the
POKEMON.
|-resisted|POKEMON
A move was not very effective against the
POKEMON.
|-immune|POKEMON
The
POKEMONwas immune to a move.
|-item|POKEMON|ITEM
The
ITEMheld by thePOKEMONhas been changed or revealed due to a move or ability. In addition, Air Balloon reveals itself when the Pokémon holding it switches in, so it will also cause this message to appear.
|-enditem|POKEMON|ITEM
The
ITEMheld byPOKEMONhas been destroyed, and it now holds no item. This can be because of an item's own effects (consumed Berries, Air Balloon), or by a move or ability, like Knock Off. If a berry is consumed, it also has an additional modifier|[eat]to indicate that it was consumed. This message does not appear if the item's ownership was changed (with a move or ability like Thief or Trick), even if the move or ability would result in a Pokémon without an item.
|-ability|POKEMON|ABILITY
The
ABILITYof thePOKEMONhas been changed due to a move/ability, or it has activated in a way that could not be better described by one of the other minor messages. For example, Clear Body sends-failwhen it blocks stat drops, while Mold Breaker sends this message to reveal itself upon switch-in.Note that Skill Swap does not send this message despite it changing abilities, because it does not reveal abilities when used between allies in a Double or Triple Battle.
|-endability|POKEMON
The
POKEMONhas had its ability surpressed, either by a move like Gastro Acid, or by the effects of Mummy.
|-transform|POKEMON|SPECIES
The Pokémon
POKEMONhas transformed intoSPECIESby the effect of Transform or the ability Imposter.
|-mega|POKEMON|MEGASTONE
The Pokémon
POKEMONusedMEGASTONEto Mega Evolve.
|-primal|POKEMON
The Pokémon
POKEMONhas reverted to its primal forme.
|-burst|POKEMON|SPECIES|ITEM
The Pokémon
POKEMONhas usedITEMto Ultra Burst intoSPECIES.
|-zpower|POKEMON
The Pokémon
POKEMONhas used the z-move version of its move.
|-zbroken|POKEMON
A z-move has broken through protect and hit the
POKEMON.
|-activate|EFFECT
A miscellaneous effect has activated. This is triggered whenever an effect could not be better described by one of the other minor messages: for example, healing abilities like Water Absorb simply use
-heal, and items that are consumed upon use have the-enditemmessage instead.
|-hint|MESSAGE
Displays a message in parentheses to the client. Hint messages appear to explain and clarify why certain actions, such as Fake Out and Mat Block failing, have occurred,
when there would normally be no in-game messages.
|-center
Appears in Triple Battles when only one Pokémon remains on each side, to indicate that the Pokémon have been automatically centered.
|-message|MESSAGE
Displays a miscellaneous message to the client. These messages are primarily used for messages from game mods that aren't supported by the client, like rule clauses such as Sleep Clause, or other metagames with custom messages for specific scenarios.
|-combine
A move has been combined with another (For example: Fire Pledge).
|-waiting|SOURCE|TARGET
The
SOURCEPokémon has used a move and is waiting for theTARGETPokémon (For example: Fire Pledge).
|-prepare|ATTACKER|MOVE|DEFENDER
The
ATTACKERPokémon is preparing to use a chargeMOVEon theDEFENDER(For example: Dig, Fly).
|-mustrecharge|POKEMON
The Pokémon
POKEMONmust spend the turn recharging from a previous move.
|-nothing
DEPRECATED: A move did absolutely nothing. (For example: Splash). In the future this will be of the form
|-activate||move:Splash.
|-hitcount|POKEMON|NUM
A multi-hit move hit the
POKEMONNUMtimes.
|-singlemove|POKEMON|MOVE
The Pokémon
POKEMONused moveMOVEwhich causes a temporary effect lasting the duration of the move. (For example: Grudge, Destiny Bond).
|-singleturn|POKEMON|MOVE
The Pokémon
POKEMONused moveMOVEwhich causes a temporary effect lasting the duration of the turn. (For example: Protect, Focus Punch, Roost).
Sending decisions
Using the Pokémon Showdown client, you can specify decisions with
/choose CHOICE, or, for move and switch decisions, just /CHOICE works as
well.
Using the simulator API, you would write >p1 CHOICE or >p2 CHOICE into the
battle stream.
Possible choices
You can see the syntax in action by looking at the JavaScript console when playing a Pokémon Showdown battle in a browser such as Chrome.
As an overview:
-
switch Pikachu,switch pikachu, orswitch 2are all validCHOICEstrings to switch to a Pikachu in slot 2. -
move Focus Blast,move focusblast, ormove 4are all validCHOICEstrings to use Focus Blast, your active Pokemon's 4th move.
In Doubles, decisions are delimited by ,. If you have a Manectric and a
Cresselia, move Thunderbolt 1 mega, move Helping Hand -1 will make the
Manectric mega evolve and use Thunderbolt at the opponent in slot 1, while
Cresselia will use Helping Hand at Manectric.
To be exact, CHOICE is one of:
-
team TEAMSPEC, during Team Preview, whereTEAMSPECis a list of pokemon slots.- For instance,
team 213456will swap the first two Pokemon and keep all other pokemon in order. TEAMSPECdoes not have to be all pokemon:team 5231might be a choice in VGC.TEAMSPECdoes not need separators unless you have over 10 Pokémon, but in custom games, separate slots with,. For instance:team 2, 1, 3, 4, 5, 6, 7, 8, 9, 10
- For instance,
-
default, to auto-choose a decision. This will be the first possible legal choice. This is what's used in VGC if you run out of Move Time. -
undo, to cancel a previously-made choice. This can only be done if the another player needs to make a choice and hasn't done so yet (or if you are callingside.choose()directly, which doesn't auto-continue when both players have made a choice). -
POKEMONCHOICEin Singles -
POKEMONCHOICE, POKEMONCHOICEin Doubles
POKEMONCHOICE is one of:
-
default, to auto-choose a decision -
pass, to skip a slot in Doubles/Triples that doesn't need a decision (can be left off, but can be useful for readability, to mean "the pokemon in this slot is fainted and won't be making a move") -
move MOVESPEC, to make a move -
move MOVESPEC mega, to mega-evolve and make a move -
move MOVESPEC zmove, to use a z-move version of a move -
switch SWITCHSPEC, to make a switch
MOVESPEC is:
MOVESLOTSPECorMOVESLOTSPEC TARGETSPEC-
MOVESLOTSPECis a move name (capitalization/spacing-insensitive) or 1-based move slot number -
TARGETSPECis a 1-based target slot number. Add a-in front of it to refer to allies. Remember that slots oppose each other, so in a battle, the slots go as follows:Triples Doubles Singles 3 2 1 2 1 1 -1 -2 -3 -1 -2 -1(But note that slot numbers are unnecessary in Singles: you can never choose a target in Singles.)
-
SWITCHSPEC is:
- a Pokémon nickname/species or 1-based slot number
- Note that if you have multiple Pokémon with the same nickname/species, using the nickname/species will select the first unfainted one. If you want another Pokémon, you'll need to specify it by slot number.
Once a choice has been set for all players who need to make a choice, the battle will continue.
All decisions except /undo can be sent with |RQID at the end. RQID is
REQUEST.rqid from |request|. Each RQID is a unique number used to
identify which action the request was intended for and is used to protect
against race conditions involving /undo (the cancel button).
If an invalid decision is sent (trying to switch when you're trapped by Mean Look or something), you will receive a message starting with:
|error|[Invalid choice]
This will tell you to send a different decision.
Choice requests
The protocol message to tell you that it's time for you to make a decision is:
|request|REQUEST
Gives a JSON object containing a request for a choice (to move or switch). To assist in your decision,
REQUEST.activehas information about your active Pokémon, andREQUEST.sidehas information about your your team as a whole.REQUEST.rqidis an optional request ID (see "Sending decisions" for details).
Example request object:
{
"active": [
{
"moves": [
{
"move": "Light Screen",
"id": "lightscreen",
"pp": 48,
"maxpp": 48,
"target": "allySide",
"disabled": false
},
{
"move": "U-turn",
"id": "uturn",
"pp": 32,
"maxpp": 32,
"target": "normal",
"disabled": false
},
{
"move": "Knock Off",
"id": "knockoff",
"pp": 32,
"maxpp": 32,
"target": "normal",
"disabled": false
},
{
"move": "Roost",
"id": "roost",
"pp": 16,
"maxpp": 16,
"target": "self",
"disabled": false
}
]
}
],
"side": {
"name": "Zarel",
"id": "p2",
"pokemon": [
{
"ident": "p2: Ledian",
"details": "Ledian, L83, M",
"condition": "227/227",
"active": true,
"stats": {
"atk": 106,
"def": 131,
"spa": 139,
"spd": 230,
"spe": 189
},
"moves": [
"lightscreen",
"uturn",
"knockoff",
"roost"
],
"baseAbility": "swarm",
"item": "leftovers",
"pokeball": "pokeball",
"ability": "swarm"
},
{
"ident": "p2: Pyukumuku",
"details": "Pyukumuku, L83, F",
"condition": "227/227",
"active": false,
"stats": {
"atk": 104,
"def": 263,
"spa": 97,
"spd": 263,
"spe": 56
},
"moves": [
"recover",
"counter",
"lightscreen",
"reflect"
],
"baseAbility": "innardsout",
"item": "lightclay",
"pokeball": "pokeball",
"ability": "innardsout"
},
{
"ident": "p2: Heatmor",
"details": "Heatmor, L83, F",
"condition": "277/277",
"active": false,
"stats": {
"atk": 209,
"def": 157,
"spa": 222,
"spd": 157,
"spe": 156
},
"moves": [
"fireblast",
"suckerpunch",
"gigadrain",
"focusblast"
],
"baseAbility": "flashfire",
"item": "lifeorb",
"pokeball": "pokeball",
"ability": "flashfire"
},
{
"ident": "p2: Reuniclus",
"details": "Reuniclus, L78, M",
"condition": "300/300",
"active": false,
"stats": {
"atk": 106,
"def": 162,
"spa": 240,
"spd": 178,
"spe": 92
},
"moves": [
"shadowball",
"recover",
"calmmind",
"psyshock"
],
"baseAbility": "magicguard",
"item": "lifeorb",
"pokeball": "pokeball",
"ability": "magicguard"
},
{
"ident": "p2: Minun",
"details": "Minun, L83, F",
"condition": "235/235",
"active": false,
"stats": {
"atk": 71,
"def": 131,
"spa": 172,
"spd": 189,
"spe": 205
},
"moves": [
"hiddenpowerice60",
"nastyplot",
"substitute",
"thunderbolt"
],
"baseAbility": "voltabsorb",
"item": "leftovers",
"pokeball": "pokeball",
"ability": "voltabsorb"
},
{
"ident": "p2: Gligar",
"details": "Gligar, L79, M",
"condition": "232/232",
"active": false,
"stats": {
"atk": 164,
"def": 211,
"spa": 101,
"spd": 148,
"spe": 180
},
"moves": [
"toxic",
"stealthrock",
"roost",
"earthquake"
],
"baseAbility": "hypercutter",
"item": "eviolite",
"pokeball": "pokeball",
"ability": "hypercutter"
}
]
},
"rqid": 3
}