Post Index:
#2: Gen 9 Random Battle/Gen 9 Random Doubles Battle - How does Random Battles work exactly? Code explanation post
#2: Gen 9 Random Battle/Gen 9 Random Doubles Battle - Roles and what they do
#3: Other Random Battles formats - System differences
#4: Set Development Policy, Principles, Process, and Guidelines
Random Battles Changelog
How does Level Balancing work? How are levels decided in Random Battles?
Gen 9 Random Battles Set Suggestions
If you have any questions on any of the information in this thread, feel free to ask in the Simple Questions, Simple Answers thread, or ask me personally!
This thread is intended to help understand the systems and mechanisms that make the Random Battles teams you use on PS!.
Overview: The Flow Of Set Generation
Random Battles set generation follows a very specific series of steps. Each step informs the decisions of the steps afterwards, but the later steps have no say in the earlier steps' decisions. These steps cannot go out of order or in reverse at all whatsoever. Any suggestion that would require these steps to go in any direction other than forwards is not possible. Each step listed below will be expanded upon in a hide-box later in this post. The steps are:
Generate First Pokemon Species -> Choose Role -> Choose Tera Type -> Choose Moves -> Choose Ability -> Choose Item -> Adjust EVs/IVs if needed -> Generate Pokemon 2's Species -> etc.
If you got through all that, good for you, you're now an expert in Random Battles set generation! Put that on your resume, you've earned it. If you have any questions, feel free to ask me personally! Just be sure you've read everything carefully.
#2: Gen 9 Random Battle/Gen 9 Random Doubles Battle - How does Random Battles work exactly? Code explanation post
#2: Gen 9 Random Battle/Gen 9 Random Doubles Battle - Roles and what they do
#3: Other Random Battles formats - System differences
#4: Set Development Policy, Principles, Process, and Guidelines
Random Battles Changelog
How does Level Balancing work? How are levels decided in Random Battles?
Gen 9 Random Battles Set Suggestions
If you have any questions on any of the information in this thread, feel free to ask in the Simple Questions, Simple Answers thread, or ask me personally!
This thread is intended to help understand the systems and mechanisms that make the Random Battles teams you use on PS!.
How does Random Battles work, exactly?
Good question. One that will take a lot of text to answer. This post will contain technical information that may be difficult to understand; however, I will do my best to explain it in terms anyone can get. If you can get through this post and fully understand it, you will be able to truly understand what changes are and are not possible in Gen 9 Random Battle and the consequences of the changes that can be made. Singles and Doubles use the same generator. You can tell in the code what's for Doubles or not when you see "isDoubles"! Keep in mind, though, you DO NOT need to know this, or any of the other posts' info, to enjoy Random Battles, it's just supplemental information if you're curious.teams.ts - location of the process itself
random-sets.json - location of movepools, ability pools, roles, levels, and Tera types
random-sets.json - location of movepools, ability pools, roles, levels, and Tera types
! means "Not", take the inverse of what the thing following it is saying.
".includes" means "does this pokemon have the ability to obtain this?"
".has" means "does this pokemon so far already have this thing in this specific random battle set?"
"===" means "is"
"counter.get" means we're keeping track of whether this Pokemon has this thing or not, and in what quantity.
"&&" means "and"
"||" means "or"
"isDoubles" means the code is specific to Gen 9 Random Doubles generation. "!isDoubles" means it's specific to singles. Otherwise, it's shared between both.
".includes" means "does this pokemon have the ability to obtain this?"
".has" means "does this pokemon so far already have this thing in this specific random battle set?"
"===" means "is"
"counter.get" means we're keeping track of whether this Pokemon has this thing or not, and in what quantity.
"&&" means "and"
"||" means "or"
"isDoubles" means the code is specific to Gen 9 Random Doubles generation. "!isDoubles" means it's specific to singles. Otherwise, it's shared between both.
Overview: The Flow Of Set Generation
Random Battles set generation follows a very specific series of steps. Each step informs the decisions of the steps afterwards, but the later steps have no say in the earlier steps' decisions. These steps cannot go out of order or in reverse at all whatsoever. Any suggestion that would require these steps to go in any direction other than forwards is not possible. Each step listed below will be expanded upon in a hide-box later in this post. The steps are:
Generate First Pokemon Species -> Choose Role -> Choose Tera Type -> Choose Moves -> Choose Ability -> Choose Item -> Adjust EVs/IVs if needed -> Generate Pokemon 2's Species -> etc.
This step chooses a number of random team members (from existing tiers and Unreleased) equal to the current maxTeamSize (default: 6). Pokemon with a number of formes, such as Rotom or Zamazenta, have the chance for that Pokemon to generate split between the formes. So, for example, you are half as likely to see a Zamazenta-Crowned as you are to see a Toedscruel. Levels are applied to the Pokemon as they are generated, using level data from sets.json.
While this step occurs, it is possible for the slot being chosen to be rejected and other random Pokemon to be rolled instead if the original Pokemon does not meet certain conditions. Team generation currently uses this feature to prevent teams from having more than 3 Pokemon weak to any given typing, more than 2 Pokemon of any given type, or more than 1 Pokemon that shares a 4x weakness.
Additionally, Zoroark formes cannot generate in Slot 6, and Intrepid Sword and Dauntless Shield users cannot generate in Slot 1.
While this step occurs, it is possible for the slot being chosen to be rejected and other random Pokemon to be rolled instead if the original Pokemon does not meet certain conditions. Team generation currently uses this feature to prevent teams from having more than 3 Pokemon weak to any given typing, more than 2 Pokemon of any given type, or more than 1 Pokemon that shares a 4x weakness.
Additionally, Zoroark formes cannot generate in Slot 6, and Intrepid Sword and Dauntless Shield users cannot generate in Slot 1.
The Role-choosing step is relatively simple; each Pokemon has one to three "Roles" to choose from in sets.json (please see Post #2 for details on what each role means!). Roles are largely decided completely randomly, although if there is already a Pokemon with the role of Tera Blast user (or Ogerpon or Terapagos) on the team, any future Tera Blast user roles (as well as Ogerpon or Terapagos, entirely) will be excluded from the running. This step informs many future steps, but most importantly chooses which movepool to pick moves from in sets.json. Please brush up on all of the roles in Post #1 for details!
The Tera Type step is even more simple. sets.json contains a list of potential Tera types for each Pokemon, separated by role. A random Tera Type is then chosen from the Tera Type pool for the selected set.
The Tera Type step is even more simple. sets.json contains a list of potential Tera types for each Pokemon, separated by role. A random Tera Type is then chosen from the Tera Type pool for the selected set.
This is a big one.
First, please understand the difference between the "movepool" and the "moveset". The movepool is the set of move options for a given set, as visible in sets.json as "movePool". The "moveset" is the set of four moves that you see in battle.
Moves are, one by one, moved from the movepool to the moveset. Initially, this is done less randomly: there are many conditions for move enforcement. Once all move enforcement conditions are fulfilled, then moves are selected randomly from the remaining movepool until the user reaches a set of four moves. Additionally, after each move added to the moveset, the remaining movepool is checked for move incompatibilities. Anything incompatible with the selected move is removed from the movepool and can no longer be generated on the set.
Move Enforcement: (Visible on lines ~200-250 and ~700-1000 of teams.ts)
A list of move enforcement conditions exists; if any of these conditions for "enforcement" are met, an applicable move is added to the moveset. Pokemon are at minimum forced to have at least one STAB move not found on the "NO_STAB" list around line 103 of teams.ts. Most typings also have specific rules for enforcement, visible on lines 200-250. Certain roles force certain sets of moves; "bulky" roles typically force recovery moves when available, "setup" roles force a setup move, "bulky attacker" forces STAB priority when possible, roles not called "support" force the set to contain at least two attacks minimum, and most roles also force an attack matching the Pokemon's Tera Type. Additionally, Facade is forced if the user's potential abilities include Guts, and a small list of Pokemon have forced priority moves instead of forced non-priority STAB moves. Certain moves (WishTect, LeechTect, Screens) are paired together; the other must be forced if one is generated. Once no more "enforcement" conditions are applicable, moves are selected randomly.
Move Incompatibilities: (Visible on lines ~490-640 of random-teams.ts)
After each move is added to the moveset, a short list of move incompatibilities is run through and anything deemed incompatible will be removed from the broader movepool. Most of the incompatibilities in teams.ts are easily readable by people who do not know Typescript. For example, one cannot have both setup and hazards in the same moveset, so if a setup move is rolled, all hazards will be removed from the movepool, and vice versa. In addition, there are some team-based move rejections: there cannot be more than one Stealth Rock user, more than one Sticky Web user, or more than one hazard remover under most circumstances. If rejecting a move from the movepool would cause there to not be enough moves remaining to create a set of four, this step is waived. This means that Pokemon with only four moves in their movepool can still get Stealth Rock if another team member already has Stealth Rock, for example.
First, please understand the difference between the "movepool" and the "moveset". The movepool is the set of move options for a given set, as visible in sets.json as "movePool". The "moveset" is the set of four moves that you see in battle.
Moves are, one by one, moved from the movepool to the moveset. Initially, this is done less randomly: there are many conditions for move enforcement. Once all move enforcement conditions are fulfilled, then moves are selected randomly from the remaining movepool until the user reaches a set of four moves. Additionally, after each move added to the moveset, the remaining movepool is checked for move incompatibilities. Anything incompatible with the selected move is removed from the movepool and can no longer be generated on the set.
Move Enforcement: (Visible on lines ~200-250 and ~700-1000 of teams.ts)
A list of move enforcement conditions exists; if any of these conditions for "enforcement" are met, an applicable move is added to the moveset. Pokemon are at minimum forced to have at least one STAB move not found on the "NO_STAB" list around line 103 of teams.ts. Most typings also have specific rules for enforcement, visible on lines 200-250. Certain roles force certain sets of moves; "bulky" roles typically force recovery moves when available, "setup" roles force a setup move, "bulky attacker" forces STAB priority when possible, roles not called "support" force the set to contain at least two attacks minimum, and most roles also force an attack matching the Pokemon's Tera Type. Additionally, Facade is forced if the user's potential abilities include Guts, and a small list of Pokemon have forced priority moves instead of forced non-priority STAB moves. Certain moves (WishTect, LeechTect, Screens) are paired together; the other must be forced if one is generated. Once no more "enforcement" conditions are applicable, moves are selected randomly.
Move Incompatibilities: (Visible on lines ~490-640 of random-teams.ts)
After each move is added to the moveset, a short list of move incompatibilities is run through and anything deemed incompatible will be removed from the broader movepool. Most of the incompatibilities in teams.ts are easily readable by people who do not know Typescript. For example, one cannot have both setup and hazards in the same moveset, so if a setup move is rolled, all hazards will be removed from the movepool, and vice versa. In addition, there are some team-based move rejections: there cannot be more than one Stealth Rock user, more than one Sticky Web user, or more than one hazard remover under most circumstances. If rejecting a move from the movepool would cause there to not be enough moves remaining to create a set of four, this step is waived. This means that Pokemon with only four moves in their movepool can still get Stealth Rock if another team member already has Stealth Rock, for example.
In Gen 8, the Moves section is significantly messier; moves are brought from the movepool to the moveset, and then moves are rejected based on rejection conditions and rerolled until all rejection conditions are satisfied. Enforcement was just fancy rejection, rejecting random moves until the Pokemon gets what it's forced to. This could often result in heavy weighting towards specific moves compared to others, and could also regularly result in erroneous, unintended sets. Gen 8 is the only format left that uses this system, and a decent portion of the playerbase prefers it that way, so we aren't planning to change it soon.
NEW! as of 7/12/2024. We've completely revamped how Abilities get generated!
Each role has a list of possible abilities the set can generate (dubbed an "ability pool"). Under most conditions, once moves are set in stone, the ability is rolled randomly between the available options on the role. For example, (Kanto) Electrode rolls randomly between Soundproof, Static, and Aftermath, all with an equal chance of appearing. Not all abilities the Pokemon has are in each role's ability pool! Often, undesired abilities are excluded from any given set.
Abilities cannot be weighted within a role such that one is more common than the other at all times. If multiple abilities are able to generate on a given role, it will roll evenly between all of the options.
However, some abilities are conditional, which means they only appear under certain conditions. These conditions fit into two categories:
Ability Rejections:
Abilities with uses conditional on the moves rolled or the rest of the team, such as Swift Swim, Chlorophyll, Overgrow, Defiant, and Iron Fist, get rejected and removed from the ability pool if the criteria for them to appear aren't met. If the criteria are met, though, these abilities will still roll randomly with other abilities the role can have. For example, when Infernape gets Mach Punch on its moveset, it still has a 50/50 roll between Blaze and Iron Fist. The list of the rejection criteria can be found around line ~1050 of teams.ts. This might not be perfect, though, which is why we need the second category too!
Ability Enforcement:
Some abilities simply MUST appear over all the others if the conditions for their appearance are there. For example, Toucannon doesn't always get Bullet Seed, but when it does, we code Skill Link to be enforced on it. The list of enforcement conditions (typically made of hard-coded cases for specific species) can be found on around line ~1110 of teams.ts.
Each role has a list of possible abilities the set can generate (dubbed an "ability pool"). Under most conditions, once moves are set in stone, the ability is rolled randomly between the available options on the role. For example, (Kanto) Electrode rolls randomly between Soundproof, Static, and Aftermath, all with an equal chance of appearing. Not all abilities the Pokemon has are in each role's ability pool! Often, undesired abilities are excluded from any given set.
Abilities cannot be weighted within a role such that one is more common than the other at all times. If multiple abilities are able to generate on a given role, it will roll evenly between all of the options.
However, some abilities are conditional, which means they only appear under certain conditions. These conditions fit into two categories:
Ability Rejections:
Abilities with uses conditional on the moves rolled or the rest of the team, such as Swift Swim, Chlorophyll, Overgrow, Defiant, and Iron Fist, get rejected and removed from the ability pool if the criteria for them to appear aren't met. If the criteria are met, though, these abilities will still roll randomly with other abilities the role can have. For example, when Infernape gets Mach Punch on its moveset, it still has a 50/50 roll between Blaze and Iron Fist. The list of the rejection criteria can be found around line ~1050 of teams.ts. This might not be perfect, though, which is why we need the second category too!
Ability Enforcement:
Some abilities simply MUST appear over all the others if the conditions for their appearance are there. For example, Toucannon doesn't always get Bullet Seed, but when it does, we code Skill Link to be enforced on it. The list of enforcement conditions (typically made of hard-coded cases for specific species) can be found on around line ~1110 of teams.ts.
Item selection is a relatively simple, but long process. A descending list of "if" conditions begins on line ~1160 of teams.ts and ends around line 1420. The first condition in this list to be met gives the Pokemon its item. The higher-priority conditions, listed first, are often Pokemon-specific; Pikachu gets Light Ball, Ditto gets Choice scarf, and so on. As the list goes on, the conditions become more generalized. For example, a condition exists where "If you have no status moves and are neither a Fast Attacker nor a Wallbreaker, you get an Assault Vest". This condition would give everything with no status moves an AV in a vacuum; however, it is prioritized below Choice items and several other relevant item possibilities, so in practice it primarily appears on mixed attackers. If no conditions are met at all, we give the Pokemon Leftovers and call it a day. There is not enough space on this post to give every item condition a thorough explanation; i recommend reading it yourself and using some common sense!
EVs will always be 85 and IVs will always be 31 with a neutral nature in the vast majority of situations. However, a few conditions can change that. If the Pokemon has no physical attacks, its Attack EVs and IVs are set to 0, but everything else remains the same. If the Pokemon has Trick Room or Gyro Ball, its Speed EVs and IVs are set to 0, but everything else remains the same. In past gens, EVs for certain stats were lowered slightly to give Nihilego and Celesteela better use of Beast Boost. Such a feature is possible in Gen 9 as well, but it is not currently in use.
If you got through all that, good for you, you're now an expert in Random Battles set generation! Put that on your resume, you've earned it. If you have any questions, feel free to ask me personally! Just be sure you've read everything carefully.
Last edited: