[FE8] Event Conditionals Guide

There are a few mechanics involved with FE8 events that are necessary to understand how conditionals work.

1. Labels

Although Event Assembler has its own version of labels, what we’re interested in here is the version used in the events themselves. There are two event codes to know here, and they’re very simple; LABEL and GOTO.
LABEL is very important, despite doing nothing on its own. Putting LABEL labelNumber where labelNumber is any integer will mark that position in your event. Again, this does nothing on its own, but that’s where its friend GOTO comes in.
GOTO can be used to jump to any LABEL you set. Just by using GOTO labelNumber you’ll jump to the first instance of LABEL with the same labelNumber occurring after the start of the current event. On its own, this may sound pretty useless; always jumping to a point. Well, what if we could GOTO only if specific conditions are met? Hold that thought, there’s one more mechanic we need to go over.

2. Checks

Checks are event codes that can get different information about the state of the game and return them for use in events. There’s a whole lot of these, so let’s go over what all of them are and what they do.

All of these return their result in memory slot 0xC!

No Arguments:

CHECK_MODE
Checks current game mode; 0x1 for prologue, 0x2 for Eirika, 0x3 for Ephraim
CHECK_HARD
Checks for hard mode; returns true (1) if hard mode, false (0) if not
CHECK_TURNS
Checks turn count; returns current turn number
CHECK_ENEMIES
Checks number of enemies; returns total number of enemies on the map
CHECK_OTHERS
Checks number of NPCs; returns total number of NPCs on the map
CHECK_SKIRMISH
Checks if you're in a skirmish or dungeon; returns true or false
CHECK_TUTORIAL
Checks if you're in easy mode; returns true or false
CHECK_MONEY
Checks your gold balance; returns amount of gold you have
CHECK_EVENTID
Checks the current event's ID; returns the ID associated with the currently running event
CHECK_CHAPTER_NUMBER
Checks chapter number; returns number associated with current map
CHECK_ACTIVE
Checks active character; returns active character's ID

Arguments: Something you can always do with the checks that want a character ID is use 0xFFFF to use the active character instead of a specific character.

CHECK_EVENTID eventID
takes any event ID; returns true or false based on whether or not the given ID is set
CHECK_EVBIT
takes any evbit; returns true or false based on whether or not the given evbit is set
CHECK_EXISTS character
check if unit exists; returns true or false
CHECK_ALIVE character
checks if unit is alive; returns true or false
CHECK_DEPLOYED character
checks deployment status; returns true or false
CHECK_ACTIVEID character
checks if active character matches given character; returns true or false
CHECK_ALLEGIANCE character
checks unit's allegiance; returns allegiance
CHECK_COORDS character
checks unit's current position; returns coordinates
CHECK_CLASS character
checks unit's current class; returns class ID
CHECK_LUCK character
checks unit's luck stat; returns luck stat
CHECK_AT [x,y]
checks at given coordinates for a unit; returns character ID if there is a character at coordinates
CHECK_INAREA character [x1,y1] [x2,y2]
checks within a rectangular area for a unit, top left corner is (x1,y1) and bottom right corner is (x2,y2); returns true or false based on whether the given character is in the given area

Once again, these seem pretty useless on their own. What’s the point of getting this information in a memory slot? What can we do with it? That’s where conditionals come in.

3. Conditionals

Conditionals are special versions of GOTO that only GOTO a LABEL if certain conditions are met based on values in memory slots (you can use SVAL to put any value you want in a memory slot!). Once again there’s a number of these, but the vast majority of the time you’ll only need 2 of them: BEQ and BNE.
BranchType labelNumber memorySlot memorySlot is the format for all conditional codes; the first argument is the label if conditions are met, and then you specify two memory slots to compare the values in. Let’s go over an example of how you would use it in practice.

Let’s say we’ve got a village, but we only want to get an item from it if a certain character (let’s say, Joshua) is visiting. Our event could look something like this:

CHECK_ACTIVEID 0x20
BNE 1 0 0xC
TEXTSTART
TEXTSHOW 0x903
TEXTEND
REMA
CALL $591F40
SMOV 0x3 0xC
GIVEITEMTO 0xFFFF
GOTO 2
LABEL 1
TEXTSTART
TEXTSHOW 0x904
TEXTEND
LABEL 2
EVBIT_T 0x7
ENDA

Well, that’s a bit confusing. Let’s trim it down a little, make it a bit easier to understand, and throw parts into some definitions and macros:

CHECK_ACTIVE
SVAL 1 Joshua
BNE 1 1 0xC
Text(JoshuaHouse)
GiveItem(Shamshir,0xFFFF)
GOTO 2
LABEL 1
Text(GenericHouse)
LABEL 2
NoFade
ENDA

You’ll notice we changed up the beginning a bit, from one code to two. CHECK_ACTIVEID is a self-contained version of the first three codes that returns true or false to memory slot 0xC instead of doing a GOTO directly. Either way works, as there’s any number of ways to do a conditional for one situation!

If we break down our conditional further, we can simplify it to this template:

CHECK_information
SVAL 1 comparison
BNE 1 1 0xC
//successful result
GOTO 2
LABEL 1
//unsuccessful result
LABEL 2
NoFade
ENDA

Of course, you don’t always have to check for the values in each memory slot to be either the same or different. There’s a number of different checks you can use:

BEQ labelNumber memorySlot memorySlot
*B*ranch to label if values are *EQ*ual
BNE labelNumber memorySlot memorySlot
*B*ranch to label if values are *N*ot *E*qual
BGE labelNumber memorySlot memorySlot
*B*ranch to label if first slot value is *G*reater than or *E*qual to second slot value
BGT labelNumber memorySlot memorySlot
*B*ranch to label if first slot value is *G*reater *T*han second slot value
BLE labelNumber memorySlot memorySlot
*B*ranch to label if first slot value is *L*ess than or *E*qual to second slot value
BLT labelNumber memorySlot memorySlot
*B*ranch to label if first slot value is *L*ess *T*han second slot value

Something to keep in mind with your conditionals is that memory slot 0 always contains 0, and you can’t set it to any other value. You can use this to your advantage, as we did in our initial example event, to compare your true/false check results against 0 instead of storing a value to compare against.

(Thanks to @2WB for proofreading this for me!)

18 Likes

Question: Can I make a GOTO command go to whatever destination is in memory slot C?

So for an event which is different for every unit:

CHECK_ACTIVE
GOTO (ValueStoredAtMemorySlotC)

LABEL 0x01 //Erika
//Do stuff
ENDA
LABEL 0x02 //Seth
//Do stuff
ENDA
//Ect…

This would save a lot of time over having to manually check for every single unit with conditional statements.

There is not a way to GOTO a label ID stored in a memory slot. Event codes that can take a unit ID as a parameter, as well as a handful of others, generally have 3 special cases for -1, -2, and -3. Using -3 will have it read from memory slot 2, but GOTO, LABEL, and branch codes cannot read from a memory slot in this way. As all values from 0-0xFFFF are valid label IDs, there is not a special case for them.

2 Likes

Can it be possible to make a hack for that? Like reserve the FFFF for C slot result ?