• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
  • Reminder: AI-generated content is not allowed on the forums per the Rules and Regulations. Please contact us if you have any questions!
Resource icon

v21.1 Advanced AI System 2.5

This resource pertains to version 21.1 of Pokémon Essentials.
## New Shared Helpers

Eight utility methods added to CombatUtilities and SpeedTiers to replace
hundreds of inconsistent inline calculations across all damage estimators:

  • resolve_move_type — Final move type after -ate abilities, Tera Blast, Weather Ball, Terrain Pulse
  • scrappy_effectiveness — Removes Ghost immunity for Scrappy / Mind's Eye
  • resolve_move_power — Runtime base power for variable-power moves (PBS power=1)
  • field_modifier — Weather, terrain, items (Choice Band/Specs/Life Orb), burn penalty
  • defender_modifier — Assault Vest, Eviolite, Sandstorm Rock SpDef, Snow Ice Def
  • screen_modifier — Reflect, Light Screen, Aurora Veil (bypassed by Infiltrator)
  • ability_damage_modifier — Fur Coat, Ice Scales, Thick Fat, Filter, Multiscale, Tinted Lens, etc.
  • calculate_effective_speed — Stat stages, Choice Scarf, Tailwind, Trick Room, weather abilities

---

## Crash Fixes (~30)

  • num_targets called on a Symbol — crashed on every multi-target move evaluation
  • Role_Detection.detect_roles was never defined as a method — entire role system was non-functional
  • .physical?, .statusMove?, .damaging? called on GameData::Move objects (only exist on Battle::Move) — crashed Encore, Sucker Punch, Taunt, Will-O-Wisp scoring, threat assessment, and speed evaluation
  • stat_changes[:SPEED] TypeError when stat_changes hash didn't exist
  • pkmn.index NoMethodError in Role Detection for non-battler objects
  • user.battler double-wrap on already-unwrapped Battler objects — crashed Unburden threat, pinch berry, resist berry, weakness policy, and rocky helmet evaluations
  • Prediction_System.should_double_switch? called .type on Pokemon::Move objects — feature completely non-functional
  • Utilities.setup_move? delegation missing — NoMethodError on every call
  • Utilities.setup_beneficial? referenced bare constant instead of qualified Utilities::ALL_SETUP_MOVES
  • Hotfixes.validate_sanity_check called undefined pbCanChooseMove?
  • Multiple nil crashes — fainted Pokémon species data, nil target in item eval, nil move in Custom_Content
  • Division by zero in weight-based and speed-ratio moves (Grass Knot, Electro Ball, Gyro Ball)
  • Mega_Intelligence referenced nonexistent GameData::Mega constant
  • DBK_Compat rescue clause referenced wrong variable
  • Custom_Content.ability_suppressed? crashed on party Pokemon (no .effects method)
  • Variable-power moves read as 1 BP causing zero-damage estimates
  • Team_Preview.evaluate_lead_matchup — nil entries when party smaller than 6
  • Debug_Menu used puts instead of pbMessage
  • Learning_System divide-by-zero in win-rate calculation

---

## Ability Suppression Overhaul (~185 Fixes)

185+ instances of raw ability_id == :X converted to hasActiveAbility?(:X),
so the AI properly respects Mold Breaker, Gastro Acid, and Neutralizing Gas.

Affected abilities: Intimidate, Magic Bounce, Prankster, Sturdy, Flash Fire,
Levitate, Water Absorb, Volt Absorb, Unaware, Contrary, Magic Guard, Regenerator,
Disguise, Ice Face, Harvest, Protean/Libero, and many more.

Fixed in: Move Scorer, Switch Intelligence, Prediction System, Doubles Coordination,
Strategic Awareness, Substitute Logic, Tera Intelligence, Field Effects,
Endgame Scenarios, Win Conditions, Weather/Terrain Wars, Battle Personalities

---

## Damage Calculation Overhaul

### Simplified Calculators — Missing Modifiers

Eight simplified damage calculators were missing entire modifier classes.
All updated with shared helpers for consistent results:

