Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/smogon/pokemon-showdown-client/llms.txt

Use this file to discover all available pages before exploring further.

The Dex object is the primary data-access layer for the Pokémon Showdown client engine. It exposes lazily-loaded lookup tables for moves, items, abilities, and species — each normalised through toID so lookups are case- and punctuation-insensitive. When a battle uses a non-standard format (an older generation or a custom mod), Dex.mod() returns a ModdedDex instance that shadows the global data tables with generation-specific overrides. All type declarations live in battle-dex-data.ts and are re-exported through the Dex namespace so consumers only need a single import.
battle-dex.ts is MIT-licensed and has no Node.js runtime dependencies. It runs identically in the browser, in NW.js, and in standalone replay-viewer contexts.

toID(text)

Converts any value into a lowercase alphanumeric ID by stripping all non-[a-z0-9] characters. If the value has an .id or .userid property it is unwrapped first. Non-string, non-number inputs return the empty string cast to ID.
export function toID(text: any): ID
import { toID } from './battle-dex';

toID('Pikachu');            // 'pikachu'
toID('Iron Hands');         // 'ironhands'
toID('Fleur Cannon');       // 'fleurcannon'
toID('Hidden Power [Ice]'); // 'hiddenpowerice'
toID(null);                 // ''
toID({ id: 'charizard' });  // 'charizard'
Every lookup method on Dex calls toID internally, so you never need to normalise strings before passing them in.

Dex Namespace — Type Exports

The declare namespace Dex block in battle-dex.ts re-exports all data types from battle-dex-data.ts under the Dex. prefix. Import them as types only.
import type { Dex } from './battle-dex';
// or import the runtime object and use its type namespace:
import { Dex, type ID } from './battle-dex';

Primitive Types

Dex.ID
string & { __isID: true }
Branded lowercase alphanumeric string. Produced exclusively by toID(). The brand prevents accidentally using un-normalised strings where an ID is expected.
export type ID = string & { __isID: true };
Dex.StatName
string union
type StatName = 'hp' | 'atk' | 'def' | 'spa' | 'spd' | 'spe';
Dex.StatNameExceptHP
string union
type StatNameExceptHP = 'atk' | 'def' | 'spa' | 'spd' | 'spe';
Dex.BoostStatName
string union
Stats that can be boosted or lowered in battle, including the accuracy/evasion axes.
type BoostStatName = 'atk' | 'def' | 'spa' | 'spd' | 'spe' | 'evasion' | 'accuracy' | 'spc';
Dex.TypeName
string union
All 19 Pokémon types plus the catch-all '???'.
type TypeName =
  'Normal' | 'Fighting' | 'Flying' | 'Poison' | 'Ground' | 'Rock' |
  'Bug' | 'Ghost' | 'Steel' | 'Fire' | 'Water' | 'Grass' | 'Electric' |
  'Psychic' | 'Ice' | 'Dragon' | 'Dark' | 'Fairy' | 'Stellar' | '???';
Dex.StatusName
string union
Non-volatile status condition IDs.
type StatusName = 'par' | 'psn' | 'frz' | 'slp' | 'brn';
Dex.GenderName
'M' | 'F' | 'N'
Pokémon gender: Male, Female, or None (genderless).
Dex.NatureName
string union
All 25 nature names: 'Adamant' | 'Bashful' | 'Bold' | 'Brave' | 'Calm' | 'Careful' | 'Docile' | 'Gentle' | 'Hardy' | 'Hasty' | 'Impish' | 'Jolly' | 'Lax' | 'Lonely' | 'Mild' | 'Modest' | 'Naive' | 'Naughty' | 'Quiet' | 'Quirky' | 'Rash' | 'Relaxed' | 'Sassy' | 'Serious' | 'Timid'.
Dex.CategoryName
'Physical' | 'Special' | 'Status'
Move damage category.

Composite Types

Dex.StatsTable
object
A record of all six base stats, all required.
type StatsTable = {
  hp: number;
  atk: number;
  def: number;
  spa: number;
  spd: number;
  spe: number;
};
Dex.WeaknessType
0 | 1 | 2 | 3
Type-effectiveness category used in the type chart. Numeric constants are also available as Dex.REGULAR, Dex.WEAK, Dex.RESIST, and Dex.IMMUNE on the singleton.
ValueConstantMeaning
0REGULAR1× neutral
1WEAK2× or 4× super-effective
2RESIST0.5× or 0.25× not-very-effective
3IMMUNE0× immune
Dex.PokemonSet
Teams.PokemonSet
Alias for Teams.PokemonSet; see the Teams API for the full field listing.

Effect Object Types

