Pokemon Battle Predictor
Your battle's future is now in sight
A Machine Learning Browser Extension
Pokemon Battle Predictor is a browser extension for Pokemon Showdown which uses TensorFlow.js machine learning models trained on 100,000+ battles to tell you the current probability of:
Who will win the battle
Your opponent switching out or choosing a move
Which move they will use if they stay in
Which Pokemon they will switch to if they switch
This extension is currently in beta, so if you find any bug or have any suggestions, please email firstname.lastname@example.org with them!
How does it work?
Step 1: Search
The best way to learn what someone will do in the future is by knowing what they and others have done in the past, so the first in this project was searching for data on people playing Pokemon. Enter Pokemon Showdown, an online Pokemon battle simulator which supports many different kinds of ways people play and is conveniently made by data nerds as well!
After a battle, users can upload their battle to the Pokemon Showdown server, which can then be viewed by anyone at a latter date. Because of the site's popularity among competitive players, there are millions of battles to possibly learn from. Along with storing past battles, an extensive set of usage statistics for the meta-games they support are calculated, including insightful info such as the most common moves a Pokemon uses in battle, how often one Pokemon wins over the other, and more. This combination of breadth and depth of data made this the best source.
However, with so much data, choosing only what is relevant is key. At the time of writing this, the most popular/recent meta-games are changing rapidly as new moves and Pokemon were added recently, so the choice was made to focus on meta-games based on the older games as they're stability makes the predictions more useful. In the coming weeks, support for predicting Galar region battles will be added back, but for now the extension is sticking with meta-games from Kanto to Alola. The only problem with doing this is those meta-games are much less popular, resulting in less available data, but there's still enough to at least predict the chance to win.
The last consideration is making sure the people in the battles being learned from know what they're doing themselves. Thankfully players on Showdown have rankings based on how often they win, so only battles of players above a decent ranking are considered. In theory, the best results would com from having separate models for different segments of ratings as players on the lower end of rankings will play much differently than those at the top. This will be done in the future if a more efficient way of downloading past battles is found (Showdown only displays the past ~1200 battles uploaded and far more are needed at a time).
Step 2: Train
The heart of this project, machine learning models enable the program to make it's predictions. The TensorFlow.js API is used to create different neural networks which are trained from the parsed and prepared data from all the games for a meta-game for the 4 different types of predictions. If you are unfamiliar with machine learning, you should read parts of this simplified overview to learn more before continuing. (Or just read all of it, you'll learn some pretty cool stuff!)
Because each model is run at the start of every turn and does not know every detail about the opponents team, the model makes its predictions based on information that's available to both players after the previous turn finished and general past player behavior. All of the models have the same groups of inputs which are taken for each turn of each battle:
Each Pokemon's current HP*
Each Pokemon's statuses (burn, paralysis, poison, sleep, freeze, & toxic)*
Stat boosts on either side
The volatile and side effects on either side
Weather and pseudo-weather active
Which Pokemon are in on either side*
The "Switch Coefficient" for the Pokemon who are in
How often one Pokemon switches out when then the opposing Pokemon is also in
The inputs within each group are different depending on the meta-game to reflect what Pokemon available, effects possible, moves usable, etc. Seemingly necessary attributes like a Pokemon's item, type(s), or ability are not included because that information is mostly consistent across a Pokemon species within a meta-game, so just knowing a specific Pokemon is present does a good job of encapsulating those ideas. Inputs with a "*" are ones that require a one-hot representation in order for the models to understand the significance of those values for a specific Pokemon. This means there's two inputs (one for you and one for your opponent) of each of those values for every Pokemon available. In order to prevent the number of inputs from getting too large, Pokemon with a significantly lower tier than the model's meta-game do not have inputs for the 6 different statuses they could have.
The models will take those inputs and be trained with the goal of calculating the chance of its desired output. Key word here is chance, as there is a difference between trying to predict what will happen next and the chance of something happening. The difference is the former is judged by the accuracy of each prediction while the latter is judged by whether the outputs of a specific chance are accurate "that chance" of the time. Predicting chance was chosen as this is far more useful for any kind of game and this one in particular is way too random to find anything but chance reliably.
To train the models, they are fed the inputs with their correct outputs and the outputs are where the shapes of the models diverge. For predicting the chance to win, the models were trained on an equal number of turns where the battle's outcome was player 1 or player 2 winning so the model learns to return a signal number where a high value means player 1 will win and a low value means player 2 will win. The model for whether your opponent will choose to make a move or switch out the next turn works similarly where instead the correct outputs are a 1 when the opponent switches and a 0 when a move is made. This model is also greatly helped by using the switch coefficient - which is found from the usages statistics mentions in step 1 - as a base for the prediction as the frequency a Pokemon switches out rather than using a move on the opposing Pokemon has a high correlation with what the opponent will do next.
Predicting who will be switched in requires first training a model where the training output is a list of all Pokemon where the Pokemon that switched in is marked as the correct answer. After that is trained, a layer is added on the end of with the same set of outputs so the model can learn which Pokemon are brought in under similar situations. For example, the first layer may only give Seismitoad a large chance to be switched in, but the second layer learns a high chance for Seismitoad should also mean a high chance for Gastrodon and Quagsire as well. For meta-games where each Pokemon on your opponent's team are not revealed at the start, the usage statistics are used to assign the likelihood of who the unrevealed are based on the most common teammates of the revealed Pokemon. This model would be aided if an "inverse switch coefficient", how often a Pokemon not already in switches in on the opposing Pokemon, was added as an input, but considering one of this input would have to be added for each Pokemon, it was decided not worth the increase in model size.
For predicting what move your opponent will use, the model was trained where it would predict the chance of every move being used, then base on which Pokemon is in, would multiply those chances by 1 if it's known that Pokemon in battle knows that move or the usage percent for that move from the most recent moveset usage stats. This is done to both teach the model what moves a Pokemon can use and the likelihood of the Pokemon having the learnable move.
It should be noted that neural networks, especially for predicting the chance to win, are not the "right" models to solve these problems. It was honestly surprising the winning chance model using this method worked! However, given that the models are still very effective at their goal and this project started as a Tensorflow.js experiment, neural networks were used throughout. This may change with future updates.
Step 3: Battle
Once the models are trained and tested, it's time to put them to use! The Pokemon Battle Predictor extension runs a lighter version of the code used to make the models to provide just the functionality needed to understand what the current state of the battle is and make the prediction. It works by adding code to a Pokemon Showdown battle which translates their representation of a battle at the end of each turn into a form the models can accept, running the models to find their predictions, and creating UI elements on the page to show what was found. Users can also choose which predictions they want to see at a time.