Skip to content

Map Tile Animations

DoubleplusCrafty edited this page Jun 19, 2026 · 1 revision

Map Tile Animations

Coilsnake does not currently decompile animated tiles or their configuration, and so they cannot be edited in the map editor. In order to edit tile animations, you'll need to manually extract the data from the rom yourself, and insert it back with coilsnake by sticking it in ccscript. It's a rather involved process but if you're ready then read on!

Note: All addresses used here are for an unheadered ROM.

Each map tileset has a list of up to 8 sets of tile animations. These animations involve "DMAing" strings of 8x8 tiles into the SNES's VRAM where the map minitiles are located, overwriting them and thus animating every metatile they're used in. All the tiles used for graphical animations in a single map tileset are all stored together in one blob of 4bpp graphical data, which I have dubbed a Tile Cluster. Each map tileset has its own cluster, and the cluster can contain multiple animation groups. The clusters can contain up to 256 tiles total.

Besides the actual graphics, there exists a table for configuring the animations. Each map tileset has its own set of animation groups. Each group has the following properties:

  • Frame Count (1 byte): Number of animation frames in this animation group.
  • Delay (or speed) (1 byte): Number of game frames that each animation frame will last. The game runs at 60 fps so, for example, a delay of 20 will animate at 3 fps.
  • Group Length (2 bytes): How many minitiles this animation replaces, or in other words, how long this animation group is. This is measured in bytes, and one tile is 32 bytes (0x20), so if for example a group is 10 tiles long, then the group length would be 320, or 0x140. This basically allows a single animation to apply to multiple minitiles in a row.
  • Cluster Offset (2 bytes): The offset for where in the tile cluster this animation group starts. This is also measured in bytes, so multiply the tile number by 32 (or 0x20).
  • Minitile Destination (2 bytes): Which minitile in the map tileset to start overwriting with this animation group. For some reason this is multiplied by 16 (0x10) instead of 32. So for example, to start overwriting minitile 11, then this destination parameter would be 176 (or 0xB0). If you want animated tiles to use the foreground layer, add 512 to the tile number, or 8192 to the minitile destination value.

This is all rather hard to explain with words, so if you're really confused, don't worry, I've got a lot of pictures in the following example to help.

Tools Needed

Again, Coilsnake currently does not decompile anything related to animated tiles, and the map editor is not capable of editing or viewing any of it. Here is what you will need in order to work with animated tiles:

  • These two CCS files: the Animated Tile Graphic Table and the Animated Tile Config Table. The Graphic Table will be used to insert the actual binary blobs of tile graphics into the rom, while the Config Table is used for, of course, configuring the animation properties.
  • If you don't have it already, you'll need the ubiquitous asm65816.ccs.
  • exhal and inhal, a pair of programs for compressing and decompressing the format that HAL Labs used. You'll need this for extracing the animated tile graphic clusters out of the rom, and to compress them when you're ready to add your own tiles in.
  • A binary graphics editor, I heavily recommend YY-CHR (I actually don't know of any others).

Now lets take a detailed look at how these graphics and configuration work in the game!

Configuring Clusters and Groups: Example with Onett

First, let's use exhal to extract the graphic cluster of Onett's animated tiles so we can look at them. Exhal is a command line program and you use it simply with:

“exhal.exe” “EarthBound.sfc” [address] “Output_file.bin”

I've included a table with the addresses of the animated tile clusters for every tileset down at the bottom of the page. Onett's tile cluster is located at 0x1FC93B, so we can go ahead and run exhal like this:

“exhal.exe” “EarthBound.sfc” 0x1FC93B “OnettTileCluster.bin”

Now we can open that .bin file in Y-CHR, and we'll be able to see and edit the tiles:

Screenshot of YY-CHR, with Onett's tile cluster open in it

You'll need to set the "Format" dropdown to "4BPP SNES/PCE(CG)" for them to display properly! ALSO the colors will not be right, you'll need to manually load in a palette to show the correct colors. Hopefully EBME gets the ability to export palettes soon but in the meantime uhhh guess what, you gotta manually copy the colors from EBME into YY-CHR, have fun :)

OK so now that we have some graphics to look at, let's open up the Configuration Table. You'll see there's an entry for each tileset, and each entry has a different amount of stuff to it. Let's look closely at the entry for Onett:

//Onett
tileset_1:
	groups(2)
	anim_group(4, 19, 320, 32, 16)
	anim_group(2, 20, 64, 1312, 176)

Here's what it all means: That first parameter, groups(2), is how many animation groups this tileset has. Onett indeed has two different sets of animation: The stars in the night sky, and the water to the west. You'll notice that tilesets that have no animations, such as Twoson, simply have groups(0) and no further data.

After that is a line for each group. This follows the parameters as described earlier, to recap the format is:

  • frame_count
  • delay
  • group_length x 32
  • cluster_offset x 32
  • minitile_dest x 16

Now, let's compare this to the graphics and see what it means. Here's an image of Onett's tiles with numbers so it's easier to follow: Image of Onett's tile cluster with tile numbers edited onto it

The blank tile 0 is basically skipped when it comes to calculating everything, so you can ignore it.

Let's start with the first animation group. The frame count is 4, so naturally this group has 4 frames of animation. The delay is 19, so each animation frame lasts for 19 game frames. The group length is 320, divide that by 32 and we find that this animation is 10 tiles long, or in other words, it replaces 10 minitiles in a row. The cluster offset is 32, which divided by 32 is just 1, so it starts with the very first tile of the cluster. And finally, the minitile destination is 16, this gets divided by 16, which again is 1, meaning it replaces the very first minitile.

