Dispos Enemy AI - DivineDragonFanClub/Lythos GitHub Wiki

Dispos Flags & Enums

AI Flags
public DisposData.AIFlags
{
	NotActivateByAttacked = 1,
	Dummy = 2,
	ZeroAttack = 4,
	Heal = 8,
	Break = 16,
	Chain = 32,
	EquipShortAfterLongRange = 64,
	MoveBreak = 128,
	EngageAttackOnce = 256
}
Flags
public DisposData.Flags
{
	Normal = 1;
	Hard = 2;
	Lunatic = 4;
	Create = 8;
	Leader = 16;
	NotMove = 32;
	Edge = 64;
	Pos = 128;
	Must = 256;
	Fix = 512;
	Guest = 1024;
	MaskSortie = 896;
	MaskDifficulty = 7;
}
Directions
public DisposData.Directions
{
	None = 0;
	Up = 1;         // ⇑
	UpperRight = 2; // ⇗
	Right = 3;      // ⇒
	LowerRight = 4; // ⇘
	Down = 5;       // ⇓
	LowerLeft = 6;  // ⇙
	Left = 7;       // ⇐
	UpperLeft = 8;  // ⇖
}
States - See Engage Attack Rampage
public DisposData.State
{
	Normal = 0;
	Rampage = 1;
	Keep = -1;
}

Enemy AI

AI for each enemy unit is determined both in dispos and by scripts. Fire Emblem Engage has a modular approach to AI, meaning the enemy AI consists of up to 4 components, as seen in dispos: Action, Mind, Attack, and Move.

image

Any AI sequence can be put into any of these fields, but usually Action determines when the unit "activates," and Mind, Attack, Move determines what the unit does. Usually, attack is battling or using staves, move is moving + waiting, and mind is other actions. What each of the AI sequences do is defined in AI.xml.

AI.xml

image

Each AI sequence is a list of commands. In the case of action commands (with code 3), the game will simply iterate though them in order and select the first action that can be performed. This is how each unit decides what to do each turn.

Active: Determines if the command is for active units, inactive units, or both. For actions, 0 is active, -1 is both, -2 is inactive.

Code: Determines which type of command it is. Actions have code 3, and are ususally of most interest to edit.

image

Mind: Determines which specific command it is. Further down is a table of each.

StrValue0 and StrValue1: Parameters for the command. Arguments can be passed directly, but values V_0, V_1, V_2, and V_3 are often used so that arguments can be passed from fields in dispos such as AI_AttackVal. Most commands don't use the parameters, and their purpose varies.

Trans: Unknown, but actions don't use them.

For instance, take "AI_AT_Attack" shown above, a very common AI sequence for regular enemies in the game. Action commands 41, 72, 0, 71, 74 are HE_MiddleLow, MI_GuardBattleScore, AT_Default, MI_Guard, MI_GuardNoMove respectively. Thus, each turn will have the following procedure to decide what this unit will do each turn once it's active:

First it's HE_MiddleLow. This means checking if it's appropriate to heal. If so, heal, otherwise move on to the next command which is MI_GuardBattleScore. This means checking if it's possible to chain guard and if it's smarter than attacking. If so, chain guard, otherwise move on to the next command, AT_Default. This one just checks if it's possible to attack an enemy. If not, move on to MI_Guard. Check if it's possible to chain guard an ally at all. If not, do nothing.

Note that the MI_GuardNoMove command in this example is only to be attempted if the unit is inactive due to Active="-2", and the final command with Code="0" just signifies the end of the sequence. Also, this sequence, "AI_AT_Attack", is used by a wide variety of units, most of which cannot chain guard.

Action commands

Here's what each Mind value means for Code="3". Keep in mind the descriptions may be inaccurate, as this is just my conclusions from staring at disassembly code for a couple of hours.

