Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2019-02-23 17:27:50

Anonymous
Member
Registered: 2019-02-23
Post 1/14

Pokemon Red/Blue (Modifying Trainer AIs)

I am currently working on a difficulty hack of Pokemon Red. I am able to successfully increase pokemon parties and increase trainer pokemon DV's but I don't know how to modify the trainer AI by making them use a Potion, Super Potion, Hyper Potion, Full Restore etc. I am working with the disassembly and I read the file called trainer_ai.asm but it has not really helped as much. Can somebody please tell me what from what offset to what offset are all the AI changes done. Here is the trainer_ai.asm file

TrainerAI:
and a
ld a, [wIsInBattle]
dec a
ret z ; if not a trainer, we're done here
ld a, [wLinkState]
cp LINK_STATE_BATTLING
ret z
ld a, [wTrainerClass] ; what trainer class is this?
dec a
ld c, a
ld b, 0
ld hl, TrainerAIPointers
add hl, bc
add hl, bc
add hl, bc
ld a, [wAICount]
and a
ret z ; if no AI uses left, we're done here
inc hl
inc a
jr nz, .getpointer
dec hl
ld a, [hli]
ld [wAICount], a
.getpointer
ld a, [hli]
ld h, [hl]
ld l, a
call Random
jp hl

TrainerAIPointers:
; one entry per trainer class
; first byte, number of times (per Pokémon) it can occur
; next two bytes, pointer to AI subroutine for trainer class
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,JugglerAI ; juggler_x
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,GenericAI
dbw 3,JugglerAI ; juggler
dbw 3,GenericAI
dbw 3,GenericAI
dbw 2,BlackbeltAI ; blackbelt
dbw 3,GenericAI
dbw 3,GenericAI
dbw 1,GenericAI ; chief
dbw 3,GenericAI
dbw 1,GiovanniAI ; giovanni
dbw 3,GenericAI
dbw 2,CooltrainerMAI ; cooltrainerm
dbw 1,CooltrainerFAI ; cooltrainerf
dbw 2,BrunoAI ; bruno
dbw 5,BrockAI ; brock
dbw 1,MistyAI ; misty
dbw 1,LtSurgeAI ; surge
dbw 1,ErikaAI ; erika
dbw 2,KogaAI ; koga
dbw 2,BlaineAI ; blaine
dbw 1,SabrinaAI ; sabrina
dbw 3,GenericAI
dbw 1,Sony2AI ; sony2
dbw 1,Sony3AI ; sony3
dbw 2,LoreleiAI ; lorelei
dbw 3,GenericAI
dbw 2,AgathaAI ; agatha
dbw 1,LanceAI ; lance

JugglerAI:
cp $40
ret nc
jp AISwitchIfEnoughMons

BlackbeltAI:
cp $20
ret nc
jp AIUseXAttack

GiovanniAI:
cp $40
ret nc
jp AIUseGuardSpec

CooltrainerMAI:
cp $40
ret nc
jp AIUseXAttack

CooltrainerFAI:
cp $40
ld a, $A
call AICheckIfHPBelowFraction
jp c, AIUseHyperPotion
ld a, 5
call AICheckIfHPBelowFraction
ret nc
jp AISwitchIfEnoughMons

BrockAI:
; if his active monster has a status condition, use a full heal
ld a, [wEnemyMonStatus]
and a
ret z
jp AIUseFullHeal

MistyAI:
cp $40
ret nc
jp AIUseXDefend

LtSurgeAI:
cp $40
ret nc
jp AIUseXSpeed

ErikaAI:
cp $80
ret nc
ld a, $A
call AICheckIfHPBelowFraction
ret nc
jp AIUseSuperPotion

KogaAI:
cp $40
ret nc
jp AIUseXAttack

BlaineAI:
cp $40
ret nc
jp AIUseSuperPotion

SabrinaAI:
cp $40
ret nc
ld a, $A
call AICheckIfHPBelowFraction
ret nc
jp AIUseHyperPotion

Sony2AI:
cp $20
ret nc
ld a, 5
call AICheckIfHPBelowFraction
ret nc
jp AIUsePotion

Sony3AI:
cp $20
ret nc
ld a, 5
call AICheckIfHPBelowFraction
ret nc
jp AIUseFullRestore

LoreleiAI:
cp $80
ret nc
ld a, 5
call AICheckIfHPBelowFraction
ret nc
jp AIUseSuperPotion

BrunoAI:
cp $40
ret nc
jp AIUseXDefend

AgathaAI:
cp $14
jp c, AISwitchIfEnoughMons
cp $80
ret nc
ld a, 4
call AICheckIfHPBelowFraction
ret nc
jp AIUseSuperPotion

