Skip to content

Instantly share code, notes, and snippets.

@aEnigmatic
Last active March 23, 2024 15:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aEnigmatic/8c5211f04ef065e318eb5b74a5151ee6 to your computer and use it in GitHub Desktop.
Save aEnigmatic/8c5211f04ef065e318eb5b74a5151ee6 to your computer and use it in GitHub Desktop.
How to read the FFBE AIs

How to read the AIs

A unit (i.e. enemy / boss) has x-y actions per turn, for each it will have to "decide" what to do.
For each, start from the top until you find the first condition that resolves to true.

I tried making everything as self-explanatory as possible, but it's still complicated enough.
The output is a python-like pseudocode but that was my choice for easy reading.
(Input is just a set of "actions" with "conditions")

Actions

Action Description
wait No (gameplay) action (but set variables), wasting an action (confirmation needed)
endTurn End the turn immediately
attack(target) Standard attack
useSkill(target, x) Use skill #x from given skillset
useRandomSkill(target) Use random skill from given skillset
Targetting Info Description
self Self-explanatory
random Random unit respecting provoke / camouflage effects
highest [STAT] Unit with the highest value of [STAT] but also respecting provoke / camouflage effects

Conditions

Game states

Condition Description
isTurn(x)
isTurnMod(x) Turn number is a multiple of x. CAREFUL: if the boss has first-strike, it's multiples of (x+1)
timesExecuted() < x timesExecuted() refers to the number of times the current condition / action has already been (successfully) executed
once() Shorthand for timesExecuted() < 1, i.e. not yet, thus only evaluating successfully once.

Unit states

Condition Description
[unit].HP < or > x (percentual HP)
[unit].is(something)
[unit].sufferedDamageLastTurn(element, damage_type)
[unit].usedLastTurn(x) x = [attack, guard, ability, magic, esper, limitburst, item]
[unit].hitByLastTurn(x) see above
[unit].healedByLastTurn(x) see above
[unit].supportedWithLastTurn(x) see above
[unit].hasStatus(x)
[unit].hasDebuff(x)
[unit].hasBuff(x)
[unit].hasReflect()
[unit].totalDamage() > x

[unit]

self refers to the boss itself.
unit('x:ally:y') refers to allies of the boss, likewise
unit('x:enemy:y') refers to its enemies, i.e. your party.

Note
unit('1:ally:any') might be the same as self (confirmation needed).

Variables

Types

Type Information Properties
Permanent flags True / False Set to x, start as False
Volatile flags True / False Set to x, start as and reset to False at the end of the turn
Timers Number Increase by 1 at the end of turn, starts at 1 (confirmation needed), resets to 1 (confirmation needed)
Counters Number Increase by x
Unknown True / False (?) Might not actually exist?
Expansion? True / False (?) Second set of variables, possibly for more volatile flags (confirmation needed)

Naming schemes

Names are easier to remember and distinguish than numbers (which is how the game refers to them).
They are 5 characters long so they align perfectly.

Type Scheme Names
Permanent flags food honey, ramen, sushi, bacon, steak, salad, fries, sugar, pizza, pasta
Volatile flags fruit & vegetable apple, berry, peach, olive, mango, lemon, grape, melon, guava, gourd
Timers aquatic life manta, whale, squid, shark, guppy
Counters colors green, white, black, mauve, azure
Unknown terrestrial life otter, tiger, mouse, goose, horse
Expansion? var_x var_31, var_32, ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment