FE8’s event engine works a little bit differently than FE7’s; the first thing is how its event codes are structured.
Whereas in FE7 and FE6 event codes are just a byte long, FE8’s event codes are two bytes long. The upper half of the byte is the event code ID, just like in the other games, but the lower half has a couple new things.
Let’s take the ASMC code; in FE8, its event code is 0x0D40.Let’s split it up like so:
0D 4 0
The 0D is ASMC’s Event Code ID; this determines what routine is run when this code is executed.
The 4 tells the game how much space the code and its parameters take up. FE8 maintains a block of data in memory dedicated to the event engine. The location of this block is not fixed, but 0x38 bytes from the start of this block is a pointer to the current event code. When the code is finished running (note - some commands like STAL will run repeatedly until certain conditions are met), the game will add 42 bytes to this pointer. FE7’s Event codes have to manually include this step in their own routines, a rather unwieldy process.
*Note that this part of the event code must always be a multiple of 2 - this keeps all of the event codes word-aligned, which is very important!
Finally, the 0 in our ASMC code is a kind of internal parameter - many event codes will read this number and do different things based on its value. For instance, there exists a 0xD41 code, labeled _ASMC2 by the Event Assembler; _ASMC2 differs from ASMC in that it checks the state of a bit in a halfword just after the current event pointer in memory. If the fourth bit is set, it will not execute the ASM in its parameter.
Most event codes don’t read this last digit so it will always be zero for them, while others have up to 0xF variants based on the value of this digit.
Event codes are read by the routine at $0800CECE; here the game loads the event code ID of the event code being processed (0x0D for ASMC and _ASMC2) and uses it as an index to one of two tables of pointers to their associated routines - if the event code ID is below 0x80 it indexes the table at $8591B28. If the ID is 0x80 or above, it is subtracted by 0x80 and indexes the table at $8591C98. In between these two tables are some unknown pointers and other data that I don’t know what it does.
Every routine for event codes always returns a value for r0, from 1 to 6; this tells the event engine what to do after executing the event. It’s how codes like STAL execute over and over until their time has expired; I haven’t documented exactly what each return value does though.
For some more (rough) examples of event codes, read this partial list of event codes that appear in within chapters.