![]() |
Trainer AI in Firered
Hello.
I found what seems to be the scrips that determine how trainers act during battles. It's a different bytecode than that used for NPCs, or moves, or moveanimations, or overworld effects, etc. It runs a series of 32 scripts for each move in the moveset, the scripts can add or subtract to a score for this move depending on the circumstances and then quit. Unlike the npc scripts there aren't serveral variables that you can access by number but only one that you can use freely, and another one that contains the id of the move being considered right now. In case a command can use either variable as input, there are two variants of it with separate codes. (In my notes __8 is the free variable and _2 is the move being considered, I'm renaming these however wherever I encounter them in my notes. _8, _16 and _32 refer to the lengths one byte, two bytes, four bytes) Many of these commands are followed by one byte that specifies if it refers to the attacking pokemon (1) or defending pokemon (0). The dispatch table is at 083F55A4. Meanings as far as I have figured them out so far are: Spoiler:
Reminder regarding status1 and status2. The Pokemon Information relevant for a battle is copied from their own data structures into four structures at 02023BE4 (two for player side, two for opponent side). JPAN documented this in this post: http://www.pokecommunity.com/showpost.php?p=7156541&postcount=5 (in the RAM-structures spoiler) and status1 and status2 are part of that structure. The array of 32 pointers to such scripts is at 081D9BF4. Code:
Here are some lightly documented examples: Spoiler:
More information can be found in my IDA database. At this point I need to thank JPAN. Never before have I relied on JPANs research this much. |
Really NICE, ****ING GREAT if IT would be possible to better the enemy ai, GREAT JOB!
|
I also made some overview graphics, for people that are also reverse engineering the battle system.
Notes: A → B (solid) means "A calls B.". A → B (dashed) means "A causes B to be called.". A → B (dotted) is like a call (solid), in the sense that after B is done, A continues running, but it is realized through means like function pointers (dashed). The blue part exists in at least seven variants for different circumstances. And each battle side (player side 1&2, and opponent side 1&2) can use a different set of the blue functions. It's also likely that the blue part is the interface for link battles. 'bs', 'bx', and 'bc' have no special meanings here ('b' is for 'battle'). I just use random letters to group these. First graphic describes how a move script can start a move animation script. Spoiler:
The second graphic describes the startup-process of a battle. I omitted the lines from "c1_exec_bc_and_bx" to the other boxes because it got messy, instead I colored the boxes green. Spoiler:
The third graphic emphasizes that move scripts can be run by different subsystems (by a bc_ callback directly, or through a bs_ callback). Spoiler:
I omitted the addresses in most places, but you can look up these names in my database. (Or ask me) |
have you successfully made it in FireRed?Sorry I was just confused
|
Quote:
And this is awesome knizz! This means I can implement new moves without having to worry about how the AI would use it. Thanks man |
I've taken a quick glance at the different trainer ai scripts, and here's a short summary of what they do:
Code:
|
double post because this update deserves it
So, know how sometimes even a smart AI will fail to guess/recognise the opponent's ability? Well, turns out that is a bug. Long story short: ability usage history can be stored for each of the two/four participants in a battle. It is however only stored for the player: the routine won't do anything if you ask it to store it for the opponent. However, there's a problem: the big and scary function ability_something does magic with abilities, and sometimes it needs to receive the battle side as an argument. When it doesn't need that, the argument will be 0. But at the end of the routine, it will save the ability to history if it was used, and there's the problem: 0 means player's side, and the ability gets registered as if it were used by your poke. So, let's say, if the opponent sends out a poke with intimidate, then the AI will think it is actually your poke that has intimidate, until it gets to activate its real ability. This all was fixed in Emerald. Now, actually fixing this would mean tracking down every time ability_something is called with an empty argument for the battle side, and that's just too much work. Instead, I offer you guys this solution: I have rewritten the routine that stores the used ability into history: if it's asked to store your poke's ability into history, it will check if your poke actually does have that ability, and if it doesn't, then it won't store anything. Just insert the following routine at 0xC71D0: Code:
|
Quote:
|
Quote:
|
Quote:
Also I was wondering if they were preset strategies and I seem to have mistakenly thought that 7 was the best. Umm, what does nop mean in a case like this though? Would it just select moves randomly or something? |
Quote:
|
Quote:
That probably wasn't the best way to describe it though. :/ |
Quote:
Turns out A-trainer allows giving that unknown a max value of 0xFFFF, so turns out that's the only program that supports giving trainers a proper AI atm... Also I've just updated the two posts from last night. The AI scripts' descriptions now contain enough information, and the bugfixroutine should more or less work in double battles. |
Quote:
|
Quote:
|
Quote:
|
Quote:
|
Quote:
|
Quote:
Quote:
Quote:
|
The routine that determines if the AI will switch is located at 08039C84, with the actual thinking happening at 08039A80. I have no idea how it works.
The routine that determines if the AI will use an item is located at 0803A1F4. It will identify the type of item at 0803A198: Code:
Then, it will run checks based on the type of item - 1 (see the jump table at 0803A304). For example, it will use a full restore if the hp of the poke is less than 25% of its max hp. If anyone wants to analyse those routines further, please do. |
Quote:
|
Quote:
|
Script 31 isn't unused, it's likely used in the RSE poochyena/zigzagoon fight to make it flee if your HP is low.
|
Hmm. Unable to use my asm insertion program to insert it at that address, so I just looked for free space, copied down the code that it produced. (084B58224243D21820321278914203D0002806D10220F3E7034A12689269203211547047E43B0202F43F0202) and then pasted this over the information at that address, but it keeps freezing. Where exactly does the original code end?
Edit: I'm an idiot. Working as intended. Thanks so much! |
Sorry for this being a bit of a bump, but I noticed that one of the "trainer" AI scripts is that of the roaming/running Pokemon...does this mean that Pokemon such as Entei, Latios, etc (or really, anything) have an "AI value" as well that gets set to this? Does this only control its running behavior, or also the roaming behavior as well? This obviously isn't used for trainer battles, so I'm curious how this actually -is- applied in practice, potentially to create new roaming/fleeing encounters.
Also, are the values here the same as they would be in Emerald, minus the addresses? I know you mentioned Emerald having a bug fix, but other than that I would be able to use this at least as a reference? Thanks so much! |
| All times are GMT -8. The time now is 8:39 AM. |
![]()
© 2002 - 2018 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2016 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.
Acknowledgements
Use of PokéCommunity Assets
vB Optimise by DragonByte Technologies Ltd © 2023.