This package provides the core logic required for parsing and analyzing Pokémon Showdown battle logs, classifying specific types of teams or Pokémon, and producing various reports about their usage. This project began as a translation of Gilad "Antar" Barlev's Smogon-Usage-Stats (including updates from Mathieu "Marty" Dias-Martins) from Python to TypeScript, though has since been extended, optimized, and corrected.
This package can be used together with @pkmn/logs
to efficiently process gigabytes of
battle logs within minutes to produce the reports hosted at https://www.smogon.com/stats/. It also
supports a custom binary format based on
@pkmn/engine
data and used by pkmn projects
such as EPOKé or 0 ERROR.
$ npm install @pkmn/stats
The most naive way of using @pkmn/stats
is to iterate over a collection of logs, run them through
the Parser
and use Stats
to compute various statistics that can then be
displayed by Display
:
import {Dex} from '@pkmn/dex';
import {Generations, GenerationNum} from '@pkmn/data';
import {Parser, Stats, Display} from '@pkmn/stats';
const GENS = new Generations(Dex);
const gen = GENS.get(8);
const format = 'gen8ou';
const cutoffs = 1500;
const stats = Stats.create();
for (const log of logs) {
const battle = Parser.parse(gen, format, log);
Stats.update(gen, format, battle, cutoffs, stats);
}
console.log(Display.fromStatistics(gen, format, stats));
When attempting to generate statistics for a large (100GiB+) corpus, @pkmn/stats
can be used in
tandem with @pkmn/logs
to efficiently produce the statistics and reports that are
desired by your application.
The Parser
class takes in Pokémon Showdown stored battle logs 'parses' it into a Battle
object
that can be processed by Stats
. The parsing done by @pkmn/stats
is highly specific to the type
of analysis that it performs and is not likely to be useful for other applications - robust parsers
should be built on top of pkmn/protocol
.
pkmn/client
serves as a far better example of a
general purpose parser (though note, @pkmn/client
just deals with the output log
field of a
stored log - the storage logs processed by the @pkmn/stats
Parser
contain metadata in addition
to the output logs).
A log which has be parsed into a Battle
by the Parser
can be fed into the Stats
class to
compute Statistics
. However, there are numerous options for updating a Statistics
object -
statistics for various weight cutoffs and/or tags can be computed simultaneously, and the various
update
methods can be used to optimize the computation as desired.
Statistics objects can be combine
d together (and like with update
, this can also be used to
combine statistics for multiple weight cutoffs or tags simultanenously). Note that due to the fact
that floating-point arthimetic is not
commutative, the order in which Statistics
are combined may influence the results.
The Display
class can be used to produce @pkmn/stats
's unified output format. Two
methods are provided - fromStatistics
for converting the Statistics
returned by the Stats
class into the unified report, and a fromReports
method which can be used to convert legacy
reports to a unified report which is similar (but not identical) to
@pkmn/stats
's new format. A CLI exists for converting legacy reports to the new format,
see below.
@pkmn/stats
can still generate all of the legacy reports from Smogon-Usage-Stats, the Reports
class provides methods for each of the 5 main report types (usage, leads, moveset, detailed moveset,
metagame), as well as a methods for compute 'update' reports based on previous data. There is also a
movesetReports
method which computes the movesetReport
and detailedMovesetReport
both at the
same time (mostly useful for performance reasons).
The Classifier
can be used to compute a Pokémon (or an entire teams') bias and stalliness.
Bias is a metric computed from a Pokémon's base stats which compares offensive versus defensive
prowess whereas stalliness is meant to measure how much a Pokémon contributes to a 'stalling'
playstyle.
The classifyTeam
method also returns tags - various labels for the particular categories the
team falls into based on attributes of its members.
NOTE: The Classifier
expects PokemonSet<ID>
arguments, not PokemonSet
-
Parser#canonicalizeTeam
can be used to convert a PokemonSet
into a PokemonSet<ID>
if
necessary.
A convert
tool is packaged with @pkmn/stats
that takes in a reports directory as
input and a location to write the transformed reports and converts the legacy reports to the new
output format.
$ convert path/to/reports path/to/output
There is no CLI tool for actually generating reports - @pkmn/logs
should be used to
process logs en masse.
The recommended way of using @pkmn/stats
in a web browser is to configure your bundler
(Webpack, Rollup,
Parcel, etc) to minimize it and package it with the rest of your
application.
The 'update' report test depends on the current tiering information of every Pokémon to determine
what the correct updates are. Because tiers changes over time, when the @pkmn/dex
dependency gets
updated the 'golden' expected output will need to be updated as well. To update the golden files,
run the update script and check in its output after inspection:
$ ./src/test/update
This package is distributed under the terms of the MIT License. The Smogon-Usage-Stats project that this package was based on is also licensed under the MIT License.