The AI prioritizes physical and special moves over status moves, and doesn't use Stealth Rock, Light Screen, or Reflect on the first turn. It also doesn't use heal moves even when HP is below half, and doesn't use Swords Dance or Dragon Dance very often.
The skill level is 100.
Also, when there is only one member in the party, no move is used when the PP of the most effective move is 0, and no error log is displayed.
I don’t think this is a "bug" per se, but I believe the default AI is actually superior when it comes to using status moves.
This is because status moves are almost always chosen with a specific role or "utility" in mind. For example:
Stealth Rock is used to punish switching and to nullify items like Focus Sash or abilities like Sturdy.
Recovery moves are meant to increase a Pokémon's longevity on the field.
Setup moves (stat boosters) are essential for breaking through defensive "walls" or minimizing incoming damage.
Light Screen, Reflect, and Tailwind are specifically brought in to create a tactical advantage for the rest of the team.
Every Pokémon equipped with status moves has a defined role. Therefore, if a Pokémon has a status move and the situation allows it to function effectively, I want the AI to prioritize using it.
There still remains some other bugs/mistakes not reported though.
The plugin names used in self.dbk_enabled?(plugin) isn't correct, and Settings::ZMOVE_TRIGGER_KEY never exist in Z-Power plugin.
Should be the one below.
Ruby:
# Check if DBK plugin is enabled
def self.dbk_enabled?(plugin)
return false unless DBK_PLUGINS[plugin]
# 1. Try PluginManager check (most reliable)
if defined?(PluginManager) && PluginManager.respond_to?(:installed?)
plugin_id = case plugin
when :dynamax then "[DBK] Dynamax"
when :terastallization then "[DBK] Terastalization"
when :z_moves then "[DBK] Z-Power"
when :raid_battles then "[DBK] Raid Battles"
when :sos_battles then "[DBK] SOS Battles"
else nil
end
return true if plugin_id && PluginManager.installed?(plugin_id)
end
# 2. Fallback to method/constant checks
case plugin
when :mega_evolution
return true # Built-in to Essentials, always available if item held
when :dynamax
# Check if Dynamax methods exist (more reliable than constants)
return defined?(Battle) && Battle.instance_methods.include?(:pbCanDynamax?)
when :terastallization
# Check if Terastallization methods exist
return defined?(Battle) && Battle.instance_methods.include?(:pbCanTerastallize?)
when :z_moves
return defined?(Battle) && Battle.instance_methods.include?(:pbCanZMove?)
when :raid_battles
return defined?(Battle) && Battle.instance_methods.include?(:pbRaidBattle?)
when :sos_battles
return defined?(Battle) && Battle.instance_methods.include?(:pbSOSBattle?)
else
return false
end
end
And in should_z_move?, user.can_z_move? should be @battle.pbCanZMove?(user.index) to prevent NoMethodError.
There still remains some other bugs/mistakes not reported though.
The plugin names used in self.dbk_enabled?(plugin) isn't correct, and Settings::ZMOVE_TRIGGER_KEY never exist in Z-Power plugin.
Should be the one below.
Ruby:
# Check if DBK plugin is enabled
def self.dbk_enabled?(plugin)
return false unless DBK_PLUGINS[plugin]
# 1. Try PluginManager check (most reliable)
if defined?(PluginManager) && PluginManager.respond_to?(:installed?)
plugin_id = case plugin
when :dynamax then "[DBK] Dynamax"
when :terastallization then "[DBK] Terastalization"
when :z_moves then "[DBK] Z-Power"
when :raid_battles then "[DBK] Raid Battles"
when :sos_battles then "[DBK] SOS Battles"
else nil
end
return true if plugin_id && PluginManager.installed?(plugin_id)
end
# 2. Fallback to method/constant checks
case plugin
when :mega_evolution
return true # Built-in to Essentials, always available if item held
when :dynamax
# Check if Dynamax methods exist (more reliable than constants)
return defined?(Battle) && Battle.instance_methods.include?(:pbCanDynamax?)
when :terastallization
# Check if Terastallization methods exist
return defined?(Battle) && Battle.instance_methods.include?(:pbCanTerastallize?)
when :z_moves
return defined?(Battle) && Battle.instance_methods.include?(:pbCanZMove?)
when :raid_battles
return defined?(Battle) && Battle.instance_methods.include?(:pbRaidBattle?)
when :sos_battles
return defined?(Battle) && Battle.instance_methods.include?(:pbSOSBattle?)
else
return false
end
end
And in should_z_move?, user.can_z_move? should be @battle.pbCanZMove?(user.index) to prevent NoMethodError.
### 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...
Very nice plugin.
But during testing there was an error
[2026-02-15 01:29:30 +0100]
[Pokémon Essentials version 21.1]
[v21.1 Hotfixes 1.0.9]
Exception: NoMethodError
Message: undefined method `>' for nil:NilClass
Backtrace:
[Advanced AI System] 0_Move_Scorer.rb:1696:in `score_protect_utility'
[Advanced AI System] 0_Move_Scorer.rb:417:in `score_move_advanced'
[Advanced AI System] Core.rb:98:in `pbGetMoveScore'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:512:in `block (2 levels) in pbGetMoveScores'
PBDebug:6:in `logonerr'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:512:in `block in pbGetMoveScores'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:481:in `each'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:481:in `each_with_index'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:481:in `pbGetMoveScores'
[Deluxe Battle Kit] [003] Command Menu Refactor.rb:463:in `pbDefaultChooseEnemyCommand'
I've tried to use U-turn (super-effective in this case (but I don't know if that's important)) and immediately got this.
Game didn't crash after that, but still.
[Pokémon Essentials version 21.1]
[v21.1 Hotfixes 1.0.9]
Exception: NoMethodError
Message: undefined method `damagingMove?' for #<Pokemon::Move>
Backtrace:
[Advanced AI System] Win_Conditions.rb:494:in `block in find_best_attacking_move'
[Advanced AI System] Win_Conditions.rb:493:in `each'
[Advanced AI System] Win_Conditions.rb:493:in `find_best_attacking_move'
[Advanced AI System] Win_Conditions.rb:85:in `block (2 levels) in check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:81:in `each'
[Advanced AI System] Win_Conditions.rb:81:in `block in check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:75:in `each'
[Advanced AI System] Win_Conditions.rb:75:in `check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:57:in `identify_win_condition'
[Advanced AI System] Win_Conditions.rb:386:in `apply_win_condition_bonus'
error!
[Pokémon Essentials version 21.1]
[v21.1 Hotfixes 1.0.9]
Exception: NoMethodError
Message: undefined method `damagingMove?' for #<Pokemon::Move>
Backtrace:
[Advanced AI System] Win_Conditions.rb:494:in `block in find_best_attacking_move'
[Advanced AI System] Win_Conditions.rb:493:in `each'
[Advanced AI System] Win_Conditions.rb:493:in `find_best_attacking_move'
[Advanced AI System] Win_Conditions.rb:85:in `block (2 levels) in check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:81:in `each'
[Advanced AI System] Win_Conditions.rb:81:in `block in check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:75:in `each'
[Advanced AI System] Win_Conditions.rb:75:in `check_sweep_condition'
[Advanced AI System] Win_Conditions.rb:57:in `identify_win_condition'
[Advanced AI System] Win_Conditions.rb:386:in `apply_win_condition_bonus'
error!
I've been waiting for this resource for literally years, thank you so much for taking on the challenge of making it!
A small thing I noticed in a very niche context. Not an error, but potentially of interest anyways. I set up a double battle that had a vivillon that could use rage powder next to an eevee that could use helping hand. They both had attacking moves, but the AI had the eevee use helping hand and the vivillon use rage powder the same turn, leading to the essentially no action from the opponent.
It's definitely niche, but I wonder if there's a way to build in a check that would prevent the usage of rage powder/follow me + helping hand in the same turn? Off the top of my head, it's pretty much the only move combo that literally leads to no actions occurring on the opponent's side (other than splash of course) regardless of what you, the player, does.
This section is for the discussion of the tutorials and resources on Eevee Expo. To find tutorials and resources, check out the Tutorial and Resource Manager for optimal navigation.