Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/smogon/pokemon-showdown-client/llms.txt

Use this file to discover all available pages before exploring further.

The Pokémon Showdown test client (testclient-old.html) is the official way to develop and test client changes without running the full production infrastructure. It loads its game data and configuration from the live play.pokemonshowdown.com servers, but you can redirect its WebSocket connection to any server you control — including one running entirely on your local machine. This page walks through the connection mechanics, the test key system that makes local login practical, and the hard limits of the test client even when everything is configured correctly.
You must run node build (Windows) or ./build (macOS / Linux) before the test client will work. The build step compiles the TypeScript source and bundles the data files. Node.js v20 or later is required.

Connecting to a Custom Server

The Query String Format

Pass the target server’s host and port as a query string argument to testclient-old.html, prefixed with ~~:
testclient-old.html?~~host:port
For a Pokémon Showdown server running locally on the default port:
testclient-old.html?~~localhost:8000
When testclient-old.html loads, it reads location.search and parses the ?~~ prefix with this inline script:
(function() {
  if (location.search !== '') {
    var m = /\?~~(([^:\/]*)(:[0-9]*)?)/.exec(location.search);
    if (m) {
      Config.server = {
        id: m[1],
        host: m[2],
        port: (m[3] && parseInt(m[3].substr(1))) || 8000
      };
    } else {
      alert('Unrecognised query string syntax: ' + location.search);
    }
  }
})();
If no port is provided, it defaults to 8000. If the query string is present but does not match the ?~~ prefix, an alert is shown.

Browser Quirk: ? Becomes %3F on Local Files

Some browsers URL-encode the ? character to %3F when the page is opened from the local filesystem (file:// protocol), which breaks the query string parsing entirely.
1

Install a local HTTP server

From the root of the repository (the directory containing this README), run:
npx http-server
This starts a static file server on http://localhost:8080 by default.
2

Navigate using HTTP, not file://

Open your browser and go to:
http://localhost:8080/play.pokemonshowdown.com/testclient-old.html?~~localhost:8000
Because the page is served over HTTP, the browser will not encode the ? character, and the query string will be parsed correctly.
3

Confirm the connection

The main menu should display “Connecting…” and then show the lobby of your custom server. If your server is not running yet, you will see a connection error in the chat log.

The Test Key System

Why It Exists

For security reasons, browsers enforce Cross-Origin Resource Sharing (CORS) policies that prevent arbitrary websites from controlling your PS session or reading your login cookies. This is a good thing for production — it means a malicious site cannot use your account — but it creates friction when you want to log in on the test client, because the test client’s origin (localhost or file://) does not match play.pokemonshowdown.com. Without a test key, the default fallback requires you to manually copy and paste your session ID from the production site into a prompt every time you log in. If you are iterating rapidly, this becomes tedious quickly.

Setting Up config/testclient-key.js

1

Get your session ID (sid)

Log into play.pokemonshowdown.com in your browser, then navigate to:
https://play.pokemonshowdown.com/testclient-key.php
This page displays your current sid cookie value as plain text. Copy it.
2

Create the key file

Create a new file at config/testclient-key.js (in the repository root’s config/ directory) with this content:
const POKEMON_SHOWDOWN_TESTCLIENT_KEY = 'sid';
Replace sid with the actual session ID string you copied in the previous step.
3

Verify the file location

The path must be config/testclient-key.js relative to the repository root — not play.pokemonshowdown.com/config/testclient-key.js. The HTML file loads it with:
<script src="../config/testclient-key.js"></script>
which resolves one directory above play.pokemonshowdown.com/.
Your sid cookie is a live session credential. Do not commit config/testclient-key.js to version control. The file is listed in .gitignore for this reason. Treat it like a password — if it leaks, anyone can act as you on Pokémon Showdown until the session expires or you log out.

What Still Won’t Work

Even with a correctly configured test key and a running custom server, certain features are permanently unavailable in the test client:

Registering an Account

You cannot create a new registered Pokémon Showdown account from the test client. The registration flow requires the production login server, which the test client cannot fully interact with due to CORS restrictions.

Logging into Other Accounts

You can only log in as yourself (the account whose sid is in the key file). Switching to a different registered account is not supported. You can still switch to unregistered (guest) accounts and back, however.
Everything else — battles, team builder, replays, chat, tournaments, custom rooms, and all client UI features — can be tested normally.

Login Server Warning

This repository does not include instructions for running your own Pokémon Showdown login server, and the maintainers will not provide them. Do not ask for help with this. If you misconfigure a login server, your users’ passwords can be exposed. Only attempt to run a login server if you fully understand the security implications and can do so without assistance.
The test client is intentionally designed so that you do not need a login server to test most client features. The test key mechanism lets you authenticate as yourself against the production login server while your custom game server handles everything else.

SockJS Version Management

The test client depends on SockJS for its WebSocket transport layer. When SockJS needs to be upgraded to a newer version, a manual patching step is required to make it work correctly with nw.js (the desktop client environment). After updating the minified SockJS file, find every occurrence of this pattern in the minified source:
.call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})
And replace each one with:
.call(this,window)
This patch is documented in UPGRADING-SOCKJS.md at the repository root. The standard SockJS build checks for multiple global object candidates (global, self, window) in order, but the nw.js environment exposes global with a different shape than expected, causing the transport to fail. Pinning to window directly bypasses the detection logic.
The patched SockJS file is already committed to the repository as play.pokemonshowdown.com/js/lib/sockjs-1.4.0-nwjsfix.min.js. You only need to apply the patch manually when upgrading to a newer SockJS version.

Quick Reference

Local server URL

http://localhost:8080/play.pokemonshowdown.com/
testclient-old.html?~~localhost:8000

Test key file path

config/testclient-key.js
(repository root, not play.pokemonshowdown.com/config/)

Get your sid

https://play.pokemonshowdown.com/testclient-key.php

Start local file server

npx http-server
Run from the repository root directory.

Build docs developers (and LLMs) love