After some more testing I realised that the units with 0x21/0x22 will only move if the character they’re set to follow is outside of their attacking range… Silly me, I guess?
Yeah, 0x0D-0x11 and 0x21/0x22 should both be the same in that aspect - the difference is what the unit does once it has the target inside its range. (I should have made that clearer in the original description)
Also, I encountered something a bit strange…
I gave a bunch of enemies 0x22 AI and assigned an enemy target, but on some turns a few units wouldn’t move towards their target. Luckily, it looks like you can avoid this issue by having the enemy to be followed defined before the followers in the chapter enemy data. (And I guess it makes sense for the leader to move before the followers anyways)
Oh crap, @Gryz, you got the 100th post!
In celebration of the 100th post milestone, here’s some new AI info:
AI 2 0x00 (B972F8)
1200FF00 00000000 00000000 00000000 : 0300FF00 00000000 00000000 00000000
AI 2 0x01 (B97398)
1200FF00 00000000 F270B908 00000000 : 0300FF00 00000000 00000000 00000000
AI 2 0x02 (B973B8)
1200FF00 00000000 F470B908 00000000 : 0300FF00 00000000 00000000 00000000
AI 2 0x00 is the standard move towards enemies AI. The pointers in 0x01 and 0x02 both dereference to zeroes. But if they point to a character ID or a list of characters (like AA 00 BB 00 CC 00 00 00) you can prevent the unit from moving towards those characters.
So by combining this “do not move towards character” behavior with “do not attack character” from AI 1, you can have the unit completely ignore a character. This can be quite handy for actively-moving recruitable enemies. If the enemy is using AI 2 0x03 (attack units in range) you are fine with just using AI 1 = “do not attack character” since AI 2 0x03 will already prevent the enemy from moving if not attacking.
I figured this out by looking at how the AI is used in FE6. AI 2 0x01 prevents units from moving towards Clarine (used by Rutger and chapter 4 enemies) and 0x02 prevents units from moving towards Lalum/Elphin (used by Douglas). Both are used in conjunction with an AI 1 setting that prevents those characters from being attacked.
I’m still doubtful that AI1 is Aggression and AI 2 is movement… I still think it’s some kind of primary/secondary system – especially since in my custom AI, I took the AI in AI2 and transplanted that to AI1. Maybe the way the game is natively organized is with aggression and movement though?
I agree with your primary-secondary AI idea.
AI1 = 00 + AI2 = 00 (aggressive enemy)
AI1: Action (attack, steal, staff), unit is allowed to move
AI2: If no action performed, move towards enemies
AI1 = 00 + AI2 = 03 (attack units in range)
AI1: Action, unit is allowed to move
AI2: If no action, do NOT move
AI1 = 03 + AI2 = 03 (stand still)
AI1: Action, unit is NOT allowed to move
AI2: If no action, do NOT move
This is consistent with the strange behavior you get with 03/00
AI1 = 03 + AI2 = 00 (not used by ingame enemies)
AI1: Action, unit is NOT allowed to move
AI2: If no action, move towards enemies
Example: 03/00 enemy merc with an iron sword will only attack if a player unit is adjacent at the start of the enemy phase. If no adjacent units, the merc will move towards player units but will not attack even if the merc moves next to a player unit.
Also, the forum gave me this message…
Let others join the conversation
This topic is clearly important to you – you’ve posted more than 20% of the replies here.
Are you sure you’re providing adequate time for other people to share their points of view, too?
I think I should stop posting in this topic.
Haha wow Discourse, that sounds like an anti-klok filter if I ever heard of one.
Gryz is monopolizing the AI thread! How unjust!
How targeting relates to multiple weapons, multiple targets, positioning, and ties:
For each weapon in inventory (top to bottom)
For each unit in range (deployment order)
Determine attack position
If TP >= highest TP seen so far, set this weapon-target option as highest.
Attack using highest TP option.
In event of TP tie, inventory order and deployment order are the tiebreakers. Select weapon-target option with lower weapon in inventory then unit further down in deployment list.
X attack position: 0203A3F0 + 0x10
Y attack position: 0203A3F0 + 0x11
Here are the two remaining TP modifying functions:
08039094: TP bonus for each allied unit in a 3 space radius around attack position. The attacker will receive a bonus from itself if its pre-attack position is inside the bonus area. 1 space away = 3 TP, 2 spaces away = 2 TP, 3 spaces away = 1 TP
1 2 1 1 2 3 2 1 1 2 3 3 2 1 1 2 3 2 1 1 2 1 1
The gap in the outer layer is due to a bug…
FD 01 00 00 (If allied unit at X-3, Y+1 give a TP bonus of 0)
This should be:
FF FE 01 00 (If allied unit at X-1, Y-2 give a TP bonus of 1)
Multiply bonus TP by TP_Modifier[0x02]. Cap total bonus to 10 TP.
080391E4: TP penalty for attack position being inside enemy range. For enemy range, use only the strongest usable weapon in inventory. TP penalty from each enemy = (attack power with strongest weapon) / 2. Add up penalties then divide total by 8.
Lyn with 8 strength and 5 mt iron sword: (8 + 5)/2 = 6
Sain with 13 strength, 6 mt javelin, and 10 mt steel lance: (13 + 10)/2 = 11
If attack position is only in Lyn’s range: TP penalty = 6/8 = 0
If attack position is only in Sain’s range (steel lance): TP penalty = 11/8 = 1
If attack position is in both Lyn’s and Sain’s range: TP penalty = (6+11)/8 = 2
Multiply penalty TP by TP_Modifier[0x06]. Cap total penalty to 20 TP.
This function reads from 0202E3F4 (points to row pointers at 020302E0) which is used during the enemy/other phase to map the (highest attack) / 2 values.
omg, my rampaging dragon without changing factions constantly can finally come true
The wiki post has been updated. Also, here’s some more AI codes:
Normally, units with healing staves only heal allies who are in recovery mode (determined by target’s AI3 byte). This AI causes the staff-user to heal allies with HP <= 50% regardless of recovery mode status.
Makes the unit alternate between AI1 0x0E behavior (explained above) and “action without moving”.
On “action without moving” turns, unit goes back to using the recovery mode of targets to determine whether to use a healing staff.
AI2 0x07 is identical to AI2 0x06 except it changes AI2 to 0x01 when foe enters expanded range.
AI2 0x09 = random movement
Hey, it looks like the AI list that comes with the CUE modules was right about this one. Burning RN’s will change where the unit moves. Believe it or not, this AI is actually used in FE6, but only in fog-of-war maps where it will be less obvious.
Correction in staff priority
Staff priority is not: status staff > healing staff
If unit has multiple usable staves, use the staff with the highest weapon rank. If multiple staves share the highest rank, use the staff that is lowest in inventory.
This explains why I saw a clear hierarchy with Heal-Mend-Recover, but inventory order mattered when carrying multiple status staves. I change Heal to A rank and it gets used instead of Recover and Berserk.
This is literally the most useful thing I have seen in a week. I can put this to such good use.
I believe you’re right here. I had the code for that, but there was a complicated jump in the middle that does who-knows what. But I can certainly see this being the case. My bad for not seeing that initially.
I just realized that I never posted where a unit’s recovery mode status is stored…
Byte 0x0A of unit data in RAM:
0x00 = recovery mode OFF
0x01 = recovery mode ON
There’s a chapter array at 1D3A60 that controls the AI’s ability to use Door Keys, Lockpicks, and Antitoxins.
Bit 01 = Enable Door Key in chapter. Bit 02 = Enable Lockpick in chapter. Bit 04 = Enable Antitoxin in chapter.
All FE7 chapters allow the AI to use Lockpicks and Antitoxins.
Chapters that prohibit AI from using Door Keys: 6, 17, 23x, 27 Jerme, 32x.
How exactly do these items get used? Please don’t ask me that. It’s complex and messy. Well, here is my current theory based on what I have observed and tested so far…
Door Key, Lockpick(1), Antitoxin conditions:
- Primary AI (AI1) fails. Generally, this happens when the unit has no target for attack, steal, staff. AI1 0x06 always fails.
- Secondary AI (AI2) fails or AI2 = 0x04 (brigand AI) or AI2 = 0x05 (thief AI). AI2 0x00 fails when the unit has no available path to foes due to walls/terrain. AI2 0x03 always fails.
- AI1 cannot be 0x03, 0x04, 0x05 (action without movement) and AI4 cannot be 0x20.
- Item cannot be disabled by the chapter array.
Door Key: Move towards doors and open.
Lockpick(1): Move towards doors/chests and open (requires STEAL ability).
Antitoxin: If poisoned, retreat and cure poison.
If unit has multiple of these items that can be used, priority is given to the lowest in inventory.
Then if AI2 = 0x04 (brigand AI) or 0x05 (thief AI) and none of the above items were used:
Chest Key (1-use): Move towards chests and open.
Lockpick(2): Move towards CHESTS (not doors) and open (requires STEAL ability).
Note: the chapter’s item bans do not apply to the Lockpick here.
Usage priority to the top Lockpick/Chest Key in inventory.
The Chest Key with 5-uses cannot be used by the AI.
Note that there are 2 opportunities to use Lockpicks
Lockpick(1): Can open both doors and chests, but can be blocked by the item ban.
Lockpick(2): Requires brigand/thief AI, can only open chests, and is unaffected by the item ban.
So, a thief carrying a Lockpick in a chapter with Lockpicks disabled = a thief that will only open chests and will ignore all doors.
A thief with Door Key + Chest Key will be absolutely determined to use the Door Key before opening any chests. This is due to the Door Key check always occurring before the Chest Key check.
Why did I say Lockpick AI requires the steal ability?
Class/char ability 0x08 (Lockpick): Determines whether to gray out Lockpick in inventory and if the player units can use it. For AI-controlled units, the game mistakenly checks class/char ability 0x04 (steal) for Lockpick functionality. This means enemy/NPC Assassins cannot use Lockpicks by default.
If enemies aren’t using Door Keys at all, check the chapter’s item ban list. If you want attack-in-range enemies to hold/drop Door Keys without using them, you will need to disable Door Keys.
Door Keys with common AI:
Enemies with “aggressive AI” (00/00) should never use Door Keys unless they are put in a locked room away from the player units.
Enemies with “attack-in-range AI” (00/03) will actually leave their positions and move towards doors if Door Keys aren’t disabled for the chapter.
Enemies with “stand still AI” (03/03) should never use Door Keys regardless of the item settings for chapter.
Enemies with “thief AI” (06/05) and carrying a combo of Door Keys + Chest Keys will seek to use Door Keys before using Chest Keys.
FE7 Door Key, Lockpick, Antitoxin AI Editor
Enable item for AI
0x01 Door Key
0x03 Door Key, Lockpick
0x05 Door Key, Antitoxin
0x06 Lockpick, Antitoxin
0x07 Door Key, Lockpick, Antitoxin
I’ll get to it when I retake my interest in AI… I actually think I documented the code somewhere, though. Or at least, I know which branch to look at.
Some notes from my investigation of keys and stuff.
At 081D3BDC: Table containing routines for AI using Door Keys, Lockpicks, Antitoxins
69 00 00 00 A9 BA 03 08 // Door Key 6A 00 00 00 41 BB 03 08 // Lockpick 6E 00 00 00 29 BC 03 08 // Antitoxin
0803B9E4 cmp r5, r0
r5 = unit’s item, r0 = item value from above table (0x69, 0x6A, 0x6E)
The Door Key, Lockpick, Antitoxin routines read 0203A8EC+0x80 which contains the item usability byte from the 081D3A60 chapter array.
If none of the above items were used and unit has thief/brigand AI:
08036ACE cmp r0, #0x68 // Check for Chest Key
08036AD8 cmp r0, #0x6A // Check for Lockpick
AI Command 0x10 (08037DD0) used in AI2 0x04 (brigand AI) and AI2 0x05 (thief AI)
bl 0803BA18 --> bl 0803B9C4 --> Check for Door Key, Lockpick, Antitoxin
bl 0803710C --> bl 08036A8C --> Check for Chest Key and Lockpick
Bug that checks for steal ability (0x04) instead of Lockpick ability (0x08) for AI-controlled units:
0803BB96 mov r4, #0x4 // First Lockpick check (Door Key, Lockpick, Antitoxin)
08036AE8 mov r0, #0x4 // Second Lockpick check (thief/brigand AI: Chest Key, Lockpick)
I stumbled upon something else regarding byte 0x0A of unit struct in RAM.
0x08 = Escape mode ON
I then took a quick peek at AI command 0x17 (08038030) in AI2 0x0C (unit escapes). As I suspected, it turns on escape mode.
Oh. Look at what is just above the Door Key, Lockpick, Antitoxin table:
081D3B74 : AI Staff Routines
4A 00 00 00 51 AC 03 08 // Heal 4B 00 00 00 51 AC 03 08 // Mend 4C 00 00 00 51 AC 03 08 // Recover 4D 00 00 00 C9 AD 03 08 // Physic 4E 00 00 00 99 AF 03 08 // Fortify 53 00 00 00 A5 B0 03 08 // Warp 54 00 00 00 C9 AD 03 08 // Rescue 4F 00 00 00 FD B1 03 08 // Restore 50 00 00 00 ED B3 03 08 // Silence 51 00 00 00 79 B5 03 08 // Sleep 52 00 00 00 79 B5 03 08 // Berserk 58 00 00 00 FD B6 03 08 // Barrier
Heal, Mend and Recover share conditions/routines (makes sense)
Sleep and Berserk share routines (both require target to be equipped with a weapon)
Physic and Rescue share routines. AI will use Rescue on allies in recovery mode. NPC units are allowed to use Rescue on player units (which could be detrimental rather than helpful).
Restore removes status changes from allies, including the buffs from dancer rings.
Restore has a bug: the unit can use Restore on itself to remove poison or dancer buffs (sleep, silence, berserk prevent staff use). During battle animation, the self-targeting unit appears on both sides of the screen.
Barrier targets in-range ally with lowest resistance (base res + any ongoing res boost from a previous Pure Water or Barrier). Unfortunately, this routine also has a self-target bug. The unit will use Barrier on itself if unit has the lowest resistance among all in-range allies (or if there are no allies).
I noticed that setting AI to [03,03,XX,00] or [03,03,XX,20] will prevent the self-targeting problem of Restore/Barrier. However, these staves have limited use if the user can’t move to allies.
Don’t get too excited about Warp just yet. I couldn’t get an enemy to use it. There is some sort of routine at that address, but it might be incomplete or bugged. Actually, if I give Warp the conditions of Heal/Mend/Recover it works but it just sends the target to coordinates [0,0] (even if staff range doesn’t go that far)
So… Just a quick question.
How would I go about implementing these AI routines into the game? Are the specific AI combinations already in the game by default?
Sorry if this seems very obvious. I just can’t seem to figure out how this thread is organized.
We haven’t done too much with this yet; I’m still muddling with some ideas with putting together more documentation on this, but currently, we only have knowledge of what some of the AI codes do… Expect more over like, winter break when I have more time, I guess?