poke-env: a Python client that turns Pokemon Showdown into a training environment
Poke-env: Python Interface for Pokemon Showdown Bots
At a glance
- What is it?
- poke-env wraps the Pokemon Showdown battle protocol in asyncio Python classes so you can write a bot by overriding one method. It is a client and environment library, not a solver, and its correctness depends on the Showdown server you point it at.
- Who is it for?
- Adopt poke-env if you already have a Showdown server you control and you want the battle loop, protocol parsing and team handling done for you; the README's own two-RandomPlayer script is the fastest way to confirm the whole chain works before you write any agent code.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap poke-env fills between a Showdown server and an agent loop
Pokemon Showdown is a Node.js battle simulator that speaks a line-based text protocol over websockets. Writing an agent directly against that protocol means handling connection lifecycle, room names, challenge and search messages, request payloads, and the long tail of battle messages that arrive out of order relative to your own decisions. poke-env exists to absorb that layer. It is a Python library for building scripted agents, self-play experiments, and reinforcement learning workflows on Pokemon Showdown, per the README. The intended user is someone who wants to spend their time on decision logic rather than on protocol plumbing: a reinforcement learning researcher, a hobbyist writing a heuristic bot, or a class project that needs a working opponent pool. The README traces the project's origin to a group project in an artificial intelligence class at Ecole Polytechnique, which is a fair signal about the level of abstraction it aims for. It is not a framework that ships a trained model. Nothing in the repository description or README claims a built-in policy beyond the simple players used for testing.
Player, choose_move, and the asyncio battle loop
The central abstraction is the Player class. You subclass it and override choose_move, and the library handles everything around that call: connecting, authenticating, accepting or issuing challenges, tracking battle state, and submitting your chosen action back to the server. The README's quickstart path is exactly this: subclass Player, override choose_move. Concurrency is explicit rather than hidden. Player takes a max_concurrent_battles argument, and in the README's example both RandomPlayer instances are constructed with max_concurrent_battles=1, which keeps the sample deterministic and easy to reason about. The scheduling model is asyncio, so a training script is an async main function driven by asyncio.run. Two counters are exposed on the player object after battles complete: n_finished_battles and n_won_battles. Those are the numbers the README prints, and they are the minimum instrumentation you need to confirm a run is doing anything. The battle_against method on a player is the entry point for self-play, taking an opponent and an n_battles count. That is the whole visible data flow: your code builds players, players connect to a Showdown server, the library translates server messages into Python state, your choose_move returns an action, and the library serialises it back. Where the documentation is thinner is in the shape of the observation your choose_move receives and how much of the battle history is retained; the README does not describe it, and the getting started guide is the place to look.
Standing up a local Showdown server before you write any agent code
The installation story has two halves and the second one is easy to underestimate. The Python side is a single command: pip install poke-env, requiring Python 3.10 or newer. The other half is the simulator. The README is direct that a local server is strongly recommended for training and local development, and the setup is the upstream Showdown repository: git clone https://github.com/smogon/pokemon-showdown.git, then npm install, then cp config/config-example.js config/config.js, then node pokemon-showdown start --no-security. The --no-security flag is the part worth pausing on. The README states it runs a local server with most rate limiting and throttling turned off, and recommends it for development. That is a deliberate trade: you get throughput for self-play, and you accept that the server is not hardened. It should not be exposed. Once the server is up, the verification step is the README's two-RandomPlayer script, which uses the default localhost configuration and should work as-is. If that script prints a finished battle count of 1 and a win count for player 1, your chain from Python through websockets to the simulator is intact. For working on the library itself, the README gives the development path: clone the repository, run uv sync --dev, and run commands through uv run, for example uv run pytest unit_tests/.
Team generation and Smogon statistics in 0.16.x
The 0.16.0 release notes describe Smogon stats, team generation, and bo3 support, and 0.16.1 is titled as an update to the team generation algorithm. That matters because team construction is a separate problem from move selection, and a bot that cannot produce a legal team for a format cannot play it. The README points at the teambuilding algorithm as something external projects have consumed: Pokemon Team is described as using the poke-env teambuilding algorithm to generate Pokemon Showdown teams from Smogon usage statistics. The README also notes that team data comes from the Smogon forums' RMT section, and that data files are adapted versions of the js data files from Pokemon Showdown. The consequence of that last point is that poke-env ships a copy of game data rather than querying the simulator for it. When Showdown's data changes, the library's copy has to be updated in step, which is a recurring maintenance obligation rather than a one-off. The back-to-back 0.16.0 and 0.16.1 releases, three weeks apart, with 0.16.1 changing the team generation algorithm, suggest that part of the codebase is still moving. If your pipeline depends on generated teams being stable across versions, pin the version and diff the output when you upgrade.
Where poke-env is the wrong tool
The clearest limitation is architectural. poke-env is a client of an external Node.js process, so every battle is a websocket round trip to a simulator you have to run and keep alive. That is not a problem for a few hundred battles. It becomes the dominant cost for the kind of self-play volume that reinforcement learning papers describe, and the library does not present itself as solving that. There is no mention of vectorised environments, batched inference, or a headless simulator in the material. A second limitation is the public server. The README says you can use Smogon's server to try agents against humans, but frames the local server as strongly recommended. Running training against the public server is therefore against the grain of the project's own guidance, and the --no-security escape hatch only exists on a server you host. A third is scope: poke-env is a single-game environment. If your interest is in a general game-playing framework with many environments behind one API, this is a library for one simulator, and the abstraction it offers is shaped by Showdown's protocol. Finally, the README does not describe reward shaping, observation encoding, or episode boundaries. Those are the parts reinforcement learning users care most about, and their absence from the README means you should read the docs before assuming they are solved for you.
How this differs from Gym-style environment libraries
The natural comparison is with Gymnasium-style environment packages, which expose a step(action) returning observation, reward, done and info, plus reset(), and leave the transport entirely out of the picture. poke-env inverts that. Its primary interface is a Player object that owns a live connection to a server, and the extension point is choose_move, a method that returns an action rather than a step tuple. The reward signal is not part of the contract in the README's description; you derive whatever you want from battle state and the win counters. The advantage of the poke-env shape is that the same Player class works for scripted bots, human-vs-bot play on the public ladder, and learning agents, because the connection handling is shared. The cost is that you cannot trivially run a thousand environments in one process, and you inherit the simulator's process as a dependency. If your existing training loop expects Gymnasium semantics, you will be writing an adapter, and that adapter is where the interesting design decisions about observation and reward actually live.
Licence, maintenance and upgrade cost
poke-env is MIT licensed, which permits commercial and closed-source use with the usual requirement to preserve the copyright notice and licence text. The README asks for citation via a BibTeX entry rather than imposing any licence term on it; that is a request, not a condition of the MIT grant. The repository is not archived and the last push is recent, with three releases between April and August of 2026, so the project is active. The maintenance cost you take on is the coupling to Pokemon Showdown itself: the README states that data files are adapted versions of the js data files from the upstream simulator, so a Showdown data or protocol change eventually becomes a poke-env change, and your pinned version determines when you get it. A second recurring cost is the Node.js server, which needs npm install and a config file copied into place before first run. Neither of these is large, but both are ongoing. If you deploy a bot that plays a live format, budget for the fact that the format's data and the library's copy of it move on different schedules.
Editorial conclusion
Adopt poke-env if you already have a Showdown server you control and you want the battle loop, protocol parsing and team handling done for you; the README's own two-RandomPlayer script is the fastest way to confirm the whole chain works before you write any agent code. Do not adopt it if you need a maintained training stack with vectorised environments, or if you want to run serious self-play against the public play.pokemonshowdown.com server, since the project explicitly recommends a local server with --no-security instead. Verify first that your Python is 3.10 or newer, that your local server starts, and that the team generation path in 0.16.x produces teams for the format you actually intend to train on.
Community notes