While battle simulations are more accurate for specific situations, TDO, which stands for "total damage output", can be a very useful way to rank pokemon and their attacks. TDO is equal to the amount of damage a pokemon can dish out before dying. The advantages of TDO include:

- It incorporates a Pokemon's offensive and defensive ability in one useful number
- It is just a formula, so it can be plugged into excel
- You don't need to specify the defender's moves or stats
- If two pokemon battle, the one with higher TDO will do better every time

*Actual* TDO requires battle simulations to calculate. But TDO is easy to approximate with just a formula. This approximation is what is seen on pokemon spreadsheets*. Not everyone uses the same approximations, and some formulas are better than others. We have spent some time to come up with a formula that incorporates energy gains from taking damage and other edge-effects.

The approximate formulas for TDO and tankiness itself are simple.

$$TDO_{prop} = DPS1 * HP * DEF$$ $$Tankiness_{prop} = HP * DEF$$DPS1 is your DPS against a target with 1 defense, and HP, DEF are the hit points, defense of your pokemon. But even though these formulas are short, the formula for DPS itself is a bit more complex. This is to take into account corrections for energy gains from damage and wasted energy gains from dying early. It is given in its full form at the very bottom of this page!

*Actually what is used is not TDO, but a formula which is *proportional to* TDO, meaning the TDO of each pokemon is off by some constant factor. This is good enough, because all that we need is each Pokemon's *relative* ranking to make moveset or counter decisions.

The spreadsheet has every pokemon so it is too big for this page. It lists all combinations of moves, including legacy moves.

Survival time was based on t5 raid bosses.- It only considers the attacker, not the matchup. This makes the TDO formula simpler and more general, but if two enemies have very different stats, the TDO values will be off for at least one of them. Of course this means that TDO does not account for type advantages (although it does account for STAB).
- Discontinuities: TDO calculates as if there were a steady stream of damage & energy going between attacker and defender. The advantage of this is that it is less matchup-specific: changing a pokemon from level 29 to 30 will not make a big difference. However if you want to find the winner for a particular combination of levels/IVs, TDO will be less accurate than a simulation. This is especially true for shorter battles where edge effects have not had time to average out.

Tankiness has some flaws too. Doing lots of damage actually should decrease your survival time because the enemy gains more energy. This is not accounted for in just DEF * HP, but for gym defenders it won't make a big difference.

In a world of simulations, what is the use of TDO anymore? A few things. Simulations are good at looking at very specific matchups, but it is very hard to average simulations in an accurate way that gets an overall metric of a pokemon as each battle introduces different biases. This makes approximate TDO and DPS an attractive, yet approximate, overall metric.

Another advantage of TDO is ease of use. You just plug and chug... no programming. Use it on excel sheets etc to get quick results without investing a lot of time and effort on tons of simulations.

Then multiply by HP_A * HP_B on both sides of the equation to get the equivalent condition:

$$DPS_A * HP_A > DPS_B * HP_B$$Therefore DPS * HP is what determines which pokemon wins. But DPS_A depends on DEF_B and vice-versa... It would be nice to have only properties of pokemon A on the left side, and only pokemon B on the right side. So let's define a new variable, DPS1, which is DPS but with the DEF factored out. It is the DPS you would do against a target with 1 defense:

$$DPS_A = \frac{DPS1_A}{DEF_B}$$Plug it into the inequality:

$$\frac{DPS1_A}{DEF_B} * HP_A > \frac{DPS1_B}{DEF_A} * HP_B$$And multiply by DEF_A * DEF_B on both sides:

$$DPS1_A * HP_A * DEF_A > DPS1_B * HP_B * DEF_B$$So equivalently, the pokemon who wins is the one with the highest DPS1 * HP * DEF. Often TDO is seen written as ATK * DEF * HP... you can see that these are similar because DPS is proportional to ATK. But DPS1 * HP * DEF is more accurate so it is the one we will use.

In the last section we showed the TDO formula and justified its usefulness:

