[FE7] The Official AI Documentation Thread

You know how in FE12 certain enemies won’t move until another specific “trigger” enemy attacks? Well, it looks like the GBA FE’s already have built-in support for similar behavior. (It only gets used a few times in FE6)

AI1 0x0D
Move/attack if the unit’s leader has foe in range.
Switches AI1/A12 to 0x00/0x00 (aggressive) when leader is defeated.
The unit must be auto-leveled in order for the unit’s leader data to be loaded.

To create FE12-style enemy traps:
Leader/trigger enemy: AI1 = 0x00, AI2 = 0x03 (attack when foe in range)
Followers: AI1 = 0x0D, AI2 = 0x03 (make sure leader is set and unit is auto-leveled)

Strangely, FE6 mostly uses this AI with an already aggressive leader:
Leader/trigger enemy: AI1 = 0x00, AI2 = 0x00 (aggressive)
Followers: AI1 = 0x0D, AI2 = 0x00
So there might be more to this AI? Or maybe IntSys is just weird.

1 Like

What else is new?

01 00 FF 00 00 00 00 00 BD A5 03 08 00 00 00 00 @Execute this routine. Do nothing if Support#7 is 00 or player unit
Dropbox - AI Byte 1 Commands.txt - Simplify your life
From [the Unified FE Hacking Dropbox][1]

This loads the 0x38 byte of the unit data. For player units, this is Support #7. Am I to assume it’s the leader for enemies?
[1]:Unified FE Hacking Doc Dropbox

Yep, byte 0x38 = enemy leader.

Are we sure these are right? Where’s the post that found this out? From the AI codes I’m looking at, they seem to be backwards.

AI1PointerTable(0x00, SeekWallsAI)
AI2PointerTable(0x00, Pursue)

Bad:
UNIT Batta Brigand 0x00 Level(1,Enemy,False) [10,7] [10,7] [IronAxe] [0x00, 0x0 ,0x0, 0x0]
UNIT

SeekWallsAI:
GetEnemyInCoefMoveRange(OneMove)
ConditionalGoto(0, LT, 1)
GetEnemyInCoefMoveRange(ThreeMove)
ConditionalGoto(0, LT, 2)
SeekWalls
LoopAI
Label(1)
DefaultAction
LoopAI
Label(2)
MoveTowardsOpponents
LoopAI

OneMove:
defMovementCoefficient(0x1)

ThreeMove:
defMovementCoefficient(0x3)

Pursue:
MoveTowardsOpponents
LoopAI

Help guys it’s too readable.

2 Likes

AI assembler! That’s awesome.

AI2 0x13, 0x14, 0x15, 0x16, 0x1D
Yeah, you’re right. There’s clearly a change AI command in there, but it doesn’t get used.

Here’s how it’s supposed to work:
If unit is within a rectangular area, switch AI1/AI2 to [0x00,0x00]
Otherwise, move unit towards a specific point (which should be located within the rectangle)

(X1, Y1) = Upper-left corner of rectangle
(X2, Y2) = Lower-right corner of rectangle
Routine 0803A548 checks whether the unit is within the rectangular area.
Currently, the parameters are formatted like this: X1 Y1 00 00 X2 Y2 00 00
But they should be formatted like this: X1 Y1 X2 Y2
Due to this error, units with this AI will just crowd around the interior point.

AI2 0x17, 0x19, 0x1A, 0x1E
These units won’t move back. After stepping on the target point, this AI essentially turns into AI1 0x00.

1 Like

rectangular area AI? far out, I have some comprehensive re-eventing to do now

Taking a look at the AI Commands for AI2 0x8:

