• Follow our Instagram!
  • Curious about what we're currently doing about bots? Check out the latest updates from staff in this thread.

PsyMew - Open Source AI Battle Bot Project!

PsyMew — An Open-Source AI Battle Bot Project for Pokemon Showdown based on FoulPlay!​


mew.gif


GitHub​




Hey everyone,

I've been working on a side project for a while now and figured it was finally in a good enough state to share. It's called PsyMew — an open-source Pokemon Showdown battle bot that uses LLMs (Google Gemini or Anthropic Claude) to actually reason about its moves instead of relying on hardcoded logic.

The basic idea: instead of a traditional minimax or damage-calc-only approach, the bot captures the full battle state every turn — your team, the opponent's known info, field conditions, hazards, speed tiers, everything — scores every legal move and switch, then hands it all to an LLM and says "pick the best play." The AI gets real damage estimates, type effectiveness scores, threat assessments, and game-phase context, so it's not just vibing — it has actual data to work with. But it can also reason about things like predicting switches, setting up, or knowing when to play safe vs. take risks.

It started as a fork of Foul Play (big shoutout to pmariglia for the original work), and I basically ripped out the decision engine and replaced it with an LLM pipeline. The MCTS engine from poke-engine is still there as a fallback if the AI gets rate-limited or goes down.




What it can do right now​


  • AI-powered move selection — Gemini 2.5 Pro or Claude Sonnet 4 reads the full battle context and picks moves via function calling. It's not just "pick the super effective move" — it considers positioning, endgame scenarios, switch predictions, etc.
  • Move & switch scoring — Every action gets a 0-100 score based on type effectiveness, STAB, damage, abilities, weather. The AI sees these scores but can override them with strategic reasoning.
  • Threat assessment — Each turn it calculates what the opponent's best move is against you, whether they outspeed, and if they can KO. Warns the AI when it's in danger.
  • Game-phase awareness — Plays differently in early game (info gathering, positioning) vs. endgame (exact KO calcs, every HP matters).
  • Multi-format — Works in random battles, OU, other singles formats, and doubles is WIP.
  • Tutor mode (WIP) — A coaching mode where it comments on your opponent's plays turn-by-turn and gives post-game reviews. Still rough but it's a fun experiment.
  • Fallback MCTS — If the LLM is unavailable, poke-engine takes over automatically.




How it works (the nerdy bit)​


Every turn the bot:

  1. Snapshots the full battle state — both teams, field, hazards, weather, turn history
  2. Scores every legal move (0-100) using type charts, STAB, base power, abilities, weather
  3. Runs a threat assessment on the opponent's active mon — best move against you, speed comparison, KO potential
  4. Figures out game phase — early game vs. endgame, numbers advantage/disadvantage
  5. Packs all of this into a structured prompt and sends it to Gemini/Claude with a function-calling schema
  6. The LLM picks the action — it usually follows the scores but can deviate for strategic reasons

It's honestly kind of fascinating to watch. Sometimes it makes plays I wouldn't have considered, and sometimes it does something baffling. That's LLMs for you lol.




Getting started​


If you want to try it out, the setup is pretty straightforward:

Code:
git clone https://github.com/professor-conifer/PsyMew.git
cd PsyMew
pip install -r requirements.txt
cp .env-example .env
# edit .env with your Showdown username/password

# authenticate with your AI provider (pick one):
python gemini_login.py    # if you have Google AI Pro
python claude_login.py    # if you have Claude Pro/Max
# or just add GEMINI_API_KEY=... or ANTHROPIC_API_KEY=... to .env

python start.py

You'll need Python 3.11+ and Rust (for compiling the MCTS fallback engine). Full details in the README.

It supports Google OAuth, API keys, Claude Code OAuth, and a few other auth methods — basically whatever you already have should work.




This is an open project — I want your help​


I'm not posting this just to show off a thing I made. I'm posting it because I want this to be a community project. The whole reason it's open source is because I think this is way more interesting as something people build together than something one person tinkers with alone.

Whether you're a competitive player, a developer, or just someone who thinks the idea of an AI playing Pokemon is cool — there's a way to contribute:

  • Play against it and tell me what happens — I mostly test in random battles and gen9 singles. If you run it in other formats and it falls apart, that feedback is gold. Battle logs and replays are super helpful.
  • Help with the AI prompts — The system prompt and turn prompt are basically the bot's brain. If you're into prompt engineering or just know competitive Pokemon really well, you can directly improve how the bot thinks. The prompts are all in plain Python — no ML background needed.
  • Doubles support — It technically works in doubles but it needs serious work. If you know doubles mechanics and want to take a crack at it, that'd be incredible.
  • Tutor mode — There's a coaching mode where the bot comments on your plays and gives post-game reviews. It works but the commentary is inconsistent. If you want to experiment with making that better, the tutor module is pretty self-contained and easy to hack on.
  • Bug reports & ideas — If the bot does something obviously wrong, open an issue. Even if you don't code, just describing what went wrong helps a lot.
  • Or literally anything else — Better logging, tests, documentation, new features, refactors — it's all welcome. The codebase is pretty approachable and I'm happy to walk people through it.

Seriously, even if you've never contributed to an open-source project before, this is a great one to start with. It's a small codebase, the problem domain is fun, and I'm not going to gatekeep PRs. If your change makes the bot smarter or the code cleaner, it's getting merged.




Some things to keep in mind​


  • This is a hobby project. It's not perfect and probably never will be — but that's part of the fun.
  • It does require a Gemini or Claude API key (or a Pro/Max subscription for OAuth). The MCTS fallback works without any AI credentials though.
  • The bot is as good as the LLM behind it. Gemini 2.5 Pro is surprisingly solid at competitive reasoning, but it still makes questionable plays sometimes.
  • It's GPL-3.0 licensed — fully open source, fork it, mod it, do whatever.




If you've read this far, thanks for your time. I'd really appreciate any feedback — whether it's about the bot's play quality, the code, the project direction, or just cool ideas for what an AI-powered battle bot could do. This has been a really fun intersection of two things I'm passionate about (AI and competitive Pokemon) and I hope some of you find it interesting too.

Drop a reply if you try it out or have questions. Happy to help with setup or discuss the technical side.

GitHub: professor-conifer/PsyMew

Not affiliated with Pokemon Showdown, Smogon, Nintendo, Game Freak, or The Pokemon Company. Just a fan project.
 
Interesting. To be honest I am normally skeptical of LLM's in general with it comes to battling, mostly because of inference cost of a large model compared to optimized MCTS. But your idea to feed it 'condensed' data (I'm guessing things like damage rolls) is new to me.

I see one possible improvement. You currently use PokeEngine's search results as a fall back, but why not incorporate that information into what you give the LLM? I know that foul play returns multiple determinizations of the opp's team, each with an associated probability. And for each of these determinizations, PokeEngine returns marginal UCB1 stats (visit counts, average scores) for each player. And I know he's tried a branch where PokeEngine returns the full matrix, visits and average values for all pairs of moves. I think this could potentially be a rich source of strategic information.

Thank you for sharing. Also I relate to your want to democratize the project, so to speak :)
 
I love your suggestion! I've actually been experimenting on a branch with incorporating the PokeEngine's information to the LLM more so that better thought out and strategic decision making can occur more consistently since dabbling route has seemed to be improving the battle experiences in my test runs.

And for each of these determinizations, PokeEngine returns marginal UCB1 stats (visit counts, average scores)

^ this seems exactly what I've been looking for at that too! So I will definitely look into your approach and give it a shot on a new branch! (Or you're always welcome to do so yourself and send a PR ;D )

Thank you again for the suggestion though! Totally worth looking into!
 
I am normally skeptical of LLM's in general with it comes to battling, mostly because of inference cost of a large model compared to optimized MCTS
Oh and yes that was a concern of mine when I started it with Claude, so I'd shifted my efforts into Gemini support for a more cost efficient alternative and currently in the works of adding support for the new DeepSeek V4 Preview series, as personally I've found it the first open source model (and out of the cheaper api providers for AI lol) that I've gotten Claude comparable results and accuracy with for fractions of the cost, so hoping the DeepSeek integration when that's finished will incredibly lower any costs from running PsyMew (wasn't too bad on Gemini but Claude API burns like paper doing anything)

Last night I put $5 in DeepSeek API to sort of stress test the model a bit on some different projects and burned through almost 30m total tokens at ~$2.50 so having some more recent faith in LLM still being a viable option for this project idea for now hahaha
 
I know that foul play returns multiple determinizations of the opp's team, each with an associated probability. And for each of these determinizations, PokeEngine returns marginal UCB1 stats (visit counts, average scores) for each player. And I know he's tried a branch where PokeEngine returns the full matrix, visits and average values for all pairs of moves. I think this could potentially be a rich source of strategic information.
Well your feedback absolutely improved the battle performance from the LLM! That missing data from PokeEngine was absolutely the spice it needed! Idk if you have GitHub but I can totally throw you credit in the README for the drastic improvement your feedback brought! Those changes paired really well with the new DeepSeek support added too xD I just gotta update the docs when I can fit it in so that DeepSeek config is added and explained :D
 
Back
Top