Skip to main content
Pokemon Showdown supports hundreds of battle formats, each with unique rulesets and restrictions. Formats are identified by a format ID used throughout the simulator API.

Format IDs

Format IDs are lowercase, alphanumeric strings with no spaces:
gen9ou
gen9randombattle
gen9vgc2026
gen7customgame

Naming Convention

Format IDs typically follow this pattern:
gen[GENERATION][FORMAT][VARIANT]
GENERATION
number
Generation number (1-9) or omitted for current gen
FORMAT
string
Format name: ou, ubers, randombattle, vgc, doubles, etc.
VARIANT
string
Optional variant or regulation: regi, bo3, etc.

Format Categories

Formats are organized into sections:

Singles Formats

Competitive 6v6 singles battles:

Random Battle

Format ID: gen9randombattleRandomized teams with competitively viable sets. Great for quick battles without team building.

OU (OverUsed)

Format ID: gen9ouThe most popular competitive format with standard rules and a curated banlist.

Ubers

Format ID: gen9ubersAllows legendary and mythical Pokemon banned from OU.

UU / RU / NU / PU

Format IDs: gen9uu, gen9ru, gen9nu, gen9puUsage-based tiers with Pokemon banned from higher tiers.

Doubles Formats

Competitive doubles battles:

Random Doubles

Format ID: gen9randomdoublesbattleRandomized doubles teams.

Doubles OU

Format ID: gen9doublesouCompetitive doubles with standard rules.

VGC (Video Game Championships)

Format IDs: gen9vgc2026regi, gen9vgc2026regfOfficial Pokemon VGC rules with regulation variations.

Doubles Ubers

Format ID: gen9doublesubersUnrestricted doubles format.

Other Metagames (OMs)

Creative formats with modified rules:

Almost Any Ability

Format ID: gen9almostanyabilityPokemon can use almost any ability.

Balanced Hackmons

Format ID: gen9balancedhackmonsAnything hackable is allowed with balance restrictions.

STABmons

Format ID: gen9stabmonsPokemon can use any move matching their type.

Mix and Mega

Format ID: gen9mixandmegaAny Pokemon can mega evolve with any mega stone.

Custom Formats

Custom Game

Format IDs: gen9customgame, gen9doublescustomgameNo restrictions - for testing and experimentation.
stream.write(`>start {"formatid":"gen9customgame"}`);

Format Configuration

Formats are defined in /config/formats.ts with configuration objects:
{
    name: "[Gen 9] Random Battle",
    desc: "Randomized teams of Pokémon with competitively viable sets.",
    mod: 'gen9',
    team: 'random',
    bestOfDefault: true,
    ruleset: ['PotD', 'Obtainable', 'Species Clause', 'HP Percentage Mod', 
              'Cancel Mod', 'Sleep Clause Mod', 'Illusion Level Mod'],
}

Key Properties

name
string
required
Display name of the format (e.g., "[Gen 9] OU")
mod
string
required
Generation/mod to use (e.g., 'gen9', 'gen8')
gameType
string
Battle type: 'singles' (default), 'doubles', 'triples', 'multi', or 'freeforall'
team
string
Team generation mode:
  • 'random' - Randomly generated teams
  • 'randomBSSFactory' - BSS Factory sets
  • Not specified - Teams must be provided
ruleset
string[]
Array of rules to apply (e.g., ['Standard', 'Sleep Clause Mod'])
banlist
string[]
Banned Pokemon, moves, items, and abilities
restricted
string[]
Restricted items with usage limits (e.g., limit one restricted legendary)

Using Formats

Starting a Battle

Specify the format ID when starting a battle:
const stream = new BattleStream();
stream.write(`>start {"formatid":"gen9ou"}`);

Format-Specific Behavior

Teams are generated automatically if not provided:
stream.write(`>start {"formatid":"gen9randombattle"}`);
stream.write(`>player p1 {"name":"Alice"}`); // No team needed
stream.write(`>player p2 {"name":"Bob"}`);
Or provide your own team:
const team = Teams.pack(Teams.generate('gen9randombattle'));
stream.write(`>player p1 {"name":"Alice","team":${JSON.stringify(team)}}`);

Format Examples from Source

Here are real format definitions from the Pokemon Showdown source:

Gen 9 Random Battle

{
    name: "[Gen 9] Random Battle",
    desc: `Randomized teams of Pokémon with competitively viable sets.`,
    mod: 'gen9',
    team: 'random',
    bestOfDefault: true,
    ruleset: ['PotD', 'Obtainable', 'Species Clause', 'HP Percentage Mod', 
              'Cancel Mod', 'Sleep Clause Mod', 'Illusion Level Mod'],
}

Gen 9 OU