AI2 0x08 - 08B975B8 - ???
01 00 FF 00 00 00 00 00 D9 A4 03 08 00 00 00 00 @Seen in unreached commands in AI 0x17?
00 00 FF 01 00 00 00 00 72 A9 03 02 00 00 00 00 @If 0<Memory, Goto 1
03 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 @Goto 0
1B 00 FF 01 00 00 00 00 00 00 00 00 00 00 00 00 @Label 1
01 00 FF 00 00 00 00 00 F1 A3 03 08 44 3B 1D 08 @ Parameters = FF 01 00 00
01 00 FF 00 00 00 00 00 C1 A0 03 08 48 3B 1D 08 @Get Foe in Expanded Range
00 00 FF 01 00 00 00 00 72 A9 03 02 00 00 00 00 @If foe in expanded range, goto 1
0E 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 @Nop
03 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 @Goto 0

Had a hunch based on the 0x32 there, confirmed experimentally.

Is there a way to make the enemy target more units?
I know AI1 0x0A makes the enemy attack the character 0x03, but can you make them attack other units?
Like, 0x0A = Target 0x03, 0x1A = Target 0x04, 0x1B = Target 0x05 and so on.

I don’t know is this is doable, but is there something to force the enemy to attack certain units?
–But I suppose this haven’t been figured out yet, because I remember someone wanted to create the Provoke skill based on AI and he couldn’t.–

The actual code for AI 0xA is
AI 0xA - 08B97ABC - Only attack character 0x03 (tutorial Lyn) (B97AC0)
04 64 FF 00 03 00 00 00 00 00 00 00 00 00 00 00 @??? Data = 03 = Lyn_t
00 05 FF 00 03 00 00 00 72 A9 03 02 00 00 00 00 @If memory != 0x3, goto top
05 64 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 @Default behaviour if can’t find Lyn_t?
03 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 @Goto top

So to expand it just add more 04-type commands. AI Assembly. Blah. Stuff. Sorry I’d explain more but I have to leave so this is a rushed post.

A post was split to a new topic: AI Help Needed

ok I think it’s better to just ask because my own tests are giving me something weird. For making the custom AI, is the order [A1,A2,A3,A4] or is it actually [A3,A4,A1,A2] like the first post was suggesting?

I think they are read in the latter order but actually written in the first

If you’re asking about when assembling events, the traditional [AI1, AI2, AI3, AI3] order still works, but I’m now recommending the format which I defined for the newest event assembler of [AI1, AI2] AI3 AI4.

If you’re talking about making your own AI, then it doesn’t matter; you specify whether it’s AI1 or AI2 by overwriting different pointer tables.

Ah thank you both, using the old event assembler so it will be a1 - a4 then.

Reposting from the FE8 AI thread:

This routine is super important for AI execution.
Routine 08034E50
Writes command data to 0203A97C

Parameters:
r0 = move to x
r1 = move to y
r2 = command
r3 = target unit deployment number (escape x)
sp+0x00 = inventory slot to use or steal (0xFF = ballista)(escape y)
sp+0x04 = snag/wall x-coordinate (escape direction)
sp+0x08 = snag/wall y-coordinate

Commands:
00 = none. 01 = attack. 02 = escape (remove unit from map). 03 = steal.
04 = pillage village. 05 = staff. 06 = item. 07 = dance/play. 08 = talk.
Note: dance/play doesn’t work.

0203A97C
0x00 = command
0x01 = enemy deployment number
0x02 = move to x
0x03 = move to y
0x04 = (skipped)
0x05 = (skipped)
0x06 = target unit deployment number (escape x)
0x07 = inventory slot to use or steal (0xFF = ballista)(escape y)
0x08 = snag/wall x-coordinate (escape direction)
0x09 = snag/wall y-coordinate
0x0A = 01 (indicates a command was written)

Not 100% sure on talk command bytes 0x06-0x09 yet.
Looks like the deployment numbers of the talkers and maybe the talk event id.

5 Likes

Oh my god this is amazing I’m going to put this to good use.

Edit: Can you find a corresponding routine in FE8?

Edit2: I don’t have time this week, but I want to mess with this asap. So, next week. Not being able to/not putting enough effort into find this routine was a sticking point with me not meddling too much with AI anymore.

It’s so lit tho

1 Like