Now for the second animation group, which are the stars. This group has 2 frames, a delay of 20, a length of 2 tiles (64 ÷ 32 = 2), is offset 41 tiles into the cluster (1312 ÷ 32 = 41), and replaces minitile 11 (176 ÷ 16 = 11).

Now, I've rearranged the image of the tiles to show how all these parameters apply. Hopefully it makes sense!

Images of Onett's tile cluster, arranged to lay out the animation frames

Adding a Custom Animation

Ok now that you (hopefully) understand how animations are configured, I'm gonna show you how to make your own animation from scratch! I've made this little animation that makes the flowers dance. I want to insert it into Onett's animations!

The first step would be to decompress the graphics cluster, which I already did earlier in this tutorial. Now, with that file of the cluster open in YY-CHR, I'll add my new flower tiles to the end of it.

You'll notice that I split the frames up, putting the first frame of the white and red flower together, then the second frame of both flowers, and so on. This will make it simpler to insert because they can both be controlled as a single group.

The next step is to compress this file so it can be added back to the rom. Luckily, with ccscript's insertbin feature, Coilsnake will be able to add it to the rom for us in whatever free space it finds. All we have to do is compress it, and then add it to the animated_tile_graphic_table.ccs file. Get the command line open again, this time we'll be using inhal, which is run like this:

“inhal.exe” -n “file_to_compress.bin” “new_compressed_file.bin”

file_to_compress will be the graphics cluster with the flowers that I just created. The new_compressed_file will be created by inhal, make sure you don't get these files mixed up! I'll run inhal with “inhal.exe” -n “custom onett flowers.bin” “custom_onett_flowers_compressed.bin”

Now, to actually insert these tiles into the rom, we use the animated_tile_graphic_table.ccs. First, move the compressed graphics cluster .bin to your CCScript folder. Then open up animated_tile_graphic_table.ccs, and find the line that says "[3B C9 DF 00]" //long tileset_1. By default, this table uses the vanilla graphics that are already in the game, so we need to tell it to use our new graphics instead. Get rid of the original pointer and uncomment the long pointer for tileset_1 (basically, get rid of the "[3B C9 DF 00]" and two slashes, so that the only thing on the line is simply long tileset_1. Then, down under that table, under the label tileset_1: (the one that says //insertbin "your_animated_tiles.bin"), uncomment it and replace the dummy file name with the name of your new compressed graphics cluster, in my case this line should now say insertbin "custom_onett_flowers_compressed.bin"

Now the next step is over in animated_tile_configuration_table.ccs, to set up how these flowers work. Using what we covered above, this should be easy to figure out. Remember, anim_group(frame_count, delay, group_length x 32, cluster_offset x 32, minitile_dest x 16)

  • My flower animation has 4 frames
  • I chose to make the flowers animate with a delay of 20 frames
  • The length is 2 (one tile for each flower), times 32 and we get 64
  • The first tile for these flowers is at tile number 45 of the cluster. Multiply by 32 and we get 1440
  • Most of the tile animations in EarthBound replace the first minitiles in the tilesets. This doesn't have to be the case though. As you can see in the tile editor, the flower tiles I want to replace are way in the middle:

This means our minitile destination will be minitile 268. Multiply this one by 16, and that makes 4288.

Now if we put it all together, that gives us anim_group(4, 20, 64, 1440, 4288). Let's add it under the two existing groups, and also make sure to update the number of groups to groups(3)! Otherwise your new group will be ignored.

Now, with these two ccs files and the compressed graphics cluster in the CCScript folder of your coilsnake project (and asm65816.ccs as well), we can go ahead and compile to test it out!

TIP: This was briefly mentioned up above but I'll say it again in case you missed it - Animated tiles can apply to the foreground layer of tiles too! Simply add 512 to the tile number, or 8192 to the minitile destination value. So for example, if I wanted to animate a tree, and the tree's tiles start at minitile 55, I would instead change that to minitile 567, and I would put 9072 in the minitile destination in the config.

Tileset Graphic Cluster Addresses

Here's the addresses of all the graphic tile clusters. These are the addresses you'll plug into exhal in order to decompress the cluster for a tileset.

Tileset ROM Address
0 0x1FC243
1 0x1FC93B
2 0x1FCB7F
3 0x1FCB98
4 0x1FCBB1
5 0x1FCBCA
6 0x1FD000
7 0x1FD6EE
8 0x1FDD57
9 0x1FE1EB
10 0x1FE204
11 0x1FE21D
12 0x1FE236
13 0x1FE402
14 0x1FE4C8
15 0x1EF0E7
16 0x1EF100
17 0x1EF2CF
18 0x1EF5EB
19 0x1EF869

Old stuff I"m shoving down here out of the way as I edit the page

In the ROM, there is a table of 32-bit pointers to the clusters of compressed animation graphics data at $EF11CB. There is also a table of 32-bit pointers to lists of graphical animations at $EF121B.

Useful Resources

Getting Started

Finishing Up

Sprites and Graphics

Characters and Dialogue

Misc.

Music

Map Editing

Battle Data

Advanced

CoilSnake Development Guide

Fan Translation Tutorial

Errors and Issues

Obsolete

Clone this wiki locally