{
    name: "[Gen 9] OU",
    mod: 'gen9',
    ruleset: ['Standard', 'Evasion Abilities Clause', 'Sleep Moves Clause', 
              '!Sleep Clause Mod'],
    banlist: ['Uber', 'AG', 'Arena Trap', 'Moody', 'Shadow Tag', 
              'King\'s Rock', 'Razor Fang', 'Baton Pass', 'Last Respects', 
              'Shed Tail'],
}

Gen 9 VGC 2026 Reg I

{
    name: "[Gen 9] VGC 2026 Reg I",
    mod: 'gen9',
    gameType: 'doubles',
    bestOfDefault: true,
    ruleset: ['Flat Rules', '!! Adjust Level = 50', 'Min Source Gen = 9', 
              'VGC Timer', 'Limit Two Restricted'],
    restricted: ['Restricted Legendary'],
}

Gen 9 Custom Game

{
    name: "[Gen 9] Custom Game",
    mod: 'gen9',
    searchShow: false,
    debug: true,
    battle: { trunc: Math.trunc },
    ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 
              'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}

Rulesets

Rulesets define the rules and clauses applied to a format:

Common Rulesets

'Standard'
Basic competitive rules including:
  • Team Preview
  • Species Clause (no duplicate Pokemon)
  • OHKO Clause (no one-hit KO moves)
  • Evasion Moves Clause
  • Sleep Clause Mod
  • HP Percentage Mod
  • Cancel Mod

Clauses

Individual rules that can be applied:
  • 'Species Clause' - No duplicate Pokemon
  • 'Sleep Clause Mod' - Limit sleeping opponents
  • 'OHKO Clause' - Ban OHKO moves
  • 'Evasion Moves Clause' - Ban evasion-boosting moves
  • 'Evasion Abilities Clause' - Ban evasion abilities
  • 'HP Percentage Mod' - Display HP as percentages
  • 'Cancel Mod' - Allow move cancellation

Accessing Format Data

You can access format data programmatically:
const Dex = require('pokemon-showdown').Dex;

// Get format by ID
const format = Dex.formats.get('gen9ou');

console.log(format.name);        // "[Gen 9] OU"
console.log(format.gameType);    // "singles"
console.log(format.ruleset);     // Array of rules
console.log(format.banlist);     // Array of bans

// Check if format exists
if (format.exists) {
    console.log('Format is valid');
}

Legacy Formats

Older generation formats are also supported:
// Gen 8
stream.write(`>start {"formatid":"gen8ou"}`);

// Gen 7
stream.write(`>start {"formatid":"gen7randombattle"}`);

// Gen 6
stream.write(`>start {"formatid":"gen6ou"}`);

// Gen 4
stream.write(`>start {"formatid":"gen4vgc2009"}`);
Each generation has its own mechanics, move pools, and available Pokemon.

Custom Formats

You can create custom formats by modifying config/formats.ts or config/custom-formats.ts:
export const Formats: FormatList = [
    {
        section: "Custom Formats",
    },
    {
        name: "[Gen 9] My Custom Format",
        mod: 'gen9',
        ruleset: ['Standard'],
        banlist: ['Uber', 'Shadow Tag'],
    },
];
Custom formats require modifying the Pokemon Showdown server code and are not available in the npm package.

Format Validation

When using a format, the simulator will:
  1. Check if the format exists
  2. Load the appropriate game generation (mod)
  3. Apply all rulesets
  4. Enforce banlists and restrictions
Teams must be validated separately using TeamValidator.

Complete Example

Here’s a complete example using multiple formats:
const { BattleStream, Teams, TeamValidator } = require('pokemon-showdown');

// Function to run a battle in a specific format
async function runBattle(formatid, team1, team2) {
    const stream = new BattleStream();
    
    // Validate teams
    const validator = new TeamValidator(formatid);
    const problems1 = validator.validateTeam(team1);
    const problems2 = validator.validateTeam(team2);
    
    if (problems1 || problems2) {
        console.error(`Teams invalid for ${formatid}`);
        return;
    }
    
    // Start battle
    stream.write(`>start {"formatid":"${formatid}"}`);
    stream.write(`>player p1 {"name":"Player 1","team":${JSON.stringify(Teams.pack(team1))}}`);
    stream.write(`>player p2 {"name":"Player 2","team":${JSON.stringify(Teams.pack(team2))}}`);
    
    // Read output
    for await (const output of stream) {
        console.log(output);
    }
}

// Generate teams and battle in different formats
const team1 = Teams.generate('gen9randombattle');
const team2 = Teams.generate('gen9randombattle');

await runBattle('gen9ou', team1, team2);
await runBattle('gen9doublesou', team1, team2);

Next Steps

Overview

Return to simulator overview

Team Formats

Learn about team formats

Build docs developers (and LLMs) love