| Method | File |
|--------|------|
| estimate_damage | Combat_Utilities.rb |
| estimate_move_damage | Substitute_Logic.rb |
| max_known_damage | Move_Memory.rb |
| calculate_predicted_damage | Prediction_System.rb |
| estimate_damage_percent | Pivot_Moves.rb |
| calculate_rough_damage | Endgame_Scenarios.rb |
| estimate_damage_percent | Win_Conditions.rb |
| calculate_incoming_damage | Switch_Intelligence.rb |

Each now includes: field modifiers, defender modifiers, screens, Parental Bond,
and ability-based damage modifiers.

### Missing Adaptability and Huge Power / Pure Power

Six calculators completely ignored two of the most impactful offensive abilities:

  • Adaptability (2× STAB instead of 1.5×) — Porygon-Z, Crawdaunt, Mega Lucario had STAB underestimated by 33%
  • Huge Power / Pure Power (2× Attack) — Azumarill, Medicham, Mawile had physical damage underestimated by 100%

### Missing STAB

Several calcs had no STAB at all or applied STAB based on unresolved move type
(wrong for -ate abilities). Pivot_Moves, Win_Conditions, and Move_Memory affected.

### Move Scorer Ability/Item Awareness (60+)

60+ competitive abilities and items were completely missing from the damage
calculation and scoring logic:

  • Offensive abilities: Pixilate/Aerilate/Refrigerate/Galvanize, Protean/Libero, Sheer Force, Tough Claws, Strong Jaw, Iron Fist, Technician, Mega Launcher, Reckless, Analytic, Tinted Lens, Neuroforce, Solar Power, Sand Force
  • Defensive abilities: Fur Coat, Filter/Solid Rock/Prism Armor, Multiscale/Shadow Shield, Ice Scales, Thick Fat, Heatproof, Marvel Scale, Mirror Armor, Natural Cure
  • Damage multipliers: Water Bubble (2× Water, 0.5× Fire taken), Steelworker, Parental Bond, Aura abilities (Dark/Fairy)
  • Items: Choice Band/Specs damage scaling, Life Orb, Assault Vest, Expert Belt, type-boosting items, Sharpness, Rocky Payload, Flash Fire boost
  • Status immunity: Limber, Water Veil, Insomnia, Vital Spirit, Magma Armor, Oblivious, Own Tempo, Pastel Veil

### Weather Ball / Terrain Pulse

Terrain Pulse doubled BP on terrain but never changed type from Normal.
Fixed to match Weather Ball pattern.

---

## Type System Fixes

### Type Effectiveness Halved Globally (8 Locations)

/NORMAL_EFFECTIVE instead of /NORMAL_EFFECTIVE_MULTIPLIER — all damage
effectiveness was halved across 6 files. Every SE move showed half the actual bonus.

### Type Effectiveness Squaring (12+ Fixes)

Effectiveness calculated against type1 and type2 separately then multiplied —
squaring the result for single-type Pokémon (2× became 4×, 0.5× became 0.25×).

Fixed in: Prediction System, Substitute Logic, Move Scorer, Strategic Awareness, Win Conditions

### Type Resolution (50+ Fixes)

50+ call sites used raw move.type without -ate abilities, Tera Blast,
Weather Ball, or Terrain Pulse. All replaced with resolve_move_type.

### Tera Type Support (~25 Locations)

.types[] array access replaced with .pbTypes(true) across 8 files so the AI
reads the Pokémon's Tera type when Terastallized instead of the original types.

### Scrappy / Mind's Eye (10+ Fixes)

Normal/Fighting moves always showed 0× vs Ghost even with Scrappy or Mind's Eye.
Fixed with scrappy_effectiveness wrapper across 10+ effectiveness call sites.

---

## Weather & Snow Compatibility

### Gen 9 Snow Weather (40+ Fixes)

Massive sweep replacing :Hail with :Snow or adding Snow support throughout:

  • Snow Warning, Slush Rush, Ice Body, Snow Cloak now recognized under Snow weather
  • Snowscape and Chilly Reception correctly set Snow (not Hail)
  • Aurora Veil and Blizzard accuracy work in both Hail and Snow
  • Snow chip damage and immunity checks updated
  • Weather synergy, archetype detection, and extender items all updated
  • Affected: Weather_Terrain_Wars, Field_Effects, Strategic_Awareness, Switch_Intelligence,