$$TDO_{prop} = DPS1 * HP * DEF$$*HP* and *DEF* are the base stats of the pokemon whose TDO we are finding. Base stats can be found in the game master file or on gamepress. Now we just need to find our pokemon's DPS. We can find DPS instead of DPS1 because they only differ by a constant factor equal to the enemy's defense... but we are only finding something *proportional* to TDO anyway, so that constant factor doesn't matter.

To figure out the DPS formula, let's write a few definitions. A "cycle" is a series of Fmoves, and then one Cmove. *wDPS*, or "weaveDPS" is the damage per second you do on average throughout that cycle, while "weaving" together fast and charge moves. Since DPS is damage over time, over one cycle *wDPS* can be calculated as

*FDmg, CDmg*are the damage done by your pokemon's Fast and Charge moves. This depends on the damage formula.*nFPC*is the number of Fast Moves Per Cycle*CT*is cycle time: how many seconds the cycle lasts.

So now we need to find expressions for *nFPC* and *CT*.
*CT* can be broken down into the time spent on each move type:

*CDuration* and *FDuration* can be found in the game master file. So now we just need *nFPC* to plug into the DPS equation. The number of fmoves per cycle can be calculated as

*FE*is the "Fmove Energy gain", how much energy you gain for using that Fmove.

We can find *totalFmoveEnergyGainsPerCycle* based on what percent of energy gains come from Fmoves (the rest comes from taking damage). We will look only at the time period from the start of a cycle until the beginning of the next Cmove. During this time the percent of energy gains from Fmoves is:

*EPS*is the Energy Per Second gained by either spamming FMoves or taking damage from the enemy.

The formula above is just the ratio of Fmove energy gains divided by total energy gains. Remember that in pokemon go, you take gain half of the damage you take back in energy. So next we can plug in

