From 66856841f1a04d468fcf3fe1e24bcb1234a83d5f Mon Sep 17 00:00:00 2001 From: andrebastosdias Date: Sun, 3 May 2026 22:12:04 +0100 Subject: [PATCH 1/3] Lock gender in the validator --- sim/pokemon.ts | 3 ++- sim/team-validator.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sim/pokemon.ts b/sim/pokemon.ts index 2803eb6ef7..d0940757fa 100644 --- a/sim/pokemon.ts +++ b/sim/pokemon.ts @@ -337,7 +337,8 @@ export class Pokemon { set.level = this.battle.clampIntRange(set.adjustLevel || set.level || 100, 1, 9999); this.level = set.level; const genders: { [key: string]: GenderName | null } = { __proto__: null, M: 'M', F: 'F', N: 'N' }; - this.gender = genders[set.gender] || this.species.gender || this.battle.sample(['M', 'F']); + this.gender = genders[set.gender] || this.species.gender || + (this.battle.random() <= this.species.genderRatio.M ? 'M' : 'F'); if (this.gender === 'N') this.gender = ''; this.happiness = typeof set.happiness === 'number' ? this.battle.clampIntRange(set.happiness, 0, 255) : 255; if (this.battle.format.mod === 'gen7letsgo') this.happiness = 70; diff --git a/sim/team-validator.ts b/sim/team-validator.ts index db2f77fe10..034ca5b734 100644 --- a/sim/team-validator.ts +++ b/sim/team-validator.ts @@ -1112,8 +1112,12 @@ export class TeamValidator { } if (!problems.length) { - if (this.gen > 5 && !ruleTable.has('obtainablemisc')) { - set.gender ||= 'N'; + if (!set.gender) { + if (this.gen <= 5 || ruleTable.has('obtainablemisc')) { + set.gender = species.gender || Math.random() <= species.genderRatio.M ? 'M' : 'F'; + } else { + set.gender = 'N'; + } } if (adjustLevel) set.level = adjustLevel; return null; From be0118e3ea4286afe77fe5af681ca8ee6c838029 Mon Sep 17 00:00:00 2001 From: andrebastosdias Date: Sun, 3 May 2026 22:14:46 +0100 Subject: [PATCH 2/3] Add parenthesis --- sim/team-validator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/team-validator.ts b/sim/team-validator.ts index 034ca5b734..3771b35e4a 100644 --- a/sim/team-validator.ts +++ b/sim/team-validator.ts @@ -1114,7 +1114,7 @@ export class TeamValidator { if (!problems.length) { if (!set.gender) { if (this.gen <= 5 || ruleTable.has('obtainablemisc')) { - set.gender = species.gender || Math.random() <= species.genderRatio.M ? 'M' : 'F'; + set.gender = species.gender || (Math.random() <= species.genderRatio.M ? 'M' : 'F'); } else { set.gender = 'N'; } From 1a858e17274ab5991e5763c06440658e94791367 Mon Sep 17 00:00:00 2001 From: andrebastosdias Date: Sun, 3 May 2026 22:54:02 +0100 Subject: [PATCH 3/3] Select genders inside team generators --- data/random-battles/gen1/teams.ts | 2 +- data/random-battles/gen3/teams.ts | 2 +- data/random-battles/gen4/teams.ts | 2 +- data/random-battles/gen5/teams.ts | 2 +- data/random-battles/gen9baby/teams.ts | 2 +- data/random-battles/gen9cap/teams.ts | 2 +- data/random-battles/gen9ffa/teams.ts | 2 +- sim/global-types.ts | 2 +- sim/pokemon.ts | 5 +---- test/sim/items/quickclaw.js | 4 ++-- test/sim/moves/assurance.js | 2 +- test/sim/moves/burnup.js | 2 +- test/sim/moves/pursuit.js | 2 +- 13 files changed, 14 insertions(+), 17 deletions(-) diff --git a/data/random-battles/gen1/teams.ts b/data/random-battles/gen1/teams.ts index 51d8db0cab..ddcffe8352 100644 --- a/data/random-battles/gen1/teams.ts +++ b/data/random-battles/gen1/teams.ts @@ -21,7 +21,7 @@ export class RandomGen1Teams extends RandomGen2Teams { override randomCCTeam() { this.enforceNoDirectCustomBanlistChanges(); - const team = []; + const team: RandomTeamsTypes.RandomSet[] = []; const randomN = this.randomNPokemon(this.maxTeamSize, this.forceMonotype); diff --git a/data/random-battles/gen3/teams.ts b/data/random-battles/gen3/teams.ts index c260b28708..7449029039 100644 --- a/data/random-battles/gen3/teams.ts +++ b/data/random-battles/gen3/teams.ts @@ -619,7 +619,7 @@ export class RandomGen3Teams extends RandomGen4Teams { name: species.baseSpecies, species: forme, speciesId: species.id, - gender: species.gender, + gender: species.gender || (this.random(2) ? 'F' : 'M'), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/data/random-battles/gen4/teams.ts b/data/random-battles/gen4/teams.ts index beadb292ca..1cecfe340f 100644 --- a/data/random-battles/gen4/teams.ts +++ b/data/random-battles/gen4/teams.ts @@ -767,7 +767,7 @@ export class RandomGen4Teams extends RandomGen5Teams { name: species.baseSpecies, species: forme, speciesId: species.id, - gender: species.gender, + gender: species.gender || (this.random(2) ? 'F' : 'M'), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/data/random-battles/gen5/teams.ts b/data/random-battles/gen5/teams.ts index 21af10e2ef..2023038617 100644 --- a/data/random-battles/gen5/teams.ts +++ b/data/random-battles/gen5/teams.ts @@ -831,7 +831,7 @@ export class RandomGen5Teams extends RandomGen6Teams { name: species.baseSpecies, species: forme, speciesId: species.id, - gender: species.gender, + gender: species.gender || (this.random(2) ? 'F' : 'M'), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/data/random-battles/gen9baby/teams.ts b/data/random-battles/gen9baby/teams.ts index b5d75325fa..801cd07df9 100644 --- a/data/random-battles/gen9baby/teams.ts +++ b/data/random-battles/gen9baby/teams.ts @@ -653,7 +653,7 @@ export class RandomBabyTeams extends RandomTeams { return { name: species.baseSpecies, species: forme, - gender: species.gender, + gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/data/random-battles/gen9cap/teams.ts b/data/random-battles/gen9cap/teams.ts index 6342258be7..af0afd79c0 100644 --- a/data/random-battles/gen9cap/teams.ts +++ b/data/random-battles/gen9cap/teams.ts @@ -170,7 +170,7 @@ export class RandomCAPTeams extends RandomTeams { return { name: species.baseSpecies, species: forme, - gender: species.baseSpecies === 'Greninja' ? 'M' : species.gender, + gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/data/random-battles/gen9ffa/teams.ts b/data/random-battles/gen9ffa/teams.ts index d3f964b81b..2153ee59dd 100644 --- a/data/random-battles/gen9ffa/teams.ts +++ b/data/random-battles/gen9ffa/teams.ts @@ -883,7 +883,7 @@ export class RandomFFATeams extends RandomTeams { return { name: species.baseSpecies, species: forme, - gender: species.gender, + gender: species.baseSpecies === 'Greninja' ? 'M' : (species.gender || (this.random(2) ? 'F' : 'M')), shiny: this.randomChance(1, 1024), level, moves: shuffledMoves, diff --git a/sim/global-types.ts b/sim/global-types.ts index d339924211..9efaa55f29 100644 --- a/sim/global-types.ts +++ b/sim/global-types.ts @@ -515,7 +515,7 @@ declare namespace RandomTeamsTypes { name: string; species: string; speciesId?: string; - gender: string | boolean; + gender: Exclude | false; moves: string[]; ability: string; evs: SparseStatsTable; diff --git a/sim/pokemon.ts b/sim/pokemon.ts index d0940757fa..c3ca084d10 100644 --- a/sim/pokemon.ts +++ b/sim/pokemon.ts @@ -336,10 +336,7 @@ export class Pokemon { set.level = this.battle.clampIntRange(set.adjustLevel || set.level || 100, 1, 9999); this.level = set.level; - const genders: { [key: string]: GenderName | null } = { __proto__: null, M: 'M', F: 'F', N: 'N' }; - this.gender = genders[set.gender] || this.species.gender || - (this.battle.random() <= this.species.genderRatio.M ? 'M' : 'F'); - if (this.gender === 'N') this.gender = ''; + this.gender = ['M', 'F'].includes(set.gender) ? set.gender : ''; this.happiness = typeof set.happiness === 'number' ? this.battle.clampIntRange(set.happiness, 0, 255) : 255; if (this.battle.format.mod === 'gen7letsgo') this.happiness = 70; this.pokeball = toID(this.set.pokeball) || 'pokeball' as ID; diff --git a/test/sim/items/quickclaw.js b/test/sim/items/quickclaw.js index ab2041c242..8c7d67a40b 100644 --- a/test/sim/items/quickclaw.js +++ b/test/sim/items/quickclaw.js @@ -11,7 +11,7 @@ describe('Quick Claw', () => { }); it(`[Gen 2] shares its activation roll with every holder on any given turn`, () => { - battle = common.gen(2).createBattle({ seed: [1, 2, 3, 27] }, [[ + battle = common.gen(2).createBattle({ seed: [56315, 2707, 289, 7274] }, [[ { species: 'snorlax', item: 'quickclaw', moves: ['sleeptalk'] }, ], [ { species: 'mewtwo', item: 'quickclaw', moves: ['sleeptalk'] }, @@ -28,7 +28,7 @@ describe('Quick Claw', () => { }); it(`[Gen 3] causes Speed ties with every holder when activated`, () => { - battle = common.gen(3).createBattle({ seed: [163, 106, 112, 542] }, [[ + battle = common.gen(3).createBattle({ seed: [54340, 18392, 54347, 33433] }, [[ { species: 'snorlax', item: 'quickclaw', moves: ['spore'] }, ], [ { species: 'deoxys', item: 'quickclaw', moves: ['seismictoss'] }, diff --git a/test/sim/moves/assurance.js b/test/sim/moves/assurance.js index fb04655c79..00db85b5c4 100644 --- a/test/sim/moves/assurance.js +++ b/test/sim/moves/assurance.js @@ -28,7 +28,7 @@ describe('Assurance', () => { it(`should double the power against damaged Pokemon, not damaged slots`, () => { battle = common.createBattle({ gameType: 'doubles' }, [[ { species: 'bulbasaur', level: 1, moves: ['sleeptalk'] }, - { species: 'landorus', moves: ['sleeptalk'] }, + { species: 'landorus', ability: 'shellarmor', moves: ['sleeptalk'] }, ], [ { species: 'alakazam', moves: ['psychic'] }, { species: 'pawniard', moves: ['assurance'] }, diff --git a/test/sim/moves/burnup.js b/test/sim/moves/burnup.js index 5da9d08a5b..013125b16e 100644 --- a/test/sim/moves/burnup.js +++ b/test/sim/moves/burnup.js @@ -12,7 +12,7 @@ describe('Burn Up', () => { it('should not thaw the user if it is not a Fire type', () => { battle = common.createBattle({ - seed: [0, 0, 0, 0], + seed: [0, 0, 38, 40643], customRules: 'guaranteedsecondarymod', }, [ [{ species: 'Moltres', moves: ['burnup'] }], diff --git a/test/sim/moves/pursuit.js b/test/sim/moves/pursuit.js index 3c1358c5ab..c1a734262c 100644 --- a/test/sim/moves/pursuit.js +++ b/test/sim/moves/pursuit.js @@ -106,7 +106,7 @@ describe(`Pursuit`, () => { { species: "Clefable", moves: ['calmmind'] }, { species: "Furret", moves: ['calmmind'] }, ], [ - { species: "Clefable", moves: ['calmmind'] }, + { species: "Clefable", ability: 'shellarmor', moves: ['calmmind'] }, { species: "Alakazam", moves: ['calmmind'] }, { species: "Roserade", moves: ['calmmind'] }, ]]);