Dex.Effect
interface
Base interface shared by all effect classes.
interface Effect {
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly effectType: 'Item' | 'Move' | 'Ability' | 'Species' | 'PureEffect';
  readonly exists: boolean;
}
Dex.PureEffect
class
A generic effect that is none of the four specialised types (e.g. weather, terrain, the move Splash when referenced via |-activate|). exists is always false — pure effects are constructed on the fly.
class PureEffect implements Effect {
  readonly effectType = 'PureEffect';
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly exists: boolean;
}
Dex.Ability
class
class Ability implements Effect {
  readonly effectType = 'Ability';
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly exists: boolean;
  readonly num: number;
  readonly desc: string;
  readonly shortDesc: string;
  readonly flags: Readonly<AbilityFlags>;
  readonly isNonstandard: string | null;
}
Dex.Item
class
class Item implements Effect {
  readonly effectType = 'Item';
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly exists: boolean;
  readonly num: number;
  readonly spritenum: number;
  readonly desc: string;
  readonly shortDesc: string;
  readonly megaStone: { [megaEvolves: string]: string };
}
Dex.Move
class
class Move implements Effect {
  readonly effectType = 'Move';
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly exists: boolean;
  readonly basePower: number;
  readonly accuracy: number | true;
  readonly pp: number;
  readonly type: TypeName;
  readonly category: CategoryName;
  readonly priority: number;
  readonly target: MoveTarget;
  readonly flags: Readonly<MoveFlags>;
  readonly critRatio: number;
  readonly isZ: ID;
  readonly isMax: boolean | string;
  readonly noPPBoosts: boolean;
  readonly secondaries: readonly any[] | null;
  readonly num: number;
}
Dex.Species
class
class Species implements Effect {
  readonly effectType = 'Species';
  readonly id: ID;
  readonly name: string;
  readonly gen: number;
  readonly exists: boolean;
  readonly baseSpecies: string;
  readonly forme: string;
  readonly formeid: string;
  readonly spriteid: string;
  readonly num: number;
  readonly types: readonly TypeName[];
  readonly abilities: Readonly<{ 0: string; 1?: string; H?: string; S?: string }>;
  readonly baseStats: Readonly<StatsTable>;
  readonly bst: number;
  readonly weightkg: number;
  readonly heightm: number;
  readonly gender: GenderName;
  readonly isMega: boolean;
  readonly isPrimal: boolean;
  readonly canGigantamax: boolean;
  readonly cannotDynamax: boolean;
  readonly requiredTeraType: TypeName;
  readonly isNonstandard: string | null;
  readonly tier: string;
  readonly nfe: boolean;
}
Dex.Nature
interface
interface Nature {
  plus?: StatNameExceptHP;  // boosted stat (+10%)
  minus?: StatNameExceptHP; // reduced stat (-10%)
}
Neutral natures (Hardy, Docile, Serious, Bashful, Quirky) have no plus/minus keys.
Dex.Type
interface
Extends Effect with type chart data.
interface Type extends Effect {
  damageTaken?: Record<
    Dex.TypeName | 'powder' | 'prankster' | 'trapped',
    Dex.WeaknessType
  >;
  HPivs?: Partial<Dex.StatsTable>;
  HPdvs?: Partial<Dex.StatsTable>;
}

Dex Singleton

The exported Dex object is an instance of an anonymous class implementing ModdedDex. It targets Gen 9 by default (Dex.gen === 9, Dex.modid === 'gen9').
export const Dex = new class implements ModdedDex {
  readonly Ability = Ability;
  readonly Item = Item;
  readonly Move = Move;
  readonly Species = Species;

  readonly gen = 9;
  readonly modid = 'gen9' as ID;

  readonly REGULAR = 0;
  readonly WEAK = 1;
  readonly RESIST = 2;
  readonly IMMUNE = 3;

  readonly statNames: readonly Dex.StatName[];
  readonly statNamesExceptHP: readonly Dex.StatNameExceptHP[];
  // ...
};

Lookup Namespaces

Each of the four lookup namespaces has a .get() method that accepts a name string, a pre-constructed object (passed through unchanged), null, or undefined. Results are cached in the global window.BattleMoves/Items/Abilities/Species table.
Returns a Move object. Resolves aliases from BattleAliases. Handles hiddenpower*, return*, and frustration* as special base-power variants.
Dex.moves.get(nameOrMove: string | Move | null | undefined): Move
const tbolt = Dex.moves.get('Thunderbolt');
console.log(tbolt.basePower);  // 90
console.log(tbolt.type);       // 'Electric'
console.log(tbolt.pp);         // 15
console.log(tbolt.category);   // 'Special'
Returns an Item object. Unknown items have exists === false.
Dex.items.get(nameOrItem: string | Item | null | undefined): Item
const choiceBand = Dex.items.get('Choice Band');
console.log(choiceBand.name);    // 'Choice Band'
console.log(choiceBand.exists);  // true
Returns an Ability object. Resolves aliases. Unknown abilities have exists === false.
Dex.abilities.get(nameOrAbility: string | Ability | null | undefined): Ability
Returns a Species object. Resolves aliases and normalises forme names.
Dex.species.get(nameOrSpecies: string | Species | null | undefined): Species
const gardevoir = Dex.species.get('Gardevoir');
console.log(gardevoir.types);      // ['Psychic', 'Fairy']
console.log(gardevoir.baseStats);  // { hp: 68, atk: 65, def: 65, spa: 125, spd: 115, spe: 80 }
console.log(gardevoir.bst);        // 518
console.log(gardevoir.abilities);  // { '0': 'Synchronize', '1': 'Trace', H: 'Telepathy' }

Generation and Format Methods

Returns a ModdedDex that applies generation-specific data overrides on top of the Gen 9 base tables. Instances are cached in Dex.moddedDexes.
mod(modid: ID): ModdedDex
const gen4 = Dex.mod('gen4' as ID);
const draco = gen4.moves.get('Draco Meteor');
// Returns the Gen 4 version of Draco Meteor with any gen-specific overrides applied
Convenience wrapper: calls Dex.mod('gen' + gen). Returns the main Dex if gen is falsy.
forGen(gen: number): ModdedDex
Returns the appropriate ModdedDex for a format string, handling special cases like Let’s Go (gen7letsgo), BDSP (gen8bdsp), and Champions Cup (champions).
forFormat(format: string): ModdedDex
Resolves any effect reference — move, item, or ability — from a prefixed string like "item:Choice Band" or "move:Moonblast". Falls back to a PureEffect for weather/terrain/other references.
getEffect(name: string | null | undefined): PureEffect | Item | Ability | Move

ModdedDex Class

ModdedDex provides the same .moves, .items, .abilities, and .species namespaces as the main Dex, but overlays generation-specific data from window.BattleTeambuilderTable.
export class ModdedDex {
  readonly gen: number;
  readonly modid: ID;
  readonly cache: {
    Moves: { [k: string]: Move };
    Items: { [k: string]: Item };
    Abilities: { [k: string]: Ability };
    Species: { [k: string]: Species };
    Types: { [k: string]: Dex.Effect };
  };

  constructor(modid: ID)  // modid must start with 'gen' or be 'champions'

  moves: { get(name: string): Move };
  items: { get(name: string): Item };
  abilities: { get(name: string): Ability };
  species: { get(name: string): Species };
}
ModdedDex requires window.BattleTeambuilderTable to be loaded (the teambuilder-tables.js data file). If it is absent, lookups silently fall through to the base Gen 9 data.

battle-dex-data.ts Data Tables

BattleNatures

A record mapping every NatureName to a Nature object. Neutral natures have an empty object {}.
export const BattleNatures: { [k in NatureName]: Nature }
import { BattleNatures } from './battle-dex-data';

BattleNatures.Adamant;  // { plus: 'atk', minus: 'spa' }
BattleNatures.Timid;    // { plus: 'spe', minus: 'atk' }
BattleNatures.Hardy;    // {}  (neutral)

BattleStatNames / BattleStatIDs

BattleStatNames
const object
Short display names for each stat ID.
export const BattleStatNames = {
  hp: 'HP', atk: 'Atk', def: 'Def',
  spa: 'SpA', spd: 'SpD', spe: 'Spe',
} as const;
BattleStatIDs
{ [k: string]: StatName | undefined }
Maps various display spellings to a canonical StatName. Accepts 'HP', 'hp', 'Atk', 'atk', 'Def', 'def', 'SpA', 'SAtk', 'SpAtk', 'spa', 'spc', 'Spc', 'SpD', 'SDef', 'SpDef', 'spd', 'Spe', 'Spd', 'spe'.

BattlePokemonIconIndexes / BattlePokemonIconIndexesLeft

Sprite sheet index overrides for alternate formes that do not follow the default National Dex numbering. Keys are ID strings (e.g. 'rotomfan', 'pikachubelle'), values are pixel-row indices into the sprite sheet.
export const BattlePokemonIconIndexes: { [id: string]: number }
export const BattlePokemonIconIndexesLeft: { [id: string]: number }
BattlePokemonIconIndexesLeft contains the left-facing (opponent’s) sprite indices for formes that have a separate left-facing sprite distinct from the front-facing default.

Code Examples

import { Dex, toID } from './battle-dex';

// Normalise user input
const id = toID('Draco Meteor'); // 'dracometeor'

// Look up a move
const move = Dex.moves.get('Draco Meteor');
console.log(move.name);      // 'Draco Meteor'
console.log(move.basePower); // 130
console.log(move.type);      // 'Dragon'
console.log(move.pp);        // 5
console.log(move.category);  // 'Special'
console.log(move.exists);    // true

// Look up a species
const spec = Dex.species.get('Garchomp');
console.log(spec.types);            // ['Dragon', 'Ground']
console.log(spec.abilities['H']);   // 'Rough Skin'
console.log(spec.baseStats.spa);    // 80
console.log(spec.canGigantamax);    // false

Build docs developers (and LLMs) love