Even though classic consoles like the NES have strict limitations for memory and graphics, there are still a lot techniques and tricks for squeezing art into games. One of these is how you organize banks of memory and sprite or background tiles. This will help you find extra space for more elements or to organize assets in such a way to make development easier.
Whenever you are organizing banks for the NES the first important thing you are going to need to know is how big the graphics banks are going to be. For MMC3 games, it will either be 1K banks or 2K banks (you can check out a blog about bank sizes here).
The following examples in this document are going to involve using 2K banks, so there will be two banks per page. Once that is decided, you will want to open up all of the finished artwork that you want to organize into banks. I’m going to use the bosses in Space Beats, an upcoming shoot 'em up for the NES featuring golden era sci-fi and 80's/90's hip-hop.
The first thing I do is overlay an 8x8px grid on the image. That way I’m making sure that I’m adhering to the dimensions of the tiles that I’m breaking my image down into. Then I turn grid snapping on so that my selections will always be the proper size.
After the grid is set up, the next thing you will want to do is use the rectangle select tool, and isolate one of the elements that you are going to place into the bank. If your art isn’t all on the same image like in the examples above, then this step might already be done.
This piece of artwork uses a combination of sprites and background elements. Due to the fact that the NES loads up sprites and backgrounds separately from each other, you will have to isolate and remove the sprite element from it. In this case it is the robot’s head. In order to do this, you would cut just the robot’s head out and place it in a new image.
Now that just the background elements are left behind, it is time to start placing it in a bank. For this you will be creating a new image. The dimensions of this image should be 128x128px. That is the dimensions of a single page of graphics on the NES. Then you want to overlay 8x8px grids on top of both the new image and the background element that you are about to being slicing, and turn grid snapping on.
Usually, I will take a moment to make a guide for myself so that I know how big a bank is visually as I work. I’ll create a new layer on the 128x128 image, and fill everything but the bank I’m working on with red. The backgrounds in Space Beats use 2K banks, so my guide is going to fill up half of the image.
Once the guide is set up, it is time to begin cutting the background and placing it into the bank. Open up your isolated background object, and while adhering to your 8x8 grid, select and then cut the top row of tiles. Only select the tiles that contain the artwork.
The last two tiles of this row are blank, so they will not be selected. Paste the row of tiles into your 128x128 image.
When you are arranging this image you should always keep the first tile of a page blank. That way, the tile ID for a blank tile is always the same. If you are unsure where a bank is going to be placed in the game, then it is a best practice to always keep the first tile of a bank blank so that it won’t matter where it is placed.
After your first row of tiles is in place, count how many tiles remain in that row. In this case I still have five more tiles in my first row. Go back to your artwork and select the first five tiles of the next row.
You will then cut those tiles and place them in your bank.
Continue to do this for the remainder of your art element and you will get something like this:
You can see that there is still a lot of space left in that bank, and if we look at our original image there are plenty more robots that need to be organized. There is enough room in this bank for at least two more of them.
We can simply repeat the same process for the next boss. In our current row there is still two blank tiles left. So start by selecting the first two tiles of the next image, cutting them out, and pasting them into your bank. Then continue cutting tiles and placing them in your bank until you’ve covered the entire image.
Again, repeat this process for the third boss to fill in the rest of the bank.
There is still some blank space in the bank. Because we’re currently just bringing over large images, it’s best to keep this space blank. We can reserve it for any small things we might need to add to the screen later.
After your bank is filled, move your guide up to cover the first bank and begin filling the 2nd bank the same way you did with the first. Eventually you will end up with a full page of graphics like this:
Save this image before you continue working. The NES doesn’t store palette information with the graphics themselves, so we are going to want to make everything have the same palette now that it is more organized.
Color replacement works differently across different image editing programs. For the sake of this guide, I am going to cover how to do it in Gimp. In your toolbox you want to pick the Select by Color Tool (Shift+O). Click on the color you would like to replace on your image. Next, use the eyedropper to select the color you would like to replace it with. If you are taking an image with multiple palettes and making them all use the same one you would replace the darkest color of one of your palettes with the darkest color of your chosen base palette and so on.
Once you have your color selected and the area you are replacing selected go to Edit -> Fill with FG Color. That will fill the entire selection with the color you picked with the eyedropper. Do this for all of the palettes so that they now all share the same one.
The reason why you saved the image before doing this is so that the developer can use it as a reference so they know which tiles belong to which elements. After the next step they won’t match up perfectly. It should still be close enough to use as a guide, but if you feel it is too significantly different, you are welcome to make a new reference with the finished page.
The last two images you will need to make are images of each bank individually. The final step to creating your graphics page is to remove repeat tiles. The NES doesn’t need to store more than one of the same tile in a page, so we need to remove duplicates. There are multiple methods of doing this. This guide will be using the free version of PyxelEdit. Import the image of your first bank. In the box that pops up, specify that the tiles are going to be 8x8, and then click on the box that says Identify Tiles.
This will load your image and generate a tileset of it. This generated tileset removes any duplicate tiles automatically.
You’ll want to make sure that your tileset width is the same as it is in your graphics page. You can do this by clicking on Tiles -> Change tileset width. Tileset width in PyxelEdit is measured in tiles, so in your 128x128 image it is 16 tiles wide (8 * 16 pixel tiles = 128 pixels). So you want to set your tileset width to 16 and make sure that Preserve tile layout is unchecked.
Once that is done, click Export -> Export Tileset, and save your optimized bank. Do this for the next bank and then place them back into your 128x128 image. The reason this cannot be done until you make your image use a single palette is because any automated optimization is going to treat any identical tiles that use different palettes as unique which will end up adding unnecessary tiles to your banks.
Once those images are placed back on your page, you might want to consider moving some stuff around or adding new elements into the space that you have created. If you do this, just make sure to document what you have changed from the reference image and make sure that the developer sees the documentation. Ultimately you will be delivering your reference image, the optimized 128x128 image, and any notes that you might have about how it is arranged.
Once you get comfortable with bank sizes and breaking things into tiles, you might find that it is easier to arrange your banks differently. Because sprite tiles can be flipped horizontally or vertically, any tile that is a mirror image of another one isn’t counted as a unique tile, so organizing them in horizontal strips might not be the best solution.
You can see that the sprites in Little Medusa keep their general shape, but have had any duplicate or mirrored tiles removed. If you are arranging a background that has a lot of repeating tiles in it, then arranging your tiles in strips might not be the best idea either. The backgrounds in Little Medusa are like this, so tiles were stored mostly pre-assembled.
You should arrange your tiles in a way that makes the most use of your banks as possible.
If you would like to diagram out your tiles after optimizing them, but don’t want to apply the proper palettes to them again, you can also just draw one out. Go back to your 128x128 image, and make it grayscale.
Then make a new layer and cut the Opacity down to around 30%. Next, select the tiles that make up your first element and then choose a bright color and click Edit -> Fill with FG Color on your new layer. Pick a new color and then fill in the area with the next element and so on.
Then increase the size of your canvas (Image -> Canvas Size) and add a key at the bottom for the developer to follow:
That will help them quickly identify what tiles they should be using.