$$EPS_{dmg}=EnemyDPS/2, EPS_{Fmoves}=\frac{FE}{FDur}$$*EnemyDPS* is not known since much of the usefulness of TDO is that it only depends on the attacker, but an approximate formula we will use for tier 5 raids is *EnemyDPS* = 1930/*DEF*. With *PercentEnergyFromFmoves*, we are now ready to calculate *totalFmoveEnergyGainsPerCycle*.

From the start of a cycle until the beginning of a Cmove (assuming you use the Cmove as soon as you have enough energy) you gain energy equal to

$$CE - CDur * EPS_{dmg}$$*CE*is the Cmove's Energy cost.

This formula needs some explanation. At first you might think that the whole thing should just be *CE*. The remaining term is there to account for leftover energy from the previous cycle:

*- CDuration * EPS_dmg* is there because we are only counting the period from the end of the previous Cmove until the beginning of the next Cmove. But before this period - namely, while the previous Cmove was happening - you were still taking damage and gaining energy for it. That energy gain is equal to *CDur * EPS_dmg*. On the first cycle you do not have this energy, but we do not change the formula to account for that because there are extra energy gains in the first cycle from the extra Fmove which the defender does at the very beginning of the battle.

A little note: For full-bar charge moves we can make the above expression for energy gains more accurate by replacing it with $$CE +FE/2- (CDur - CDWS) * EPS_{dmg}/2$$

*CDWS*is the Cmove DamageWindowStart, which is a variable listed in the game master file. It is the time at which damage is applied and energy is used up for a Cmove. This is different for 100energy moves because since your bar was full after starting the Cmove you could not gain as much energy before starting the next cycle.- The
*+FE/2*term is there because unless you have a full bar Cmove, you most likely gained a bit more energy than you needed from spamming Fmoves in the previous cycle. The "overshoot energy" is, on average,*FE/2*.

The above correction comes from the fact that for full-bar moves you can only begin to gain energy once you have used up the Cmove's energy. This modification won't make a huge difference, and it adds an "if" statement to the formula depending on CE, so it may be skipped.

Now we can wrap the previous equations together:

$$totalFmoveEnergyGainsPerCycle$$ $$ =(CE - CDur * EPS_{dmg}) * PercentEnergyFromFmoves $$ $$ =(CE - CDur * EPS_{dmg}) * \frac{EPS_{FM}}{EPS_{FM} + EPS_{dmg}} $$..and divide to get

$$ nFPC = \frac{totalFmoveEnergyGainsPerCycle}{FE} $$ Now we are finally ready to calculate*wDPS*, which is the average damage per second you get throughout a cycle. We had $$wDPS_{simple} = \frac{CDmg + nFPC * FDmg}{CT}$$ Why did I add the "simple" subscript to

*wDPS*? Often, the battle ends and you still have wasted energy left. So for the last 0.5 cycles or so, your DPS will just be FMove DPS. We can account for this by taking a weighted average of

*wDPS*with

*FDPS*, which is the DPS you get from just spamming Fmoves: $$wDPS_{actual} = $$ $$\frac{nC * wDPS_{simple} + 0.5 * FDPS}{nC + 0.5}$$ where $$FmoveDPS = FmoveDamage/FmoveDuration$$

*nC*is the number of Cmoves you do throughout the battle

Now we need *nC:*

0.5 is subtracted here because this formula *should* have a floor() function in it: If you don't survive until the end of the cycle, you don't get to do the Cmove. But the floor would give it discontinuities which give bad results, so we "average it out". But since a floor() function always rounds down, biases by 0.5. This bias must be included.

At this point, there is a chain of variables to plug in, everything is expressed in terms of numbers which can be found in the game_master file or on Pokemon go websites, like base stats of a Pokemon. Below is a summary.

*ATK, DEF, HP*: These are the base values of a pokemon's attack, defense, and HP. They were discovered in the Game Master file and can also be found on the pokemon pages (example)*FPow, FE, FDur*: These variables stand for the Power, Energy gain, and Duration (seconds) of the pokemon's Fast move. The power is the base damage of the move. Energy gain describes how much energy you gain for using that fast move. And duration is how many seconds after the move starts until you are free to attack again. These variables can be found in the game master file or on the corresponding page for that attack (example)*CPow, CE, CDur, CDWS:*The first three variables here are the same as above, but for the pokemon's Charged move. The last stands for "damageWindowStart", another variable from the game master file.*CDWS*is the difference in time between when a move begins and when damage is dealt (in seconds).*STAB_F, STAB_C*: This stands for "Same Type Attack Bonus". When a pokemon uses a move that is the same as at least one of its types, the damage of this move is boosted by a factor of 1.2. For example, since Dragonite is dragon-type and Dragon Tail is a dragon move it will get a 1.2x damage boost. The STAB variable is this boost, so it is always either 1 (no boost) or 1.2 (boost). The boost for the F and C moves are*STAB_F, STAB_C*, respectively.

The formula for TDO can be put in terms of only the variables above. But in this form it is very long and cumbersome. Instead we will build it up out of smaller formulas. The base formula is

$$TDO = DPS * (HP + 14) * (DEF + 14)$$The DPS variable technically should depend on the enemy's defense. For this we will later plug in a typical defense of 200, although it does not matter as the order of results won't be affected by what we choose. The order is how we make decisions of which pokemon and moves are best, so that is what matters. Next we have

$$DPS = \frac{nC * DPS_{simple} + \frac{1}{2} * \frac{FDmg}{FDur}}{nC + \frac{1}{2}}$$To use the TDO formula it is not important to know the meaning of the intermediate variable names, like *FDmg* and *nC*. But if you are curious what they mean, check the derivation section.

The variables we still need to explain are *FDmg*, *DPS_simple* and *nC*:

Now all of the variables so far can be found in the game master file, except for *nFPC* and *CDmg*.

For some additional accuracy, for moves with *CE*=100, replace *CDur* with *(CDur - CDWS)* in the equation above.

So with these formulas you can calculate the TDO of any pokemon/moveset combination.

In the spreadsheets on this post, values were all scaled by the same constant so that dragonite's dragonbreath/dragonpulse TDO and DPS match results against a Raikou raid boss, from gamepress' in-house battle simulator. The proportion of all results stayed the same, so the ordering is dictated by the formula. Only the absolute numbers were scaled.

~doublefelix921