Tileset Animations Explained - haven1433/HexManiacAdvance GitHub Wiki
This feature is still in beta and is currently only available for FireRed 1.0
Certain tiles in the game are animated as you move around, like waterfalls, flowers, and the beach. These animated tiles are stored separately from the tileset graphics and often hard to edit. But with the Tileset Animation Adder, HexManiacAdvance allows you to add entirely new tileset animation routines by introducing a new table for it.
The map tileset data within data.maps.banks/map/layout/tiles has a few different values:
- one byte for whether the tileset graphics are compressed or not (1 for compressed, 0 for uncompressed)
- one byte for whether the tileset is a 'secondary' tileset (1 for secondary, 0 for primary)
- a pointer to the tileset graphics (can be either compressed or raw, but will always be 4 bits-per-pixel)
- a pointer to the tilset palette (usually 16 sets of 16 colors, with 2 bytes per color)
- a pointer to tile 'blocks' or meta-tiles, which are groups of 8 tiles arranged into a 2x2 background and 2x2 foreground
- a pointer to block attributes (which ones can have wild pokemon, which ones are one-way jumping cliffs, which ones are doors, etc)
- a pointer to an animation initialization thumb routine!
It's this animation initialization thumb routine pointer that we're interested in. For FireRed, this is the second-to-last pointer. In Emerald, this is the last pointer. But the structure is the same: the job of this thumb routine is to do a little bit of setup and then assign an animation 'callback' routine that will be called every frame with a timer parameter.
Every frame, the callback checks the timer and decides if it needs to animate any tiles from the tileset. If it does, it calls a method to replace specific tiles in the tileset with new tiles loaded from the rom. In the vanilla game, each of these routines is highly custom, knowing exactly what animations it should use, at what frame-rate, on which tiles.
When you click the button, HexManiacAdvance will insert 3 new things into your rom:
- A table that stores the animations for your tileset in an easy-to-edit and easy-to-expand format.
- A callback routine that uses the table to update the tileset during gameplay.
- A initialization routine that you can use to connect your new animations to your tileset using the animation initialization pointer we mentioned before.
(1) Click Utilities -> Expand -> Add Tileset Animation
(2) Choose a name for your new animation, probably based on your tileset. Good names might be 'underwater' or 'route' or 'gym'.
(3) HexManiacAdvance will automatically jump to your new table, which will be named graphics.maps.tilesets.animations.<yourname>.table
. This table will host the information about how you want your tileset to animate.
If you want to animate multiple tiles, you can use the "Add 1 New" button to add more animations for the same tileset. Here's a brief summary of what each field does:
- animations -> this pointer leads to N other pointers, one for each frame of your animation. For example, if you want your water to cycle through 4 tiles, then you want 4 frames, so
animations
will point to 4 pointers, and each of those pointers will point to your tiles. It's less confusing than it sounds. - frames -> this is the number of frames in your animation. A larger number means that the animation will use more images before restarting the cycle.
- timer -> this decides how quickly your animation will run. The tick-rate will be 2^n. For example, if you pick '3', then your animation will update every 8 ticks of game time, or about 8 times per second. If you pick '4', then your animation will update every 16 ticks of the game, or about 4 times per second.
- tiles -> the number of tiles that you want to animate. For example, flowers are usually 2x2 tiles, which means 4 tiles total. So a flower animation would have 4 tiles per frame.
- tileOffset -> the index of the first tile you want the animation to replace.
(4) Edit the table based on the animation you want. For example, here, I'm wanting to make a grass animation that has 4 tiles animating through 2 different states, and I want them to update every 16 ticks. I want this animation to replace the flowers in the general tileset, which start at tile 508
.
(5) Double-click or Control+Click the animation pointer to go to your table of animation graphics. Each of them is null right now, so go ahead and click each one and choose "create new data" to create a new block of data to hold your new graphics.
(6) At this point, you want to go load the palette that your tileset uses, and you might want to examine the tile graphics as well. Go to the palette in your rom, then go to the tileset and note the address.
(7) Back at your animation graphics, click 'edit' to open the image editor. From here you can draw the new graphics for the animation, or copy/paste graphics from another source. Note that you can cycle through the available palettes until you find the one that the tileset will be using in-game.
(8) When you're done editing your animation frames, go back to the tileset data. You're ready to connect your new animations to your tileset! Change the animation pointer to point to your animation initialization routine, which is called graphics.maps.tilesets.animations.<yourname>.init
And now you're done! You should be able to load the tileset in game and see your tiles animating.