Name ID Description
AT_Default 0 Attack an enemy
AT_MiddleLow 1 Attack an enemy if m_Think is not AttackHigh
AT_Low 2 Attack an enemy if m_Think is not AttackHigh or AttackMiddle
AT_Hero 3 Attack the protag
AT_Person 4 Attack a specific Pid
AT_ExcludePerson 5 Attack an enemy other than a specific Pid
AT_ExcludeBand 6 Attack an enemy not in a specific group
AT_Job 7 Attack an enemy with a specific class
AT_JobNearestPosition 8 Attack the closest enemy with a specific class
AT_Force 9 Attack an enemy on a specific side
AT_PriorItem 10 Attack an enemy with a specific weapon
AT_CrossfireEnd 11 n/a
AT_Breath 12 Attack an enemy with a breath attack if m_Think is not AttackLongRange
AT_BreathMiddleLow 13 Attack an enemy with a breath attack if m_Think is not AttackLongRange or AttackHigh
AT_ExcludePerson2 14 Attack an enemy other than two specific Pids
RD_Heal 20 Heal an ally
RD_Warp 21 Warp an ally towards an enemy
RD_WarpFarZ 22 Warp an ally in the Z-direction
RD_Rescue 23 Rescue the most powerful ally
RD_MagicShield 24 Use reflect on allies
IR_Default 30 Use disruptive rod on an enemy
IR_HighMagic 31 Use disruptive rod on an enemy with high magic
IR_LowMagic 32 Use disruptive rod on an enemy with low magic
IR_Person 33 Use disruptive rod on a specific Pid
IR_ExcludePerson 34 Use disruptive rod on an enemy other than a specific Pid
IR_Weapon 35 Use disruptive rod on an enemy with a specific weapon type
IR_Frequency 36 Use disruptive rod on an enemy
HE_Default 40 Use healing item or move toward heal tile
HE_MiddleLow 41 Use healing item or move toward heal tile if m_Think is not AttackHigh
HE_NearingHero 42 Use healing item next to protag
EG_Attack 50 Use engage attack on an enemy
EG_Dance 51 Use dance engage attack on allies.

Within Engage Attack SID, the item's name in EquipIids must start with IID_女神の舞...
IID_女神の舞... must have its Kind 7 aka must be a staff.
IID_女神の舞... must have RangeTarget Flag enabled.
IID_女神の舞... must have its UseType 15.
EG_Vision 52 Create illusory doubles
EG_Pierce 53 Use engage attack on allies as if it pierces (like override)
EG_Bless 54 Use divine blessing on an ally
EG_BlessPerson 55 Use divine blessing on a specific Pid
EG_Wait 56 Use an enemy phase engage attack if hp >= 50%
EG_Summon 57 Use summon hero if hp >= 50%
EG_Overlap 58 Use AOE engage attack
MI_Talk 60 Talk to someone
MI_Treasure 61 Open a treasure box
MI_Village 62 Visit a house
MI_Escape 63 Escape the map
MI_EscapeSlow 64 Escape the map using less move
MI_BreakDown 65 Unknown
MI_Dance 66 Dance for an ally
MI_TerrainDestroy 68 Destroy some breakable terrain
MI_Torch 70 Extinguish a torch
MI_Guard 71 Chain guard next to an ally
MI_GuardBattleScore 72 Chain guard next to an ally if there's no good attack available
MI_GuardPerson 73 Chain guard next to a specific Pid
MI_GuardNoMove 74 Chain guard without moving if next to ally
MV_Return 80 Move toward own spawnpoint
MV_Idle 81 Wait or use healing item without moving
MV_AttackRange 82 Move to get an attackable enemy within range
MV_AttackRangeSide 83 MV_AttackRange, but with an unknown attackFlag
MV_AttackRangeExcludePerson 84 MV_AttackRange, but ignoring a specific Pid
MV_AttackRangeIgnore 85 MV_AttackRange, but with an unknown moveFlag
MV_WeakRange 86 MV_AttackRange, but with another unknown attackFlag
MV_WeakRangeSide 87 Combination of MV_AttackRangeSide and MV_WeakRange
MV_HealRange 88 Move to get a healable ally within range
MV_Hero 89 Move toward protag
MV_Person 90 Move toward a specific Pid
MV_Position 91 Move toward a pecific coordinate
MV_Force 92 Move toward a unit on a specific side
MV_ForceExcludePerson 93 MV_Force, but ignoring a specific Pid
MV_Treasure 94 Move toward closest treasure box
MV_Village 95 Move toward closest village
MV_Escape 96 Move toward escape
MV_NearestFriend 97 Move toward closest ally
MV_TerrainDestroy 98 Move toward closest breakable terrain
MV_Retreat 99 Move to the safest available spot
MV_BreakDown 100 Unknown
MV_Terrain 101 Move toward a specific Tid
MV_Rewarp 108 Rewarp toward an attackable enemy
MV_AttackRangeExcludePerson2 109 MV_AttackRange, but ignoring two specific Pids
CS_Battle 110 Attack an enemy with a battle command skill (like echo or advance)
CS_Overlap 111 Use Dragon Vein [Cavalry] on enemies
CS_OverlapNoEnemy 112 Use Dragon Vein [Cavalry] on enemies if none are attackable
CS_FullBullet 113 Use let fly on specific coordinate using a specific Iid
CS_Decoy 114 Use assign decoy on an ally if you can't kill all enemies nearby
CS_Enchant 115 Enchant allies with any item
CS_EnchantHeal 116 Enchant allies with a healing item
CS_Strategy 117 Use gambit command skill appropriately
CS_Trimasteries 118 Use combat art command skill
CS_Contract 119 Use contract on ally
CS_Yell 120 Use rally spectrum on allies if no enemies are attackable
CS_Gaze 121 Use piercing glare on a specific coordinate
VS_Plan -1 Unselectable. Set m_VsThink to AttackLow if dance engage attack is available
VS_EG_Engage -2 Engage
VS_EG_Attack -3 Use engage attack appropriately
VS_AT_MiddleLow -4 Attack an enemy if m_Think is not AttackHigh
VS_GodSkill -5 Use any sync/engage command skill appropriately
VS_MI_Dance -6 Dance for an ally
VS_MI_Guard -7 Chain guard next to an ally
VS_MI_FireCannon -8 Attack an enemy with an artillery
VS_MI_TerrainDestroy -9 Destroy some breakable terrain
VS_CS_Enchant -10 Enchant allies with any item
VS_CS_EnchantHeal -11 Enchant allies with a healing item
VS_CS_FullBullet -12 Use let fly on an enemy

Custom AI Example

			<Param Group="AI_AT_ALittle_Secret_AI" Active="" Code="" Mind="" StrValue0="" StrValue1="" Trans="" />
			<Param Group="" Active="0" Code="3" Mind="-3" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="-10" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="118" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="110" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="117" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="12" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="0" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="-8" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="-12" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="52" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="24" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="66" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="119" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="120" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="114" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="-5" StrValue0="1" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="-5" StrValue0="0" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="30" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="20" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="21" StrValue0="1" StrValue1="1" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="23" StrValue0="1" StrValue1="1" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="71" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="41" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="108" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="86" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="82" StrValue0="V_Max" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="3" Mind="88" StrValue0="V_Max" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="-2" Code="3" Mind="74" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />
			<Param Group="" Active="0" Code="0" Mind="0" StrValue0="V_Default" StrValue1="V_Default" Trans="-128" />

Lines within Details are from here but slightly edited. They're created when program randomizes & exports files. Don't use as it as a randomizer, it's old. Use Draconic Vibe Crystal: Runtime Randomizer + More instead.

Copy paste the lines into the AI section in Astra. Then, in a Chapter Dispos, have at least one AI Attack Name be AI_AT_ALittle_Secret_AI to try it out.

With this knowledge we can now design our own AI sequences, and possibly even cram as much functionality as possible into one. The sequence shown above will make units attempt to use engage attacks, command skills, regular attacks, artillery, dancing, enchanting, offensive staves, healing staves, warp, rescue, chain guarding, healing items, rewarp, and also takes care of how they will move if they don't do any of those things. Great as a general-purpose enemy AI, if you need that for some reason...

Credits

Thanks to Nifyr for writing most of this page!

⚠️ **GitHub.com Fallback** ⚠️