pokemon-showdown/protocol-doc.md
2014-08-26 14:33:31 -05:00

380 lines
13 KiB
Markdown

Protocol
========
Pokemon Showdown's protocol is relatively simple.
Pokemon Showdown is implemented in SockJS. SockJS is a compatibility
layer over raw WebSocket, so you can actually connect to Pokemon
Showdown directly using WebSocket:
ws://sim.smogon.com:8000/showdown/websocket
or
wss://sim.smogon.com/showdown/websocket
Client-to-server messages
-------------------------
Messages from the user to the server are in the form:
ROOMID|TEXT
`ROOMID` can optionally be left blank if it's the lobby, or if the room
is irrelevant (for instance, if `TEXT` is a command like
`/join lobby` where it doesn't matter what room it's sent from, you can
just send `|/join lobby`.)
`TEXT` can contain newlines, in which case it'll be treated the same
way as if each line were sent to the room separately.
A partial list of available commands can be found with `/help`.
To log in, look at the documentation for the `|challstr|` server message.
Server-to-client messages
-------------------------
Messages from the server to the user are in the form:
>ROOMID
MESSAGE
MESSAGE
MESSAGE
...
`>ROOMID` and the newline after it can be omitted if the room is lobby
or global. `MESSAGE` cannot start with `>`, so it's unambiguous whether
or not `>ROOMID` has been omitted.
As for the payload: it's made of any number of blocks of data
separated by newlines; empty lines should be ignored. In particular,
it should be treated the same way whether or not it ends in a
newline, and if the payload is empty, the entire message should be ignored.
If `MESSAGE` doesn't start with `|`, it should be shown directly in the
room's log. Otherwise, it will be in the form:
|TYPE|DATA
For example:
|j| Some dude
|c|@Moderator|hi!
|c| Some dude|you suck and i hate you!
Some dude was banned by Moderator.
|l| Some dude
|b|battle-ou-12| Cool guy|@Moderator
This might be displayed as:
Some dude joined.
@Moderator: hi!
Some dude: you suck and i hate you!
Some dude was banned by Moderator.
Some dude left.
OU battle started between Cool guy and Moderator
For bandwidth reasons, there are five message types: `chat`, `join`, `leave`,
`name`, and `battle`, which are sometimes abbreviated to `c`, `j`, `l`, `n`,
and `b` respectively. All other message types are written out in full so they
should be easy to understand.
Four of these can be uppercase: `J`, `L`, `N`, and `B`, which are
the equivalent of their lowercase versions, but are recommended not to be
displayed inline because they happen too often. For instance, the main server
gets around 5 joins/leaves a second, and showing that inline with chat would
make it near-impossible to chat.
Some outgoing message types
---------------------------
`USER` = a user, the first character being their rank (users with no rank are
represented by a space), and the rest of the string being their username.
####Room initialization
`|init|ROOMTYPE`
> The first message received from a room when you join it. `ROOMTYPE` is
> one of: `chat` or `battle`
`|users|USERLIST`
> `USERLIST` is a comma-separated list of `USER`s, sent from chat rooms when
> they're joined.
####Room messages
`||MESSAGE` or `MESSAGE`
> We received a message `MESSAGE`, which should be displayed directly in
> the room's log.
`|html|HTML`
> We received an HTML message, which should be sanitized and displayed
> directly in the room's log.
`|join|USER` or `|j|USER`
> `USER` joined the room.
`|leave|USER` or `|l|USER`
> `USER` left the room.
`|name|USER|OLDID` or `|n|USER|OLDID`
> A user changed name to `USER`, and their previous userid was `OLDID`.
`|chat|USER|MESSAGE` or `|c|USER|MESSAGE`
> `USER` said `MESSAGE`. Note that `MESSAGE` can contain `|` characters,
> so you can't just split by `|` and take the fourth string.
`|:|TIMESTAMP`
`|c:|TIMESTAMP|USER|MESSAGE`
> `c:` is pretty much the same as `c`, but also comes with a UNIX timestamp;
> (the number of seconds since 1970). This is used for accurate timestamps
> in chat logs.
>
> `:` is the current time according to the server, so that times can be
> adjusted and reported in the local time in the case of a discrepancy.
>
> The exact fate of this command is uncertain - it may or may not be
> replaced with a more generalized way to transmit timestamps at some point.
`|battle|ROOMID|USER1|USER2` or `|b|ROOMID|USER1|USER2`
> A battle started between `USER1` and `USER2`, and the battle room has
> ID `ROOMID`.
####Battle messages
`|player|PLAYER|USERNAME|AVATAR`
> Appears when you join a battle room. `PLAYER` denotes which player it is
> (`p1` or `p2`) and `USERNAME` is the username. `AVATAR` is the player's
> avatar identifier (usually a number, but other values can be used for
> custom avatars).
|gametype|GAMETYPE
|gen|GENNUM
|tier|TIERNAME
|rated
|rule|RULE: DESCRIPTION
> Additional details when you join a battle room. `GAMETYPE` is one of
> `singles`, `doubles`, or `triples`; `GENNUM` denotes the generation of
> Pokemon being played; `tier` is the format; and `rule` appears multiple
> times, once for each clause in effect. `rated` only appears if the battle
> is rated.
|clearpoke
|poke|PLAYER|SPECIES
|poke|PLAYER|SPECIES
...
|teampreview
> These messages appear if you're playing a format that uses team previews.
> `PLAYER` is the player ID (see `|player|`) and `SPECIES` is the
> species of the Pokemon. `teampreview` commonly appears after `rule`
> tags instead of after the Pokemon in the team preview.
`|request|REQUEST`
> Gives a JSON object containing a request for a decision (to move or
> switch). To assist in your decision, `REQUEST.active` has information
> about your active Pokemon, and `REQUEST.side` has information about your
> your team as a whole.
`|inactive|MESSAGE` or `|inactiveoff|MESSAGE`
> A message related to the battle timer has been sent. The official client
> displays these messages in red.
>
> `inactive` means that the timer is on at the time the message was sent,
> while `inactiveoff` means that the timer is off.
`|start`
> Indicates that the game has started.
**Major actions**
In battle, most Pokemon actions come in the form `|ACTION|POKEMON|DETAILS`
followed by a few messages detailing what happens after the action occurs.
A Pokemon is always identified in the form `POSITION: NAME`. `POSITION` is
the spot that the Pokemon is in: it consists of the `PLAYER` of the player
(see `|player|`), followed by a letter indicating the given Pokemon's
position, counting from `a`.
In doubles and triples battles, `a` will refer to the leftmost Pokemon
on one team and the rightmost Pokemon on the other (so `p1a` faces `p2c`,
etc). `NAME` is the nickname of the Pokemon performing the action.
`|move|POKEMON|MOVE|TARGET`
> The specified Pokemon has used move `MOVE` at `TARGET`. If a move has
> multiple targets or no target, `TARGET` should be ignored. If a move
> targets a side, `TARGET` will be a (possibly fainted) pokemon on that
> side.
>
> `move` can be tagged with `|[miss]` to indicate that the move missed.
`|switch|POKEMON|SPECIES|HP STATUS` or `|drag|POKEMON|SPECIES|HP STATUS`
> A Pokemon identified by `POKEMON` has switched in (the old Pokemon, if
> still there, is switched out).
>
> The new Pokemon has species `SPECIES`, HP `HP`, and status `STATUS`. `HP`
> is specified as a fraction; if it is your own Pokemon then it will be
> `CURRENT/MAX`, if not, it will be `/100` if HP Percentage Mod is in effect
> and `/48` otherwise. `STATUS` can be left blank, or it can be `slp`,
> `par`, etc.
>
> `switch` means it was intentional, while `drag` means it was unintentional
> (forced by Whirlwind, Roar, etc).
`|cant|POKEMON|REASON` or `|cant|POKEMON|REASON|MOVE`
> The Pokemon `POKEMON` could not perform a move because of the indicated
> `REASON` (such as paralysis, Disable, etc). Sometimes, the move it was
> trying to use is given.
`|faint|POKEMON`
> The Pokemon `POKEMON` has 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.
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 Pokemon. These can affect the message or animation displayed, but
do not affect anything else. Other tags include `|[still]` (suppress
animation) and `|[silent]` (suppress message).
`|-damage|POKEMON|HP STATUS`
> The specified Pokemon `POKEMON` has taken damage, and is now at
> `HP STATUS` (see `|switch|` for details).
>
> If `HP` is 0, `STATUS` should be ignored. The current behavior is for
> `STATUS` to be `fnt`, but this may change and should not be relied upon.
`|-heal|POKEMON|HP STATUS`
> Same as `-damage`, but the Pokemon has healed damage instead.
`|-status|POKEMON|STATUS`
> The Pokemon `POKEMON` has been inflicted with `STATUS`.
`|-boost|POKEMON|STAT|AMOUNT`
> The specified Pokemon `POKEMON` has gained `AMOUNT` in `STAT`, using the
> standard rules for Pokemon stat changes in-battle. `STAT` is a standard
> three-letter abbreviation fot the stat in question, so Speed will be `spe`,
> Special Defense will be `spd`, etc.
`|-unboost|POKEMON|STAT|AMOUNT`
> Same as `-boost`, but for negative stat changes instead.
`|-weather|WEATHER`
> Indicates the weather that is currently in effect. If `|[upkeep]` is present,
> it means that `WEATHER` was 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 case `WEATHER` will be `none`.
I'll document all the message types eventually, but for now this should be
enough to get you started. You can watch the data sent and received from
the server on a regular connection, or look at the client source code
for a full list of message types.
####Global messages
`|popup|MESSAGE`
> Show the user a popup containing `MESSAGE`. `||` denotes a newline in
> the popup.
`|pm|SENDER|RECEIVER|MESSAGE`
> A PM was sent from `SENDER` to `RECEIVER` containing the message
> `MESSAGE`.
`|usercount|USERCOUNT`
> `USERCOUNT` is the number of users on the server.
`|nametaken|USERNAME|MESSAGE`
> You tried to change your username to `USERNAME` but it failed for the
> reason described in `MESSAGE`.
`|challstr|KEYID|CHALLENGE`
> You just connected to the server, and we're giving you some information you'll need to log in.
>
> If you're already logged in and have session cookies, you can make an HTTP GET request to
> `http://play.pokemonshowdown.com/action.php?act=upkeep&challengekeyid=KEYID&challenge=CHALLENGE`
>
> Otherwise, you'll need to make an HTTP POST request to `http://play.pokemonshowdown.com/action.php`
> with the data `act=login&name=USERNAME&pass=PASSWORD&challengekeyid=KEYID&challenge=CHALLENGE`
>
> `USERNAME` is your username and `PASSWORD` is your password, and `KEYID` and
> `CHALLENGE` are the values you got from `|challstr|`. (Also feel free to make
> the request to `https://` if your client supports it.)
>
> Either way, the response will start with `]` and be followed by a JSON
> object which we'll call `data`.
>
> Finish logging in (or renaming) by sending: `/trn USERNAME,0,ASSERTION`
> where `USERNAME` is your desired username and `ASSERTION` is `data.assertion`.
`|updateuser|USERNAME|NAMED|AVATAR`
> Your name or avatar was successfully changed. Your username is now `USERNAME`.
> `NAMED` will be `0` if you are a guest or `1` otherwise. And your avatar is
> now `AVATAR`.
`|formats|FORMATSLIST`
> This server supports the formats specified in `FORMATSLIST`. `FORMATSLIST`
> is a `|`-separated list of `FORMAT`s. `FORMAT` is a format name with one or
> more of these suffixes: `,#` if the format uses random teams, `,,` if the
> format is only available for searching, and `,` if the format is only
> available for challenging.
> Sections are separated by two vertical bars with the number of the column of
> that section prefixed by `,` in it. After that follows the name of the
> section and another vertical bar.
`|updatesearch|JSON`
> `JSON` is a JSON object representing the current state of what battles the
> user is currently searching for.
`|updatechallenges|JSON`
> `JSON` is a JSON object representing the current state of who the user
> is challenging and who is challenging the user.
`|queryresponse|QUERYTYPE|JSON`
> `JSON` is a JSON object representing containing the data that was requested
> with `/query QUERYTYPE` or `/query QUERYTYPE DETAILS`.
>
> Possible queries include `/query roomlist` and `/query userdetails USERNAME`.