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.
How It Works
Section titled “How It Works”- A format is configured with
randomTeams = true. - When two players match, Frontier picks a generation from the format’s
randomGenslist. - Both players receive freshly generated teams from that generation’s data set.
- Team validation is skipped (the generator handles balance internally).
- 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.
Format Configuration
Section titled “Format Configuration”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 = []}| Field | Type | Default | Description |
|---|---|---|---|
randomTeams | Boolean | false | When true, teams are generated instead of pulled from player parties. |
randomGens | List<Int> | [9] | Which generations to draw data from. One gen is picked at random per match; both players get teams from the same gen. |
teamPreview | Boolean | true | When false, skip the team preview GUI and go straight to battle. Works for any format, not just random. |
Generation Data Sets
Section titled “Generation Data Sets”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.
Species Filtering
Section titled “Species Filtering”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.
Team Generation
Section titled “Team Generation”The algorithm is ported from Showdown’s teams.ts. Here’s the high-level flow.
Pool Construction
Section titled “Pool Construction”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.
Iterative Selection (6 Pokemon)
Section titled “Iterative Selection (6 Pokemon)”For each team slot, a species is sampled and validated against constraints:
| Constraint | Rule |
|---|---|
| Species Clause | No duplicate base species. |
| Type Clause | Max 2 Pokemon of any single type. |
| Weakness Clause | Max 3 weak to same type, max 1 double-weak. |
| Freeze-Dry Weakness | Max 4 Pokemon weak to Freeze-Dry. |
| Level Limit | Max 1 Pokemon at level 100. |
| Weather Compatibility | No conflicting weather setters. |
If a valid candidate can’t be found after 12 attempts, the slot is force-filled to prevent infinite loops.
Per-Pokemon Generation
Section titled “Per-Pokemon Generation”For each selected Pokemon, the generator builds out:
Moveset (priority hierarchy):
- Mandatory moves (species-required, Facade on Guts users)
- Type-enforced STAB (role-dependent)
- Priority STAB, Tera STAB, general STAB
- Coverage moves (different types)
- Utility (recovery for bulky roles, pivots, setup for sweepers)
- Filler from remaining movepool
Incompatible combos are culled automatically — Light Screen + Reflect, setup + pivot, redundant coverage.
Item (two tiers):
- Priority items — Booster Energy for Protosynthesis, Assault Vest for AV Pivot, Choice items for Choice roles.
- 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.
Default Random Formats
Section titled “Default Random Formats”Frontier ships two random formats out of the box:
| Format | Battle Type | Gens | Description |
|---|---|---|---|
random_gen9 | Singles | Gen 9 | Standard random singles. |
random_doubles_gen9 | Doubles | Gen 9 | Random doubles variant. |
Each has a corresponding ladder in ladders.conf.
Setting Up a Custom Random Format
Section titled “Setting Up a Custom Random Format”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.
Match Flow
Section titled “Match Flow”The random battle match flow differs from standard matches in two places:
- Queue join — no team validation. Players can queue with any party (or no party at all).
- 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.