Battle AI

*For when the AI is used, see Battle round.*
This page describes the **battle AI** (artificial intelligence). That is, how computer-controlled opponents in battle (both wild Pokémon and enemy/ally trainers) choose which moves to use, which items to use and when to switch out. This page assumes the AI controlling an enemy trainer, although it applies for wild Pokémon and partner trainers too.

This is a complicated topic, and unnecessary for most users. Do not attempt to modify the AI unless you have decent scripting knowledge.

## AI data representations

The AI needs to have a mental model of the battle, so that it knows what's going on and what it can do. Just as a Pokémon in battle has an in-battle representation (known as a "battler"), it also has an AI representation (known as an "AIBattler"). There is also an AI representation of each trainer involved in the battle ("AITrainer"), as well as one for the move currently being evaluated and scored ("AIMove").

All wild Pokémon are considered to be controlled by a single AITrainer with a skill level of 0. This means that the only difference between wild and trainer-owned Pokémon is the skill level of the AITrainer that controls it.

The AI makes decisions from the point of view of the trainer, not an individual Pokémon. Two Pokémon owned by the same trainer will have their actions determined by the same AITrainer, meaning they will both be at the same skill level.

## Levels of AI

The basic principle of AI in Essentials is that better trainers should be cleverer than worse trainers, and all trainer should be cleverer than wild Pokémon. A cleverer AI considers more factors from the battle it is involved in, which should make its decisions more informed and sensible. While there is always some randomness involved in the AI's final decisions, smarter trainers have less of it and are more likely to choose (what it thinks is) the optimal action.

### Skill level

When defining a trainer type, one of the properties that can be defined is a skill level. This is usually the same as the trainer type's base money payout. A higher skill level represents a better AI. By default, there are 5 tiers of AI in Essentials:

 1-31
 32-47
 48-99
 100+

If a trainer is in a particular skill tier, it is also considered to be in all the skill tiers below it. For example, a high skill trainer is also considered to be a medium skill trainer.

The Setting `SMARTER_WILD_LEGENDARY_POKEMON` will increase the skill level of wild Pokémon with certain flags ("Legendary", "Mythical" and "UltraBeast") from 0 to 32, which gives them medium skill. They will therefore perform calculations to weigh the usefulness of their moves, rather than choosing one entirely at random. (More accurately, this changes the skill level of the AITrainer that controls that wild Pokémon.)

### Skill flags

In addition to skill levels, there are also skill flags. These can also be defined for a trainer type, although many of the existing skill flags are assigned automatically at the start of battle based on the trainer's skill level. Existing skill flags include:

If a skill flag is named "AntiXYZ", it will negate the skill flag "XYZ". Such anti-flags will typically be defined for a trainer type if needed, and will be used to undo the automatic assigning of skill flags mentioned above.

## AI overview

When the AI is choosing an action for a Pokémon at the start of a round, it runs `def pbDefaultChooseEnemyCommand`. This method checks the following options in this order:

1. Switch out the Pokémon.
2. Use an item from the trainer's inventory on the Pokémon (or on a fainted Pokémon if the item is a Revive).
3. Mega Evolve the Pokémon. This is not a whole action in itself; Mega Evolution occurs as part of using a move, but the decision to do so is made now.
4. Use a move known by the Pokémon. This is what the majority of AI code is for. If the AI decides all possible moves are bad, it may choose to switch out instead.

### Switching out

The main method here is `def pbChooseToSwitchOut`, which first checks whether it is possible to switch out, and then chooses the best replacement Pokémon.

There are a number of code handlers used to decide whether the AI wants to switch out the Pokémon. These are `Battle::AI::Handlers::ShouldSwitch` and `Battle::AI::Handlers::ShouldNotSwitch`, and cover scenarios such as the Pokémon being about to faint because of Perish Song or damage taken at the end of the round, being ineffective against its foe, or being vulnerable to the foe's attacks.

`def rate_replacement_pokemon` does what its name suggests. This includes checking how vulnerable the replacement Pokémon is to existing entry hazards, and making rough guesses at how effective its moves will be against its foes and how resilient it will be to attacks from its foes.

There are more clauses in the AI's switching code, such as:

* The AI will not bother to switch out at all if the foe is unable to doing anything this round, e.g. is recharging after Hyper Beam, is Truanting, is frozen. If this is the case, the AI can get a free round, so it might as well attack instead.
* The AI is only allowed to switch out if it has the `ConsiderSwitching` skill flag (see above).
* The skill flags `UsePokemonInOrder` and `ReserveLastPokemon` affect which replacement Pokémon it considers. If these flags mean there are no valid replacement Pokémon, then the AI will not switch out even if it wants to and even if it technically could (the flags just don't allow it to).
* If the Pokémon knows Baton Pass, the AI will prefer to use that to switch out instead.

Some of the AI's switching code is also used when the AI is forced to switch out, such as by U-turn, Baton Pass or to fill an empty space in battle at the end of a round. In these cases, the skill flags mentioned above that disallow choosing certain replacement Pokémon do not apply, as the AI *must* send in a replacement even if it doesn't want to because of its skill flag.

### Using an item

The main method here is `def choose_item_to_use`, which compiles a list of all items in the trainer's inventory that will have an effect if used now (i.e. will not do nothing), and then randomly determines which one (if any) to use.

Different items have different preferences. For example, Full Restore will be preferred over a Max Potion if the Pokémon has lost HP and also has a status problem. A weaker HP-healing item will be preferred over a stronger one if the stronger one will not heal any more HP than the weaker one. A status-curing item that cures a single status problem (e.g. Antidote) will be preferred over one that can cure any status problem (e.g. Full Heal).

`def get_usability_of_item_on_pkmn` decides whether an item will have an effect.

Items are only considered for use on the Pokémon whose action is being chosen. One Pokémon's action cannot be spent healing another Pokémon with an item, for example. The exception is Revive-type items, which are considered for use on any/all fainted Pokémon in the trainer's party.

Lists of the items that the AI knows how to use can be found in the script section **AI\_UseItem**, along with the code mentioned above. These lists may include values such as how much HP a Potion-like item heals, the effect of an X Attack-like item, or the relative preference of a Revive-type item (a higher number is more preferred).

### Mega Evolving

The AI decision to Mega Evolve is very simple: always do so if possible.

### Using a move

The majority of AI code exists to help the AI decide which move to use. This will not be an exhaustive description of that code.

The AI considers each move known by the Pokémon in turn and determines a score for it, which is how much it wants to use that move. The default score is 100. If the AI has the `ScoreMoves` flag, it will perform calculations and analyses to modify this score based on what that move will do. If the AI has the `PredictMoveFailure` flag, it will completely ignore any move which is predicted to fail (e.g. Sunny Day if the weather is already sunny).

Scoring a move is broken into two main parts:

* Score modifiers based on the move's function code, i.e. its effect. If the move's effect will do nothing, the move will be considered useless if it is a status move, or be treated as a move with no effect if it is a damaging move. A useless move is given a particularly low score.
* Score modifiers based on more general properties and scenarios. This includes how much damage the move will deal, whether it will thaw the user/target if they are frozen, whether it is a priority move, whether it is a Fire move and the user is covered in Powder, whether abilities will trigger as a result of using the move, and so on.

If a move could target one of several Pokémon, the AI will individually score the move used against each of those targets. Each move/target combination is treated as a separate option the AI can choose from.

Once all move/target combinations have been scored, `def pbChooseMove` randomly chooses one of these options to be the action this round. It first determines a threshold score, which is a fraction of the highest score out of the options (the fraction is calculated in `def move_score_threshold`, and is about 0.8 on average but is higher or lower depending on the AI trainer's skill level). All of the options' scores are lowered by this threshold score, and any that end up at 0 or lower are discarded. This means that moves that are significantly worse than others cannot be chosen at all. Out of the remaining options, one is chosen at random using the modified scores as weights.

If the highest-scoring option isn't particularly high, then the AI may choose to switch out the Pokémon instead.

## Debug logging

For debugging purposes, the decisions made by the AI, including a breakdown of the scores it calculates for each move, can be recorded. While playing in Debug mode and the logging is enabled, this breakdown will be printed to the console window and will also be written into the file "debuglog.txt" in the Data folder.

The Debug menu function "Toggle Battle Logging" toggles whether this logging happens. It toggles the value of `$INTERNAL` between `true` and `false`.