Doubles_Coordination, Custom_Content, Item_Intelligence, Team_Preview, Priority_Tiers

### Cloud Nine / Air Lock Bypass (12 Locations)

12 weather-dependent calculations across 7 files never checked for Cloud Nine or
Air Lock — weather bonuses applied even when suppressed.

### Weather Symbol Mismatches

:Sand/:Snow used instead of :Sandstorm/:Hail — weather-dependent scoring
was completely dead for Sandstorm and Hail/Snow conditions.

### Extreme Weather

Sunny Day scored positively under Harsh Sun (move fails). Water/Fire moves scored
as merely weak under primal weather instead of completely failing (−200).

### Terrain Logic Fixes

  • Electric Terrain sleep immunity only covered 2 moves — expanded to all sleep moves, added grounded check
  • Psychic Terrain priority block applied against airborne targets (should only block vs grounded)
  • Misty Terrain Dragon penalty applied against airborne targets
  • Misty Terrain penalized ALL status moves (Swords Dance, Stealth Rock) instead of only status-condition moves
  • Terrain checks used != :None instead of != nil — always true, inflating scores

---

## Speed and Trick Room (22+ Fixes)

22+ raw .speed comparisons replaced with calculate_effective_speed,
covering: Trick Room, stat stages, Choice Scarf, paralysis, Tailwind,
Swift Swim, Chlorophyll, Sand Rush, Slush Rush, Surge Surfer, Unburden.

Additional fixes:
  • Nil speed variables made Trick Room and Prankster scoring completely dead
  • Trick Room scoring self-sabotaged — slow Pokémon were incentivized to cancel their own TR
  • Choice Scarf suspect heuristic compared calculated stat (~200) against base stat range (80–100) — always false
  • Choice-lock detection was entirely non-functional
  • Itemless Pokémon falsely flagged as Scarf users after species heuristic match

---

## Variable-Power Moves (40+ Fixes)

Moves with PBS Power=1 (Eruption, Water Spout, Flail, Reversal, Electro Ball,
Gyro Ball, Low Kick, Heavy Slam, Stored Power, etc.) estimated at 1 BP.
All updated with resolve_move_power using actual runtime formulas.

---

## Move List Completeness (60+ Fixes)

Hardcoded move lists expanded significantly:

  • Setup moves (~8 → 25+) — Calm Mind, Nasty Plot, Quiver Dance, Shell Smash, Geomancy, Victory Dance, etc.
  • Pivot moves (~3 → 8+) — Flip Turn, Chilly Reception, Shed Tail, Teleport
  • Protect variants (~2 → 10+) — King's Shield, Spiky Shield, Baneful Bunker, Obstruct, Silk Trap, Burning Bulwark
  • Recovery moves (~4 → 18+) — Strength Sap, Shore Up, Giga Drain, Leech Life, Oblivion Wing
  • Sound moves (~5 → 25+) — Torch Song, Alluring Voice, Psychic Noise, Boomburst, Overdrive
  • Entry hazards (~2 → 5) — Toxic Spikes, Sticky Web, Ceaseless Edge
  • Spread moves (~12 → 40+) — Make It Rain, Scorching Sands, Lava Plume, Discharge
  • Weight-based (missing → complete) — Heavy Slam, Heat Crash, Low Kick, Grass Knot

Also fixed :SWORDSDANCE vs :SWORDS_DANCE format mismatches.

### Missing Function Code Coverage

Roost, Shore Up, and Purify had no AI scoring logic.
Strength Sap, Revival Blessing, and Ceaseless Edge/Stone Axe were also unscored.

### function_code Symbol Mismatches (4 Locations)

UPPER_SNAKE_CASE compared against CamelCase function codes — 4 entire move
categories had dead scoring branches.

---

## Side-Index Bugs — Doubles (75+ Fixes)

### pbParty / pbAbleCount Wrong Index (45+)

battle.pbParty(battler.index) and pbAbleCount(battler.index) expect a
side index (0 or 1), but were passed raw battler slot indices (0–3 in doubles).
Slots 2 and 3 returned the wrong team's party. Fixed across 14 files.

