Introduction and Prerequisites
Hello everyone. Today I'm going to teach you how to make World Map Events based on my own knowledge and research of working with World Map Events. To start off, I must state a slight disclaimer, that this tutorial will require you to have some assumed knowledge as well as a few hacking utilities.
-Arch's Really Long Event Tutorial
This is where most of the "assumed knowledge" can be found. If you haven't read this tutorial yet, and/or don't know how to make events/don't know how to use Nintenlord's event assembler, then I highly recommend you read this tutorial first. This tutorial could more or less be a sub section of Arch's, so likewise it is good to be familiar with the main thing first. To re-explain the concepts introduced in his tutorial (i.e. event IDs) would be redundant.
-Nintenlord's Event Assembler
This is the main utility we'll be using. You can find it in Nintenlord's utilities in the "ROM Hacking Resources" section of the forum.
Vital for text editing. Well, not completely but in my experience it is by far the easiest to use for said purpose. If you want to use the Parser or the Anti-Huffman patch (the one that's not applied automatically by FEditor) then be my guest, you're only hurting yourself.
-notepad (or some other .txt writing equivalent)
If you don't have one of these....I really don't know what to say...other than google is your friend.
-Emulator and FE7 ROM
If you can't find these then I don't know why you're reading this tutorial. Emulators can be found in one of Nintenlord's threads in "ROM Hacking Resources." ROMs...well you're on your own for that one. If you post a ROM or ask for one, I will ban you. Well...I wish I could. But rest assured, a mod probably will.
Critical reasoning skills are vital for ROM hacking and really any kind of computer programming.
Explanation of Structure
To start off, I want to state that World Map Events are completely linear. Because there are no sections in these events, the only sections in this tutorial will be: how to start a world map event, how to end a world map event, and the different functions you can use within world map events.
What Goes At the Top
Like any event file, you're gonna wanna include a code at the top that tells which pointer in the pointer table to overwrite, as well as a code to write the data. Also, if you're using any macros, you're going to want to include the files for that as well.
FE7 World Map Events Tutorial
1 reply to this topic
Posted 15 January 2011 - 10:39 PM
Again, for including Nintenlord's standard definitions and macros. Don't forget your own definitions file!
You need to overwrite the pointer to the current prologue (aka world map) event data you're wanting to assemble for. 0xC9CDA8 is the pointer table. You can find which byte to enter in the ?? by either checking using the FE7 World Map Event References NMM, (conveniently the only NMM created by me ) or you can use this:
Prologue Table Notes (Click Here To Hide/Show Text)
Starting the Event
To start the world map data, you simply use this set of codes:
LOADWM Map [X,Y] LoadWay
Now, that can be quite a pain to remember, so Nintenlord has created a macro for you to copy and paste in your definitions (it might already actually be in EAstdlib, I'm not sure).
|#define StartWorldMap(Map, X, Y, LoadWay) "WorldMapData:; _0x87; ASMWORLDMAP 0xB5631; LOADWM Map [X,Y] LoadWay; STAL 16; _0x89"|
Now, you must be wondering, what should I input for these parameters? Well, this is where I help you.
maps (Click Here To Hide/Show Text)
Nintenlord also has these definitions available for use:
Maps (Click Here To Hide/Show Text)
Most of these seem to be CGs, however some of them are maps you can use. As for replacing them, it is doable with one of Nintenlord's graphics editor, but that information can be found in another tutorial.
The coordinates ([X,Y]) does not matter for any of these, except 0x1, which will place you at the designated coordinates (IN PIXELS!) based on the pixel in the top left hand corner of your screen. Now, this is probably where you're going to run into the most trouble, because I know I did. It's really hard to determine where is what without a zoomed out version of the zoomed in world map. Now you might try to say: "Just use 0x0 as a reference!" however, 0x1 is not a zoomed in version of 0x0, but instead, a much more limited version of it. What do I mean by that? Enter the coordinates [0,0]. Now, if 0x1 were a zoomed in version of 0x0, the top left pixel on your screen would be sitting on water right? Well it's actually land-locked. See the difference?
Because of this difficulty, I have compiled a list of pre-determined locations based on locations visited throughout the normal game.
Easy Access Locations (Click Here To Hide/Show Text)
Any locations beyond this will need to be acquired through trial and error, but these are good reference points to start with.
Map Loading Way
Lastly, there is the parameter for the way to load the map. Just use one of these:
Map Loading Ways (Click Here To Hide/Show Text)
Ending World Map Data
Like the beginning, the ending must also have a certain set of codes.
CODE 0x0 0x0 0x0 0x0
Thankfully, Nintenlord has also created a definition for this.
|#define EndWorldMap "_0xCA; MUEN 4; _0xAD; _0xAE; STAL 60; CODE $0"|
Now you know how to begin and end your world map data. Now I will teach you about what goes in between those two.
Probably the most important features of world map events is the text. This, obviously, tells the player what's is currently going on in the game. Edit text with Xeld's FEditor. The world map text banks go from 0x06BC to 0x070E. Whether or not text offsets outside of these can be used, I have not tested.
Display world map text with this command:
|TEXTWM *Text ID*|
Now, there's one vital command inside of FEditor that you need to know when typing text, as well as a command that goes with it in the assembly.
You use [LoadOverworldFaces] to pause the action and begin it anew in coincidence with a SCRO command. What the hell does that mean? Simple. Always begin your text data with [LoadOverworldFaces] or else it will proceed in the events to either the next TEXTWM or the next SCRO, while your text is being displayed.
Now this leads me to the use of the SCRO command. Instead of wasting text banks and having a TEXTWM (SCRO always comes after a TEXTWM at some point anyways) and then a set of events, and then another TEXTWM etc., you can simply use this method:
Anytime you want to advance the action on the map, while continuing to display text, enter [LoadOverworldFaces] in the text editor, and the events will progress on the map until the next SCRO command while the next bit of text is being displayed. Now isn't that cool?
Other Text Commands (Click Here To Hide/Show Text)
Now, these commands do exactly as they say, except for whatever reason the roles of the TEXTBOXTOTOP and TEXTBOXTOBOTTOM commands are reversed (Error?). So you'll have to use TEXTBOXTOBOTTOM to put the text box at the top and visa versa.
|HIGHLIGHT *Area to light up*|
This code is very simple. All you need is the byte for the area to light up and you're set. Please note that this only works with the fully zoomed out world map (0x0). Using it on another map will look stupid (because you'll be highlighting the area that's supposed to be on the full world map, which will look glitchy).
Area to Light Up Notes (Click Here To Hide/Show Text)
Nintenlord also created these definitions:
Area to Light up Macros (Click Here To Hide/Show Text)
You can also use this command to change maps:
|FADETOWM [Position X, Position Y] *Map to load*|
This code works essentially the same as the LOADWM code used at the beginning of the file. The *Map to load* parameter functions the same way as do the coordinates, which once again, only work with map 0x1.
Remember how the game is always placing dots on its world map? Well I'm going to show you how to do that too.
|PLACEDOT ID [Position X, Position Y] Palette|
ID is really much like event and condition IDs, but I think 0x0 works as well. Basically, you're just assigning it an ID number to identify it by.
As for the coordinates, on a map other than 0x1, just take a look at your screen. X is its displacement (from left to right) from the pixel in the top left corner of the screen and Y is the displacement from up to down. Really, it functions just like map coordinates, but in pixels rather than tiles. Counting pixels can be tedious so you might have to hazard a few guess and get it right by trial and error (because getting a rough estimate and counting only a few pixels is a lot less of a pain).
As for the map 0x1, it gets a lot more tricky. Your position will be determined, in pixels, by the entire map, not just what you can see (thus the dot stays still when the camera moves). You can use my easy access location references to aid you on this one. Once again, this will require some trial and error, especially if you're wanting to place the dot off the screen. If you want it on the screen, it's a little simpler. As an equation for on-screen dots:
[X(in on-screen pixels) + the X coordinate of your current location (which determines the location of the pixel in the top left corner of the screen),Y(in on-screen pixels) + the Y coordinate of your current location (which determines the location of the pixel in the top left corner of the screen)]
Now, the palette is new, and is something that only applies to this code. Really, there's only a few usable palettes, but here they are:
Dot Palettes (Click Here To Hide/Show Text)
Nintenlord has also created definitions for these.
Nintenlord's Dot Palette Macros (Click Here To Hide/Show Text)
Another simple code, the ripple effect's only parameter is its coordinates, which are determined the same way dots are.
|RIPPLE [Position X, Position Y]|
Placing Map Sprites
Here's a fun one. You can place an animated map sprite on your world map. This one has several parameters.
|PUTSPRITE ID [Position X, Position Y] Class *Sprite properties* *In-class ID*|
ID works as an identifier code just like event IDs and conditional IDs. Just don't give two sprites the same ID code. This byte will be important later.
Position works the same way it does for dots. If you want an explanation of the coordinates, refer to that section.
Class references the class table, NOT THE MAP SPRITE TABLE. Whatever class you choose, the game will load its corresponding map sprite. You can find this easily by opening the class editor NMM.
Sprite properties is new. You have several options.
Sprite Properties (Click Here To Hide/Show Text)
Nintenlord has also created definitions for these.
Nintenlord's Sprite Property Macros (Click Here To Hide/Show Text)
You can combine these definitions by following the format of this example:
What that does is adds the values together to get the determined effect (obviously the fast version is always 0x10 higher than the normal and the camera following sprite's indexes are 0x80 higher than the rest).
One thing to note is a glitch that I haven't found a fix for yet. If you're trying to load two different sprites with different palettes at the same time, one of them will start out the palette of the other before flashing to its determined palette. Again, I haven't found a fix for this.
In class ID is the only thing I'm not sure of. Looking through the disassembled code, I hardly ever saw anything other than 0x0, so 0x0 is probably a safe bet. If it's not, tell me your case and I'll see what I can find on it.
Moving the sprite is simple. If it's already loaded, just use this code:
|PUTSPRITE ID [Position X, Position Y] 0x0 0x0 0x0|
This is where the ID is important, because that determines which sprite to move.
Lastly, there is the code to remove the sprite.
|REMSPRITE ID Value|
Again, ID determines which sprite to remove.
Value determines the rate at which the sprite fades out. 0x20, 0x78, 0xE8 and 0x1EC are all values the game frequently uses. Basically, the smaller the value, the faster the fadeout.
This code seems to be necessary after the REMSPRITE code:
You can also show portraits with this code.
|SHOWPORTRAIT ID *Portrait ID* Position *Loading way* Delay|
ID, again, identifies the portrait and will be needed for later codes.
Portrait ID, like it is in the text editor, determines what portrait to load. You can find the value of the portrait you want to load in the portrait editor NMM or in Xeld's FEditor.
Position is the X (and X only!) coordinate in pixels, from the left most column of pixels on the screen (starting at 0 obviously).
Loading way is new. There are several ways you can load the portrait.
Portrait Loading Ways (Click Here To Hide/Show Text)
Nintenlord also created these macros for this purpose.
Nintenlord's Portrait Loading Way Macros (Click Here To Hide/Show Text)
Lastly, the delay is how long you want to wait before loading the portrait (I guess works like a STAL code...which you can use in world map events by the way). I the following values in the game's world map data: 0, 4, 8, 16, 20, 30, 32, 33, 150
Here is the code you use to remove portraits.
|REMOVEPORTRAIT ID *Removing way* Delay|
ID is the same ID you used to load the portrait (not to be confused with the portrait ID).
Removing way functions very similarly to the loading ways used to load the portrait, except it disappears at the end instead of appearing at the beginning.
Delay also functions the same way as loading.
Alright, well that's all the world map event codes I know (and all the ones in the language besides the experimental ones). So to put things into context, I'm going to share with you an example. This example comes from my hack, Decay of the Fangs, from chapter 1. If you want to see this in action, you'll have to load the hack. I might post a video at some later point when I have time.
Mariobro3828's Example (Click Here To Hide/Show Text)
As a note, this was before I used definitions for world map events, and was also before I learned how to use the SCRO function, so there is an unnecessary waste of text banks (almost all of those TEXTWM's could be replaced by the SCRO code, save for the first one).
Alright, now you know how to make world map events! Besides the coordinates, it's rather easy once you get the hang of it. It always takes me far less time than coding the actual event for the chapter. So in conclusion...I guess...have fun making your own custom world map events!
If you have any questions/comments or criticisms about how I can improve this tutorial, please don't hesitate to post them.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users