LanceAI:
cp $80
ret nc
ld a, 5
call AICheckIfHPBelowFraction
ret nc
jp AIUseHyperPotion

Offline

#2 2019-03-28 20:15:37

jojobear13
New member
Registered: 2019-03-28
Post 1/3

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Let's take a look at Koga and go through each part.

dbw 2,KogaAI ; koga

dbw sets aside a Word's worth of Bytes of Data (a word is equal to 2 bytes). What follows is "2" (the first byte) and "KogaAI" (a defined function name that is the second byte). What this part is going to establish is that the function "KogaAI" can only be ran "2" times during a battle.

Now let's jump down to the KogaAI function. and go through it line-by-line.

KogaAI:
This is the name of the function.

cp $40
By the time you reach this line, "call Random" from TrainerAI has already put a random number between $00 and $FF (which is 0 to 255 in decimal) into register "a". What cp $40 does is take the value in register "a" and subtracts $40 from it. If the result is zero, the "z" flag is set to 1. If the result is negative or causes an overflow, the carry or "c" flag is set to 1.

ret nc
This means "return if not-carry". You are telling the processor to check the state of the carry flag. If the carry flag is not set (meaning it's zero),  then leave this function now and return back. In the context of KogaAI, we want to kick back out if the value generated in "a" is greater than $40.

jp AIUseXAttack
Naturally it follows that if the number in "a" was less than or equal to $40 (or 0 to 64 in decimal) then you will execute this line. What this does is directly JumP you directly to the function titled AIUseXAttack. As you might assume, this makes the AI trainer you are facing enact the effect of using the X-Attack item.

Basically, Koga's AI gives him a 65 out of 256 chance to use an X-Attack on any given turn granted that he can only use the item 2 times.

In the spirit of the Gen 1 quiz-master, look at Blaine's AI. Can you tell why he does stupid things like use a super potion when at full health?

Offline

#3 2019-03-29 23:45:20

Anonymous
Member
Registered: 2019-02-23
Post 4/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

I get what you're talking about but I want to know the correct method on how to do the AI changes on a hex editor. I'm not sure from what offset to what offset are all the AI changes done. I'm a bit stuck, can you please post the right method on how to do the AI changes on a hex editor.

Offline

#4 2019-03-30 03:47:09

jojobear13
New member
Registered: 2019-03-28
Post 3/3

Re: Pokemon Red/Blue (Modifying Trainer AIs)

That's more work than a forum post can sustain. What you are essentially wanting to do is directly reprogram the machine code. Get an op-code guide for the gameboy, learn how to code in assembly for z80-style processors, then start trying to track down where specific op-codes for trainer ai occur using BGB emulator's debugger.

Offline

#5 2019-03-30 04:25:56

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 3,599/3,620

Re: Pokemon Red/Blue (Modifying Trainer AIs)

why do you want to do it in a hex editor?


Current Projects:
Check them out on Github

Offline

#6 2019-03-30 16:22:04

Anonymous
Member
Registered: 2019-02-23
Post 5/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Mateo wrote:

why do you want to do it in a hex editor?

Because it is easier to modify the actual gb rom. Messing with the disassembly is only playing around with the pokered.gbc file and not really teaches you how to modify the rom by messing around with the code.

Offline

#7 2019-03-30 19:07:00

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 3,602/3,620

Re: Pokemon Red/Blue (Modifying Trainer AIs)

I feel like you misunderstand how coding works. Either that, or perhaps you fundamentally misunderstand what the disassemblies are and how they work. But you will have a much better time editing code (such as AI functions) by editing the code directly and recompiling than you would poking around in a hex editor.

Last edited by Mateo (2019-03-30 20:33:21)


Current Projects:
Check them out on Github

Offline

#8 2019-03-30 22:42:35

Anonymous
Member
Registered: 2019-02-23
Post 6/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Mateo wrote:

I feel like you misunderstand how coding works. Either that, or perhaps you fundamentally misunderstand what the disassemblies are and how they work. But you will have a much better time editing code (such as AI functions) by editing the code directly and recompiling than you would poking around in a hex editor.

What part of the trainer_ai.asm file could I edit in order to change the original generic AI to some type of gym leader or elite four AI. I've asked SinisterHoodedFigure the creator of Pokemon Blue Kaizo for help on how to modify trainer AI in the hex editor. He said, "the pokered disassembly may have clues to where to find those AIs, though you will have to play around with it.


AIRC, there is a specific trainer list order, each with 3 offsets. Many normal non-item, no switching offsets are common hex values. Gym leaders and specific trainers have unique hex values. Changing 01 to a bigger number for the number of items value, can increase it.

The ones I used most were the cooltrainer female (my favorite-Low health=hyperPotionORSwap), Brock (full heals), Champion (full restores), Agatha (random switch, low health super potions), Lorelei(frequent super potions at low levels, And Lance (frequent hyper potions)

Don’t use Blaine or any of the x item AI, they work, but hurts more than helps. Play around with the AIs to see what you want."

He gave me a hint that you should increase 01 to a bigger number but I'm not sure on what offset should I increase the hex values in order to modify the AIs.

I went on DataCrystal for the entire ROM map of Pokemon Red but it didn't give me the offsets on where the AI changes are done.

Offline

#9 2019-03-31 01:42:28

h0tp3ngu1n
Member
Registered: 2018-09-11
Post 8/11

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Since you already have the disassembly, you could get the offsets by converting the relevant part of the disassembly back into machine code and then doing a hex search (you can do this by hand... you only need like 5 or 6 bytes).

e.g. The first two lines in trainerAI.asm say:
ld a, $a
ld hl, wBuffer
That translates to 3E 0A / 21 E9CE (remember, little endian...). And a hex search tells me that this particular string of bytes shows up exactly once in the Pokémon Red Version ROM, at offset $39719. So that must be the offset you're looking for.

(No idea if what I just said is correct. But that's what I'd do, anyway.)

Last edited by h0tp3ngu1n (2019-03-31 10:43:26)

Offline

#10 2019-03-31 15:23:49

Anonymous
Member
Registered: 2019-02-23
Post 7/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

h0tp3ngu1n wrote:

Since you already have the disassembly, you could get the offsets by converting the relevant part of the disassembly back into machine code and then doing a hex search (you can do this by hand... you only need like 5 or 6 bytes).

e.g. The first two lines in trainerAI.asm say:
ld a, $a
ld hl, wBuffer
That translates to 3E 0A / 21 E9CE (remember, little endian...). And a hex search tells me that this particular string of bytes shows up exactly once in the Pokémon Red Version ROM, at offset $39719. So that must be the offset you're looking for.

(No idea if what I just said is correct. But that's what I'd do, anyway.)

That was not the right offset but how do you convert parts of the disassembly into hex values. Can you please tell me because I want to be more familiar in using the disassembly.

Offline

#11 2019-03-31 18:03:02

Rangi
Member
Registered: 2016-05-09
Post 885/897

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Anonymous wrote:
h0tp3ngu1n wrote:

Since you already have the disassembly, you could get the offsets by converting the relevant part of the disassembly back into machine code and then doing a hex search (you can do this by hand... you only need like 5 or 6 bytes).

e.g. The first two lines in trainerAI.asm say:
ld a, $a
ld hl, wBuffer
That translates to 3E 0A / 21 E9CE (remember, little endian...). And a hex search tells me that this particular string of bytes shows up exactly once in the Pokémon Red Version ROM, at offset $39719. So that must be the offset you're looking for.

(No idea if what I just said is correct. But that's what I'd do, anyway.)

That was not the right offset but how do you convert parts of the disassembly into hex values. Can you please tell me because I want to be more familiar in using the disassembly.

The point of the disassembly is that you don't need to think about hex values or offsets, because the assembler handles that for you. Hacking a ROM in a hex editor is like trying to write an app by directly editing the .exe file.

Because it is easier to modify the actual gb rom. Messing with the disassembly is only playing around with the pokered.gbc file and not really teaches you how to modify the rom by messing around with the code.

None of this is true. It is literally the opposite of true; you are "playing around with the pokered.gbc file" in the hex editor, and the disassembly is "messing around with the code". "ld a, $a; ld hl, wBuffer" is code; "3E 0A 21 E9 CE" is not.

...However, it is worth knowing how assembly language turns into the raw values you see in the .gbc file. A summary: the GBZ80 CPU has roughly 250 operations, each with their own numeric opcode. Some of them are simple: the "inc a" operation, which adds 1 to the register A, has the opcode $3C. Others take a single byte as an argument: the "add a, v" operation, which adds the 8-bit value v to the register A, has the opcode $C6 (so "add a, 42" would be "C6 2A"). And some others take two-byte arguments in little-endian order: the "call x" operation, which calls the subroutine at address x, has the opcode $CD (so "call $4028" would be "CD 28 40"). (There are also a bunch of bit-manipulating operations that have the prefix $CB and then their opcode: "swap b", which swaps the nybbles of the register B, would be "CB 30".)

There are many tables and listings of the GBZ80 assembly opcodes online. Some of them leave out the hex opcode values because they're mostly irrelevant when writing assembly yourself, but this table includes them.

You can even compare the disassembly with the ROM it produces side-by-side. Let's say you get pokered set up correctly and it builds a copy of pokered.gbc. Then you can look at the pokered.sym file it produced, which lists the locations of every label in the ROM. (A huge advantage assembly has over hex editing: "repointing" does not exist, because you write code using labels, and it's the assembler's job to locate them and turn them into pointers.)

For example, there's the line "0E:6634 KogaAI". So the KogaAI label is at address $6634 in bank $E. That translates to offset $3A634. Now compare the assembly code after that label:

KogaAI:
    cp $40
    ret nc
    jp AIUseXAttack

with the hex values at that offset:

FE 40
D0
C3 F2 67

They match! (And if you look at the .sym file again, it has "0E:67F2 AIUseXAttack", which also matches those values.)

But again: please don't do this. It's fun to understand the asm-to-rom process, but there's no reason to be hex-editing an English Pokémon Red ROM any more.


Pokémon Polished Crystal (src): v2.2.0
Pokémon Red★/Blue★: Space World Edition (src): 2018-08-19
Polished Map (src): pokecrystal/pokered map, tileset and palette editor: v4.3.0

Offline

#12 2019-03-31 18:05:06

Rangi
Member
Registered: 2016-05-09
Post 886/897

Re: Pokemon Red/Blue (Modifying Trainer AIs)

jojobear13 wrote:

dbw 2,KogaAI ; koga

dbw sets aside a Word's worth of Bytes of Data (a word is equal to 2 bytes). What follows is "2" (the first byte) and "KogaAI" (a defined function name that is the second byte).

FYI, that's not quite right. Here's the definition of "dbw" in macros/asm_macros.asm:

; macro for putting a byte then a word
dbw: MACRO
    db \1
    dw \2
ENDM

So it puts the byte 2, and then the little-endian two-byte word KogaAI, for three bytes worth of data total.


Pokémon Polished Crystal (src): v2.2.0
Pokémon Red★/Blue★: Space World Edition (src): 2018-08-19
Polished Map (src): pokecrystal/pokered map, tileset and palette editor: v4.3.0

Offline

#13 2019-04-01 02:42:56

Anonymous
Member
Registered: 2019-02-23
Post 8/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Rangi wrote:
Anonymous wrote:
h0tp3ngu1n wrote:

Since you already have the disassembly, you could get the offsets by converting the relevant part of the disassembly back into machine code and then doing a hex search (you can do this by hand... you only need like 5 or 6 bytes).

e.g. The first two lines in trainerAI.asm say:
ld a, $a
ld hl, wBuffer
That translates to 3E 0A / 21 E9CE (remember, little endian...). And a hex search tells me that this particular string of bytes shows up exactly once in the Pokémon Red Version ROM, at offset $39719. So that must be the offset you're looking for.

(No idea if what I just said is correct. But that's what I'd do, anyway.)

That was not the right offset but how do you convert parts of the disassembly into hex values. Can you please tell me because I want to be more familiar in using the disassembly.

The point of the disassembly is that you don't need to think about hex values or offsets, because the assembler handles that for you. Hacking a ROM in a hex editor is like trying to write an app by directly editing the .exe file.

Because it is easier to modify the actual gb rom. Messing with the disassembly is only playing around with the pokered.gbc file and not really teaches you how to modify the rom by messing around with the code.

None of this is true. It is literally the opposite of true; you are "playing around with the pokered.gbc file" in the hex editor, and the disassembly is "messing around with the code". "ld a, $a; ld hl, wBuffer" is code; "3E 0A 21 E9 CE" is not.

...However, it is worth knowing how assembly language turns into the raw values you see in the .gbc file. A summary: the GBZ80 CPU has roughly 250 operations, each with their own numeric opcode. Some of them are simple: the "inc a" operation, which adds 1 to the register A, has the opcode $3C. Others take a single byte as an argument: the "add a, v" operation, which adds the 8-bit value v to the register A, has the opcode $C6 (so "add a, 42" would be "C6 2A"). And some others take two-byte arguments in little-endian order: the "call x" operation, which calls the subroutine at address x, has the opcode $CD (so "call $4028" would be "CD 28 40"). (There are also a bunch of bit-manipulating operations that have the prefix $CB and then their opcode: "swap b", which swaps the nybbles of the register B, would be "CB 30".)

There are many tables and listings of the GBZ80 assembly opcodes online. Some of them leave out the hex opcode values because they're mostly irrelevant when writing assembly yourself, but this table includes them.

You can even compare the disassembly with the ROM it produces side-by-side. Let's say you get pokered set up correctly and it builds a copy of pokered.gbc. Then you can look at the pokered.sym file it produced, which lists the locations of every label in the ROM. (A huge advantage assembly has over hex editing: "repointing" does not exist, because you write code using labels, and it's the assembler's job to locate them and turn them into pointers.)

For example, there's the line "0E:6634 KogaAI". So the KogaAI label is at address $6634 in bank $E. That translates to offset $3A634. Now compare the assembly code after that label:

KogaAI:
    cp $40
    ret nc
    jp AIUseXAttack

with the hex values at that offset:

FE 40
D0
C3 F2 67

They match! (And if you look at the .sym file again, it has "0E:67F2 AIUseXAttack", which also matches those values.)

But again: please don't do this. It's fun to understand the asm-to-rom process, but there's no reason to be hex-editing an English Pokémon Red ROM any more.

Hey Rangi, I was reading the pokered.sym file and I found "BrunoData 0E:63A9". What would be the easy way to convert the address to an offset because I want to have an easier time editing the pokered disassembly.

Offline

#14 2019-04-01 04:05:59

Rangi
Member
Registered: 2016-05-09
Post 890/897

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Anonymous wrote:

Hey Rangi, I was reading the pokered.sym file and I found "BrunoData 0E:63A9". What would be the easy way to convert the address to an offset because I want to have an easier time editing the pokered disassembly.

offset = (bank - 1) × $4000 + address, or just offset = address if bank is $00


Pokémon Polished Crystal (src): v2.2.0
Pokémon Red★/Blue★: Space World Edition (src): 2018-08-19
Polished Map (src): pokecrystal/pokered map, tileset and palette editor: v4.3.0

Offline

#15 2019-04-01 15:02:58

Anonymous
Member
Registered: 2019-02-23
Post 9/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Rangi wrote:
Anonymous wrote:

Hey Rangi, I was reading the pokered.sym file and I found "BrunoData 0E:63A9". What would be the easy way to convert the address to an offset because I want to have an easier time editing the pokered disassembly.

offset = (bank - 1) × $4000 + address, or just offset = address if bank is $00

Using the offset formula you gave me I got $23B7. Did I do it correctly.

Offline

#16 2019-04-06 17:03:06

h0tp3ngu1n
Member
Registered: 2018-09-11
Post 9/11

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Is that formula correct? It seems that according to that formula, bank 1 addresses have the same offsets as bank 0 addresses?

Offline

#17 2019-04-07 17:04:29

Danny-E 33
Administrator
Registered: 2012-06-09
Post 1,133/1,135

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Anonymous wrote:
Rangi wrote:
Anonymous wrote:

Hey Rangi, I was reading the pokered.sym file and I found "BrunoData 0E:63A9". What would be the easy way to convert the address to an offset because I want to have an easier time editing the pokered disassembly.

offset = (bank - 1) × $4000 + address, or just offset = address if bank is $00

Using the offset formula you gave me I got $23B7. Did I do it correctly.

No, you made an error somewhere.
Using this formula, bank=$e and address=$63a9

So:
offset = ($e - 1) × $4000 + $63a9
offset = $d × $4000 + $63a9
offset = $34000 + $63a9
offset = $3a3a9

h0tp3ngu1n wrote:

Is that formula correct? It seems that according to that formula, bank 1 addresses have the same offsets as bank 0 addresses?

The formula is correct. As Rangi stated:

Rangi wrote:

offset = (bank - 1) × $4000 + address, or just offset = address if bank is $00

However, I prefer this formula:
offset = bank × $4000 + address % $4000

It works the same for all banks.

To make the conversation even more confusing, I'd argue we are using 'offset' and 'address' backwards.
$63a9 describes the offset of the data relative to the start of the bank that it's in.
Whereas $3a3a9 is the absolute address of the data in the rom.

Offline

#18 2019-05-05 16:58:13

Anonymous
Member
Registered: 2019-02-23
Post 11/14

Re: Pokemon Red/Blue (Modifying Trainer AIs)

Hey Danny thanks for helping me with converting addresses to offsets but I was wondering if you could help me with this bug that I am facing. While doing tests of my rom hack of Pokemon Red when the player enters Celadon Game Corner the screen turns black and the game crashes. Do you think this might be an issue with the script of Celadon Game Corner or an issue with the header. If you don't know what I'm talking about then you can watch this video to see what the bug looks like: https://www.youtube.com/watch?v=c3TjiQ3woqk

I hope you know the right solution in order to fix the bug.

Offline

Board footer

Powered by FluxBB