### sides[] Operator Bug (30+)

battle.sides[(index + 1) % 2] for the opponent's side — in doubles slot 2:
(2+1)%2 = 1 = same side as attacker. Fixed to sides[1 - (index & 1)].

Affected: hazard checks, Reflect/Light Screen, Sleep Clause, Sticky Web,
pivot hazard bonus, sacking evaluation, Toxic Spikes absorber count.

### Other Doubles Fixes

  • Icicle Crash and Icicle Spear incorrectly listed as spread moves
  • Sandstorm and Hail falsely boosted Rock/Ice move power (no such mechanic)
  • Helping Hand hook targeted opponents instead of partner — dead code
  • Spotlight scoring completely inverted — rewarded Spotlighting bulky opponents
  • Prevent_move_conflicts unconditionally penalized screens/hazards/weather regardless of partner's move
  • Coaching scored identically at all HP levels
  • Disruption moves summed scores across all opponents instead of using best target
  • Partner synergy crashed when partner fainted (nil @pokemon)
  • Spread move lists missed partner-hitting side effects
  • Combined damage calcs crashed on stale target references after KOs
  • evaluate_momentum compared party alive (1–6) vs active battlers (0–1) — never true in singles
  • Parental Bond adjustment was inside multiHitMove block — unreachable for normal moves

---

## Switch Intelligence Fixes

  • Switch prediction entirely broken — wrong battler index formula
  • assess_threat always rated 5.0 (nil opponent reference)
  • get_partner compared different object types — always returned user's own battler as partner
  • Stat-stage multiplier arrays completely wrong (incorrect values at every index)
  • Zoroark's get_real_types returned Illusion disguise types instead of real types
  • Sniper crit damage double-multiplied — 2.625× instead of correct 2.25× at 100% crit rate
  • Magic Guard hazard calc didn't check Flying/immunity for Toxic Spikes and Sticky Web
  • Double nature modifier in calculate_party_speed
  • Role-based switch-in crashed on party Pokemon objects (no battler stats)
  • evaluate_better_options and main selection loop used wrong party indices in doubles
  • Win_Conditions.check_setup_condition used respond_to?(:stages) — always false for party objects

---

## Move Prediction & Learning

  • Move prediction entirely non-functional — :move_frequency key never matched :move_counts
  • Move memory category tracking used wrong predicted category
  • Regenerator detection used wrong function code
  • GameData::Move shim fixes for compatibility

---

## Item & Ability Intelligence

  • Choice Scarf applied 1.5× damage multiplier to all moves (should only boost speed)
  • Eject Pack only checked status moves — missed Snarl, Icy Wind, Moonblast stat drops
  • Eject Pack boost-reset included negative stages in sum
  • Black Sludge treated as recovery for non-Poison holders during Protect (it deals damage)
  • Scald penalized as harshly as Will-O-Wisp against Guts users (−60 vs correct −30)
  • Ghost-type trapping escape missing from Arena Trap and Magnet Pull
  • Shed Shell escape check had symbol typo (:SHEDSBELL instead of :SHEDSHELL)
  • Mycelium Might listed as Mold Breaker variant (only bypasses abilities for status moves)
  • Contact punishment computed all penalties before Long Reach / Protective Pads early-return

### Gen 9 VGC Item Awareness

Six dominant VGC items had no AI awareness:
Covert Cloak, Clear Amulet, Mirror Herb, Loaded Dice, Booster Energy, Ability Shield

---

## Ability Interaction Fixes

  • Contrary/Defiant/Competitive only checked status moves — missed damaging moves with stat drops (Snarl, Icy Wind, Moonblast)
  • Simple ability check applied to target instead of user for setup moves
  • Adaptability double-stacked in Custom_Content damage calc
  • Venoshock only checked regular poison, missed badly poisoned
  • Fusion Flare/Bolt gave power bonus without requiring ally to have the partner move
  • Recoil Tracking checked Rock Head on wrong battler location
  • ability_suppressed? had arguments swapped in Custom_Content

---

## Gimmick Intelligence Fixes

  • Mega_Intelligence — Scoring methods returned early before reaching analysis logic
  • Dynamax_Intelligence — Benefit scores calculated but never applied; Z-Move scoring referenced wrong constants
  • Dynamax_Intelligence — Endgame bonuses triggered from turn 1 (enemy count always ≤ 2 in singles)
  • Dynamax_Intelligencegmax_move check always returned true
  • Tera_Intelligence — Type evaluation used raw move types instead of resolved types
  • Mechanics_Hooks — Gimmick hook crashed on nil/stale @user reference
  • Terastallization plugin ID had a typo — PluginManager detection always failed

---

## Logic & Behavioral Fixes

  • Phazing moves still attempted with only 1 target available
  • Pivot moves tried to switch behind a Substitute
  • Ally-only moves selected when no ally present
  • Grounded check order wrong — Gravity, Iron Ball, and Ingrain overrides added
  • Hazard detection checked wrong side
  • Endgame double-counting opponent threats
  • Protect stall scored against wrong target
  • Team Preview ability checks on non-battler objects
  • Switch chance threshold too aggressive
  • Flinch immunity not checked before scoring flinch moves
  • Sound move barrier bypass unchecked
  • Focus Punch penalty always applied — priority >= 0 matched every move instead of > 0
  • Wonder Room attack category bonus completely inverted
  • total_stat_boosts summed negatives — boosted sweepers with minor debuffs looked unboosted
  • pivots and recovery_users counted per-move instead of per-Pokémon
  • pbAbleNonActiveCount passed battler slot instead of side index
  • Trick penalized when target had no item (irrelevant — user's item is what matters)
  • Opposing indices called on Battler instead of Battle — trade-KO logic compared AI vs itself
  • Setup data for Coil and Hone Claws overwritten by duplicate hash entries
  • Dead :TOXIC status branch (not a valid status symbol in PE)

---

## Dead Code Connected

  • pbRegisterMove hook chain was never executed — 4 files of intelligence (Mega, Dynamax, Tera, Mechanics_Hooks) were completely disconnected. Now properly wired.
  • detect_roles method body existed as orphaned module-level code — never callable. Wrapped in proper method definition.

---

## Debug & Production Cleanup

  • Unconditional echoln and puts calls in Core, Switch_Intelligence, and Hotfixes removed from production builds
  • Boot banners gated behind debug flags
  • Console spam on every switch decision eliminated
## Critical Crash Fixes
  • NameError: uninitialized constant Battle::AI::ItemIntelligenceItem_Intelligence.rb line 588
  • NoMethodError: undefined method 'battler' for Battle::Battler0_Move_Scorer.rb line 1862
  • NoMethodError: undefined method 'damagingMove?' for GameData::MoveDoubles_Coordination.rb line 2790
  • NameError: uninitialized constant Battle::AI::DoublesCoordinationDoubles_Coordination.rb line 3613
  • NoMethodError: undefined method 'stat_up' for Battle::Move::NoneDoubles_Coordination.rb line 144
  • NoMethodError: undefined method 'physicalMove?' for GameData::Move0_Move_Scorer.rb, Move_Memory.rb, Prediction_System.rb (4 sites)
---
## Behavioural Fixes
  • Toxic / Will-O-Wisp / Thunder Wave no longer score positively against immune types (e.g. Toxic vs Steel/Poison)
  • ReserveLastPokemon ace is now strictly reserved until all other party members are down
  • Reduced excessive switching when no meaningfully better option exists
  • Dazzling / Queenly Majesty / Armor Tail now correctly block priority on the entire side in doubles
---
## New Option
- ENFORCE_SLEEP_CLAUSE toggle in 0_Settings.rb (default: true)
Fixed 1-2 more bugs......................
Fixed 1-2 more bugs......................
Added a better check for double battles - fixed undefined method `stages' for #<Pokemon DONDOZO Lv.50
Fixed undefined method `damagingMove?' for #<Pokemon::Move>
v2.4.0 Update — Full Gen 1–9 Coverage + Bug Fixes

Missing support for moves, abilities, and items has been implemented — the AI should now cover everything from Gen 1–9.

Console bug and some other small bugs are fixed too.

---

Moves

  • Heavy Slam / Heat Crash — Weight-ratio → 40–120 BP calculation
  • Low Kick / Grass Knot — Target-weight thresholds → 20–120 BP
  • Terrain Pulse — 2× BP + type change in active terrain
  • Topsy-Turvy — +80 vs setup, −40 if would invert drops
  • Armor Cannon — Def / SpDef drop cost penalty (−10)
  • Bitter Blade — Drain bonus (+15) when user < 70% HP
  • Hydro Steam — 1.5× BP in Sun / Harsh Sun instead of penalty
  • Psyblade — 1.5× BP in Electric Terrain
  • Pledge Combos — Fire + Grass → Sea of Fire, Water + Fire → Rainbow, Grass + Water → Swamp; 150 BP
  • Fusion Flare / Bolt — 2× power when partner used complement move
  • Ruination — Fixed 50% current-HP damage scoring

Abilities

  • As One (Glastrier) — 2.5× weight, +1.2 threat, 1.9 snowball
  • As One (Spectrier) — 2.5× weight, +1.2 threat, 1.9 snowball
  • Mind's Eye — 1.5× weight, +0.5 threat, Scrappy + accuracy bypass in damage calc
  • Seed Sower — −1.0 defensive weight, +0.4 threat, Mold Breaker bypass (+10)
  • Zero to Hero — 2.5× weight (Hero-form Palafin)
  • Ice Scales — −2.5 defensive weight, 0.5× special modifier, Mold Breaker bypass (+20)
  • Tera Shell — 0.5× all moves at full HP, Mold Breaker bypass (+25)
  • Stamina — Gen 9 defensive ability dictionary
  • Weak Armor — Gen 9 defensive ability dictionary
  • Anger Shell — Gen 9 offensive ability dictionary
  • Electromorphosis — Gen 9 offensive ability dictionary
  • Wind Power — Gen 9 offensive ability dictionary
  • Toxic Boost / Flare Boost — Gen 9 offensive ability dictionary
  • Cotton Down — Gen 9 defensive ability dictionary
  • Embody Aspect — Gen 9 offensive ability dictionary

Items

  • Light Ball — 2.0× damage for Pikachu; +0.8 threat
  • Thick Club — 2.0× physical for Cubone / Marowak; +0.8 threat
  • Shed Shell — has_shed_shell? helper; trapping moves −30 vs holder; −0.2 threat
  • Ability Shield — −40 for ability-changing moves vs holder; −0.3 threat
  • Power Herb — Two-turn move bonus
  • White Herb — Stat-drop recovery bonus
  • Booster Energy — Paradox Pokémon stat boost scoring
### Critical Fixes
- Side/Field-Targeting Moves Scoring 0
Stealth Rock, Spikes, Reflect, Light Screen, Tailwind and all other moves with
num_targets == 0 were never scored because vanilla Essentials calls
pbGetMoveScore() without a target argument. The scorer's guard clause
(return 0 unless move && user && target) rejected them all.
- Core.rb: Added fallback target resolution — picks the first non-fainted
opponent when target is nil.
- 0_Move_Scorer.rb: Relaxed guard to return 0 unless move && user with
internal target resolution for nil targets.
- GrassyTerrain PBEffects Crash
PBEffects::GrassyTerrain does not exist; Grassy Terrain is a field terrain,
not a battle-side effect. Protect/Detect scoring crashed when evaluating
passive recovery.
- 0_Move_Scorer.rb line ~1680: Changed to
@battle.field.terrain == :Grassy && user.battler.affectedByTerrain?.
- Kernel#pp RGSS Safety
RGSS/mkxp lacks the pp standard library. Any call to pp (including AI
debug logging) caused a fatal NoMethodError.
- Core.rb: Defines Kernel#pp as a safe echoln-based fallback when the
native implementation is unavailable.
- SystemStackError Recursion Guard
Effectiveness.calculate and GameData::Type.calculate could infinitely
recurse in certain type-matchup edge cases.
- Hotfixes.rb: Added recursion depth guard (max 10) on both methods.
Fixed Status Moves in Move scorer/ fixed pp bug
Back
Top