Skip to content

Instantly share code, notes, and snippets.

@Kaiepi
Last active December 21, 2022 15:11
Show Gist options
  • Save Kaiepi/becc5d0ecd576f5e7733b57b4e3fa97e to your computer and use it in GitHub Desktop.
Save Kaiepi/becc5d0ecd576f5e7733b57b4e3fa97e to your computer and use it in GitHub Desktop.
Pokémon Showdown Bot F.A.Q.

Pokémon Showdown Bot F.A.Q.

What is a bot?

A bot is nothing more than a client for a Pokémon Showdown server. When you visit play.pokemonshowdown.com, you are using a client.

What language should I write my bot in?

Any language that has a WebSocket client library can be used.

Are there any references I can use to help me write my bot?

/rfaq bots includes a list of repositories for bots users in Bot Development have written. Node.js, Python, Lua, Rust, and Raku are among the languages some have been written in.

What do I need to do to write a bot?

A bot must do two things at minimum:

  • establish a connection with a Pokémon Showdown server
  • be able to understand and communicate with the server using Pokémon Showdown's protocol

Some of Pokémon Showdown's protocol is documented in PROTOCOL.md, but not all of it. I recommend opening up your browser's console (F12) to see exactly what messages the server sends and when. You may also need to inspect what the HTTP requests for connecting to the server look like if you're, say, writing a bot for a server other than sim2.psim.us (main). This can be done by clicking on the Network tab in the browser console.

It's important to note that the order messages get sent in isn't guaranteed to be the same every time. For instance, sometimes you will receive your own join message after joining a room, sometimes you won't. Your bot needs to be robust enough to handle such inconsistencies.

How do I make my bot log in?

After connecting to the server, it will send a |challstr| message containing a nonce. From here, there are two different ways to select an account. These will be explained separately.

How do I make my bot log in to an unregistered account?

Make a GET request to https://play.pokemonshowdown.com/~~showdown/action.php. The following parameters must be included in the URL:

  • act: must be getassertion
  • userid: must be the user ID you want to use
  • challstr: the nonce you received from the server

For example, here's the HTTP request for a GET request to attempt to use "morfent" as a username:

GET /~~showdown/action.php?act=getassertion&userid=morfent&challstr=4|... HTTP/1.1
Host: play.pokemonshowdown.com

The server will return what's called an assertion as a response. The following are considered errors:

  • if the assertion is just ";", this indicates that the username given is registered
  • if the assertion begins with ";;", this indicates any other type of error occurred while logging in

What to do with the assertion will be explained later.

How do I make my bot log in to a registered account?

Make a POST request to https://pokemonshowdown.com/~~showdown/action.php. A Content-Type header must be specified as being application/x-www-form-urlencoded; encoding=UTF-8. The body of the request must be a JSON object containing the following keys:

  • act: must be "login"
  • name: the username wanted
  • pass: the password wanted
  • challstr: the nonce received from the server

For example, here's an HTTP request to log in as "bongsniffer69" (note: lacks a real nonce):

POST /~~showdown/action.php HTTP/1.1
Host: play.pokemonshowdown.com
Content-Type: application/x-www-form-urlencoded; encoding=UTF-8

act=login&name=bongsniffer69&pass=notmyrealpasswordlol&challstr=4%7C...

The server will return what's called an assertion as a response. It is another JSON object prefixed with "]". Most of the metadata included isn't important; here's all you need to care about, given a variable data containing the JSON object:

  • if data.curuser.loggedin is false, either the username, password, or challstr was incorrect
  • if data.assertion starts with ";;", any other type of error occurred while logging in

Keep data.assertion and ignore the rest of the metadata. What you do with the assertion will be explained later.

OK, I have an assertion, now what do I do with it?

Send a /trn message to the global room. /trn takes three parameters, separated by commas:

  • a username
  • an avatar
  • an assertion

For example:

|/trn Morfent,128,4|...

Where should I host my bot?

I heavily recommend shelling out the money for a VPS to host your bot on. DigitalOcean and Vultr have $5 monthly VPSes that are perfectly capable of running a bot, and you have plenty of freedom when it comes to what you're capable of running on the VPS. glitch.me is a free option, but it is not a VPS and is heavily restricted in comparison.

WTF? Why is my bot locked?

Pokémon Showdown automatically locks users on hosts configured as untrustworthy proxies. This happens to include popular VPS options and glitch.me. Ask an RO to unlock your bot and make it a trusted user so it doesn't get locked again.

@Nailec
Copy link

Nailec commented Sep 14, 2019

Hi,

I'm currently trying to make a PS bot in Go. After successfully connecting to PS server I tried connecting to a registered account, unfortunately I'm getting a 404 error with the URL https://pokemonshowdown.com/~~showdown/action.php.

Here's my request (anonymised):

curl -XPOST https://pokemonshowdown.com/~~showdown/action.php -d '{"act": "login", "name": "*****", "pass": "*****", "challstr": "4|....."}' -H "Content-Type: application/x-www-form-urlencoded; encoding=UTF-8"

And the response I get is:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /~~showdown/action.php was not found on this server.</p>
<hr>
<address>Apache/2.4.7 (Ubuntu) Server at pokemonshowdown.com Port 80</address>
</body></html>

You can contact me here or on ps (Nailec) or discord (Nailec#3343, I'm on smogon's server) if that's more convenient for you.

@Nailec
Copy link

Nailec commented Sep 14, 2019

I found some code doing that from xfix here : https://github.com/xfix/showdown2irc/blob/master/showdown/parser.go

Apparently the url used does not have the ~~showdown/ part which was what caused me the error.

I am now using xfix's library to handle connection with my bot.

@Kaiepi
Copy link
Author

Kaiepi commented Sep 16, 2019

The host should be play.pokemonshowdown.com, not pokemonshowdown.com. I'll update this

@Et0san
Copy link

Et0san commented Dec 27, 2020

I don't know if this page is still up to date, but sending curl -XPOST https://play.pokemonshowdown.com/~~showdown/action.php -d '{"act": "login", "name": "*****", "pass": "*****", "challstr": "4|....."}' -H "Content-Type: application/x-www-form-urlencoded; encoding=UTF-8" results in action not found - make sure your request data includes act=something. Did I mess up somewhere?

@Kaiepi
Copy link
Author

Kaiepi commented Jan 1, 2021

  1. The body's supposed to be URL form encoded, not JSON.
  2. This needs a real nonce in order to be a valid request.

Updated to clarify that.

@Et0san
Copy link

Et0san commented Jan 2, 2021

  1. The body's supposed to be URL form encoded, not JSON.
  2. This needs a real nonce in order to be a valid request.

Updated to clarify that.

Thanks, I get it now.

@NTherrien-625
Copy link

How do I get to the /rfaq bots list of repositories?

@singiamtel
Copy link

singiamtel commented Dec 21, 2022

How do I get to the /rfaq bots list of repositories?

A bit late for this, but it's in the bot development room in Showdown, you can join with /j botdev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment