On the other hand, I still do feel that there are some (largely unnecessary but nice-to-know things regardless) things that Arch either skimmed over or missed completely. I’m going to say right now that none of the following things are necessary for events; the tutorial and the EA language doc included with the EA release should be enough, given enough creativity.
First of all, that FE7 code template provided with the EA release? Here’s a slightly more complete one.
Now, this may not seem a whole lot different at first glance. “Sure, Cam, you changed some names around and added a little thing at the top, how is it more complete?” Well, the default included template is already mostly done for you. All I did was add a few things (well, actually only one) to make things easier on you.
At the top of the file, you’d notice a few lines I added that says
#define MAP_OFFS 0x_____ … EventPointerTable(0x__,MAP_OFFS)What does that do? Well, it’s supposed to repoint the map for the chapter for you without any kerjiggering in nightmare.
The next thing you may notice is, as I pointed out before, that I changed the label names. It’s largely an aesthetic change, but it illustrates an important point in programming. You can label anything whatever you want. If you want, you can create a macro and call it
#define TunaFish(unit,class,level) LOU1 unit class Level(level,ally,false)if you wanted. Hell, in my template, you could change MiscEvents to “IHaveALovelyBunchOfCoconutsCollection” and EA wouldn’t complain (as long as you updated the pointer array to match).However, it’s important that you label your code properly so that people who are trying to read your code can have some clue of what it’s supposed to do. Imagine, for example, that you saw this (this is one of my old events):
what: GOTO NowLoadingTurn FADI 0x05 ASMC 0x7A8B9 LOMA 0x02 [13,12] FADU 0x05 WarpIn(Eli,17,15) LOU1 NewLyn ENUN TEX1 0x836 MUS1 0x0042 MORETEXT 0x837 REMA TEX6 0x01 [07,05] 0x0838 _ASM0x42 0x83181 ENUT 0x69 ENDAThat is confusing and almost unreadable. The label name doesn’t tell you anything about what it does, and the number of raw hex or ASM codes doesn’t help anything.
Now, here’s the same code, but I fixed some things up:
BeginMapThree: // Stall and generate the 'now loading' message. GOTO NowLoadingTurn FADI 0x05 // Clear units and load next map ClearAll // ASMC 0x7A8B9 LOMA 0x02 [13,12] FADU 0x05 // Load player units WarpIn(Eli,17,15) LOU1 NewLyn ENUN TEX1 0x836 MUS1 TogetherWeRide //0x0042 MORETEXT 0x837 REMA ScrollText(0x838) // Activate permanent event ID 0x69 and begin map three ENUT 0x69 ENDAShould be slightly less scary, but even that could be improved. At the moment, all I did was replace some ASM codes with corresponding macros. I also added in comments to make it more obvious what is supposed to do what. This makes it much easier for both myself (when trying to fix something if it doesn’t work) and others (if they’re trying to read my source for some reason or other).
Going back to pointers for a second (I know, I’m rambling, just try to follow along), remember this?
Chapter: POIN TurnEvents POIN CharacterEvents POIN LocationEvents POIN MiscEvents POIN BallistaData BallistaData POIN Bad Bad Bad Bad POIN Good Good Good Good POIN OpeningEvent EndingEventThis is important. This is the ‘header’ (for lack of a better term) of your chapter. This set of pointers tells your game where all the data in your chapter is. I suppose you could write it like this:
Chapter: POIN TunaFish Foo Generic Not Rain Rain Units Units2 Units3 Units4 Other Other2 Other3 Other4 Scene POIN OtherSceneThat should work perfectly well, assuming you get your labels all correct. But again, that’s difficult to read. If you were to look at that string, how would one know which label points to the turn based events? Rather, it’s separated the way it is so it’s much simpler for the reader to figure out which label (and therefore, which in-game pointer) is used for what. Let’s go over each one individually:
TurnEvents, CharacterEvents, LocationEvents and MiscEvents have all been covered fairly thoroughly in Arch’s event tutorial. As long as you make sure that they aren’t pointed to the same thing, it should cause no problems.
BallistaData is almost self-explanatory. There are two pointers there, and for a reason. Technically, the labels should read
POIN BallistaDataEliwood BallistaDataHectorBut, since most of us only deal with one of the two lords’ modes (Lyn mode is counted as Eliwood Normal), they point to the same thing for convenience.
The same goes for the Good and Bad labels. If you disassemble a chapter, you’d see that the labels read
POIN EnemyUnitsENM EnemyUnitsEHM EnemyUnitsHNM EnemyUnitsHHM POIN AllyUnitsENM AllyUnitsEHM AllyUnitsHNM AllyUnitsHHMBut again, they point to the same thing because precious few of us deal with HM vs. NM, or Eliwood vs. Hector modes.
OpeningEvent is the event that is loaded if the prep screen is active, and it has no purpose otherwise. A note, if the prep screen is active, it also must end with an ENDB command.
EndingEvent is loaded when condition IDs 0x02 or 0x03 are triggered (boss death and seize, respectively). All the other victory conditions (Rout, Escape, etc.) must be called manually (I don’t know exactly how but I know there’s a macro for it).
Another thing you may notice myself and some others doing in their source is the usage of a little code called ‘GOTO’, or its close cousin ‘JUMP’. What those do is throw the event over to another set of commands, which are written elsewhere. There is a vital difference between the two (besides that GOTO doesn’t exist in FE6). GOTO sends you to a set of events, and returns to the original thread once it reaches an ENDA. JUMP does not.
Foo: SomeEvents // This is the original event thread GOTO MoreEvents // Control returns here MESSAGE This statement is reached JUMP EvenMoreEvents // Everything after this is never reached. WARNING This statement is not GameOver ENDA … MoreEvents: // events ENDA // Go back to Foo. … EvenMoreEvents: // events ENDA // The event is now over.I know that it seems pointless and unnecessary. “But Cam, why would you bother with GOTO if you can just write the extra events into the original thread?” For most occasions, there’s no reason not to. However, if you happen to call a certain string of codes several times, then suddenly it is a lot more space-efficient to use GOTO. For example:
As you can see, I managed to save space in my ROM by making it so that, instead of having to use the same set of codes (“now loading”) three times, I only had to use it once and replaced them with a GOTO. The use of this command is largely conditional, there are only a handful of situations where it saves enough space to really matter. However, it’s a good habit to get into, if only because it makes things so much easier to read (oh I know what that does I don’t have to try and follow the string of codes again).
Finally, since I know this is dragging on, I want to make a note about the usage of macros. Macros and definitions make your code much more humanly readable.
UNIT 0x03 0x02 0x00 0x9 [7,4] [4,6] [0x01,0x0,0x0,0x0] [0x0,0x0,0x0,0x0]is a lot scarier (and harder to decipher) than
UNIT Lyn_t LynLord 0x00 Level(3,Ally,False) [7,4] [4,6] [IronSword] NoAIThis (scary-looking) string of ASMC codes:
ASMC 0x7D711; STAL 0x3C; ASMC 0x7D7B5; STAL 0x3C; ASMC 0x6CCB9; ASMC 0x7D771can be compressed to a single
QuintessenceEffectwith the EAstdlib. It makes it so much easier to read your script and to find problems that it’s suddenly not a giant mystery/question mark every time something goes wrong.
In conclusion, I want to thank Nintenlord for making such an awesome tool (making events with a hex editor is… well, never again), Hextator/Zahlman/anyone else who helped me with my noobish regular programming skills (that carried over back to events and inspired me to write this), Arch for writing such a boss event tutorial that makes it so I don’t have to explain everything (and for being a boss), everyone else who has helped me with this hobby and you, the reader, for spending this much time dealing with me and my rambling.
Thank you, and goodnight.
Edited by Camtech, 05 January 2012 - 04:24 PM.