[FE7] The Official AI Documentation Thread

Yes. But it’s more complicated from that. Based on the code, it seems that each entry in that table(specified by AI 1) is a pointer to a table… with a real routine specified by AI 2. I think.
In other words

byte** AITable = new byte*[# of AI1]
AITable[0] = new byte[# of 1stAIData]
byte AIToExecute = AITable[AI1][AI2]

I think.

It’s not a jump table actually… the table points to 1-byte entries in-rom… it’s weird.

Found the jump table:
0x81D3678

Basically, the AI Bytes map to a table that, after some processing, tell which jump table element to use.

After I uncover the arguments and returns for these routines, the bulk of our research will be figuring out which jump table elements do what, I guess.

  • They all take &(1stAIData) as their parameter.
  • r0 = &1stAIData
  • r1 = location of branch
  • r2 = &AI’s Data
  • They all have no return value.

Calling it a day today, but before I go, dropping some links to annotated routines

(Edit: I removed and broke the links. Check later in the post for a rar of all deocs)

(@CT075, I think you should take a look at these.)

oh, that’s a find

not entirely sure what you want me to do other than go debug the actual table entries (ha)

does anyone have that old post where icecube made ai check its might properly

Moved to first post

6 Likes

Yeah! This helps a lot. I haven’t seen any unified-all-information-here about the AI bytes like this before.

@Arch can you make that post a wiki post pretty please?

Bada bam. Great stuff here from everybody!

I’ll be cheerleading from the sidelines.

Just quickly, if you follow the pointer trails based on the table that @Crazycolorz5 found, you’ll find the addresses that specify which characters these will be.

0x8B97A0C - character corresponding to 0x12 (Lucius/0x10)
0x8B97A34 - character corresponding to 0x13 (Raven/0x04)

Edit: Just wanted to confirm that changing these bytes does indeed work.

I imagine that there’s similar sorts of things for other AI bytes–might be worth checking out later.

1 Like

Uhm, I myself am confused as to how you got those offsets. Care to explain in a bit more detail?

I followed this to a pointer table, and went to the 0x12th pointer. I followed that pointer to 0x8B97A14, which has 8 bytes of something and then a pointer to 0x8B97A0C, which has the byte 0x10 (Raven) there. I did the same for the 0x13th pointer which ends in the byte 0x04 (Lucius) there, and the same again for the 0x07th pointer which ends up pointing to a byte that has 0x14 (Nino). I suspect that expanding & repointing the table and copying and pasting the relevant bits in the AI might allow us to create our own custom versions of these or, in the very least, have more of them. :smiley:

Update: 0x8B98908 is the corresponding table for the Movement AI bytes :D. Following this, if you head to the 0x0Bth (Farina talks to Hector) pointer it brings you to 0x8B97FDC. If you go along a little further there’s a 0x02 at 0x8B97FE0. Oh, where have we seen this offset before? Right…

3 Likes

Found where the locations are stored for the second AI bytes that make units move to specific locations.
So 0x13 as the second byte of AI should make units move towards 3,13 on the map.
Using the table at 0x8B98908 that @Agro posted for the second AI Bytes, the 13th pointer points to B98724, these are the first 16 bytes at B98724.
01 00 FF 00 00 00 00 00 49 A5 03 08 (1C 87 B9 08)

In the data above in brackets is a pointer leading to B9871C and at that location, if you look at the four bytes prior so at B98718, you see 03 0D 00 00. 03 0D translated from hex = 3,13; which is the location that units with 0x13 as their second AI byte move to. I’ve tested it and changed the 03 0D and the enemy then moves to the new location specified.

So to change the location units with 0x13 as their second AI byte move to, just edit the bytes at B98718.
And so on for the rest, so for 0x14(move to 18,13 on map), the 14th pointer in the table points to B987A0, and the data at that location contains a pointer to B98798 and at that location, four bytes prior so B98794, is 12 0D 00 00 which is the location 18,13. Hopefully that all makes sense. I’m going through now and noting the offsets of the locations so I’ll post those in a bit.

EDIT
actually it seems the locations aren’t all done in the same way. so I haven’t found them all yet. so far though
0x13 - B98718 (3,13)
0x14 - B98794 (18,13)
0x15 - B98810 (10,24)
0x16 - B9888C (8,2)

1 Like

Where/how did you find this?

1 Like

probably just by following pointers and changing random bytes until stuff happened

So theres these ones and I think I’ve got how the others ones work
0x13 - B98718 (3,13) Change 03 0D
0x14 - B98794 (18,13) Change 12 0D
0x15 - B98810 (10,24) Change 0A 18
0x16 - B9888C (8,2) Change 08 02
0x1D - B9869C (15,17) Change 0F 11

For the others. The bytes to edit are just at the offset the entrys in pointer table point to I think. I haven’t tested this yet though, but i think it should be right

Just follow the pointer and edit the bytes at the location
0x17 - B97578 (6,2)
0C 06 FF 02 - Change 06 02
0x19 - B974B8 (6,9)
0C 06 FF 09 - Change 06 09
0x1A - B974F8 (6,5)
0C 06 FF 05 - Change 06 05
0x1E - B97538 (5,2)
0C 05 FF 02 - Change 05 02

1 Like

Oh – I see. There are 0x13 Aggresion AI pointers. then after that a pointer to 08B98908 is written 3 times… then 3 pointers to 08B98994 O.o… what?

… I’m gonna take a closer look at the asm that uses this…

Okay, I want to clear up what I’ve been looking at(mostly because this is still kinda complicated even with annotations) so here goes.

  1. We load 0x8B989F0, which is a pointer to…
  2. We dereference it, getting 0x08B98994
  3. We find the 1stAI-th entry in that pointer table and dereference if.
  4. We take the 1stAIData byte times 0x10 and add that to what we just got.
  5. (some processing, but usually) The first byte there is taken (e.g. for AI = 0x00, 0x00, we get 05)
  6. At the table at 0x81D3678, we use that index and jump to it. (More complicated stuff if the number is >=1B)

Okay, so the tables we get (that are 0x10 bytes long) by following the 1st and 2nd AI bytes look something like this (Annotating as I go)

05 64 FF 00 00 00 00 00 00 00 00 00 00 00 00 00
AI = 0x00, 0x00

The 0th byte is the jump table index to use.
The 1st byte is something chance based, I think – [some routine generates a random multiple of 0x64 and subtracts one.][1] If the chance is unfulfilled then it … branches and does something.
The 2nd byte is written to RAM(at 0x0203A96A), so it might be important?
The 3rd byte is read by 08037890
[1]:https://dl.dropboxusercontent.com/u/92273434/FE%20Hacking%2C%20Public%20Files/AI%20Analysis/08000E30

1 Like

I just went to this address and saw that there was a pointer to 0x8B989F0. I assumed that the pointer to the movement AI table was somewhere nearby and just searched for other pointers (there aren’t many in that area) and followed the pointers through