Skip to content

Random Battles

Random battles generate teams automatically from competitive data sets. No teambuilding required — players queue up, get a randomly generated team of six, and battle. The system is ported from Pokemon Showdown’s random team generator and filtered against Cobblemon’s implemented species at runtime.

  1. A format is configured with randomTeams = true.
  2. When two players match, Frontier picks a generation from the format’s randomGens list.
  3. Both players receive freshly generated teams from that generation’s data set.
  4. Team validation is skipped (the generator handles balance internally).
  5. The battle starts — with or without team preview, depending on the format config.

Generated teams are temporary in-memory objects. They’re never written to player storage and are garbage collected after the match ends.

Two fields on the format definition control random battles:

random_gen9 {
displayName = "Random Battle"
randomTeams = true
teamPreview = true
randomGens = [9]
teamSize = 6
clauses = []
bannedSpecies = []
bannedMoves = []
bannedAbilities = []
bannedItems = []
}
FieldTypeDefaultDescription
randomTeamsBooleanfalseWhen true, teams are generated instead of pulled from player parties.
randomGensList<Int>[9]Which generations to draw data from. One gen is picked at random per match; both players get teams from the same gen.
teamPreviewBooleantrueWhen false, skip the team preview GUI and go straight to battle. Works for any format, not just random.

Frontier ships JSON data files for generations 1 through 9, bundled in the mod jar and copied to config/frontier/random-battles/gen\{N\}/sets.json on first run. Each file contains Pokemon entries with:

  • Level — scaled inversely with competitive tier (stronger Pokemon get lower levels).
  • Role-based sets — strategic archetypes like Fast Attacker, Wallbreaker, Setup Sweeper, Bulky Support, each with its own movepool, abilities, and (for Gen 9) Tera types.

Data files reload on /ranked reload, so you can tweak them without a server restart.

After loading sets data (and after every datapack reload), Frontier filters against Cobblemon’s registries:

  • Species not implemented in Cobblemon are removed.
  • Moves, abilities, and items not in the game registries are stripped.
  • If a Pokemon has zero valid sets after filtering, it’s removed entirely.
  • Warnings are logged for every stripped entry so you know what’s missing.

This means random battles automatically adapt to whatever Cobblemon has implemented. As Cobblemon adds new species and moves, more Pokemon become available in the random pool.

The algorithm is ported from Showdown’s teams.ts. Here’s the high-level flow.

Load the selected gen’s sets data and filter against Cobblemon’s registries. Species are weighted by forme count — Pokemon with more formes get slightly higher selection weight.

For each team slot, a species is sampled and validated against constraints:

ConstraintRule
Species ClauseNo duplicate base species.
Type ClauseMax 2 Pokemon of any single type.
Weakness ClauseMax 3 weak to same type, max 1 double-weak.
Freeze-Dry WeaknessMax 4 Pokemon weak to Freeze-Dry.
Level LimitMax 1 Pokemon at level 100.
Weather CompatibilityNo conflicting weather setters.

If a valid candidate can’t be found after 12 attempts, the slot is force-filled to prevent infinite loops.

For each selected Pokemon, the generator builds out:

Moveset (priority hierarchy):

  1. Mandatory moves (species-required, Facade on Guts users)
  2. Type-enforced STAB (role-dependent)
  3. Priority STAB, Tera STAB, general STAB
  4. Coverage moves (different types)
  5. Utility (recovery for bulky roles, pivots, setup for sweepers)
  6. Filler from remaining movepool

Incompatible combos are culled automatically — Light Screen + Reflect, setup + pivot, redundant coverage.

Item (two tiers):

  1. Priority items — Booster Energy for Protosynthesis, Assault Vest for AV Pivot, Choice items for Choice roles.
  2. Fallback items — Leftovers for bulky sets, Life Orb for offensive, role-based defaults.

Ability: Incompatible abilities are culled first (weather-dependent without team weather, move-synergy mismatches), then selected from remaining options with species-specific preferences.

EVs/IVs: Baseline is 85/85/85/85/85/85 EVs (510 total), 31 all IVs. Adjustments include zero attack EVs/IVs for special-only sets, reduced speed for Trick Room users, and HP optimization for Stealth Rock/Substitute breakpoints.

Frontier ships two random formats out of the box:

FormatBattle TypeGensDescription
random_gen9SinglesGen 9Standard random singles.
random_doubles_gen9DoublesGen 9Random doubles variant.

Each has a corresponding ladder in ladders.conf.

Want random battles with a specific gen mix? Add a new format in formats.conf:

random_classic {
displayName = "Classic Random"
randomTeams = true
teamPreview = false
randomGens = [1, 3, 9]
teamSize = 6
clauses = []
bannedSpecies = []
bannedMoves = []
bannedAbilities = []
bannedItems = []
}

Then create a ladder for it in ladders.conf:

random_classic {
displayName = "Classic Random"
description = "Random teams from Gens 1, 3, and 9."
format = "random_classic"
battleType = "singles"
teamSize = 6
bringSize = 6
rating { }
rankTiers = [ ]
}

Each match, the system randomly picks one of the listed gens and generates both teams from it.

The random battle match flow differs from standard matches in two places:

  1. Queue join — no team validation. Players can queue with any party (or no party at all).
  2. Match start — instead of cloning each player’s party, Frontier generates fresh teams from the selected gen’s data set and feeds them directly to the battle actors.

Everything else — rating changes, arena teleportation, turn timers, replays — works identically to standard ranked matches.