• Add Review
  • Subscribe
  • Nominate
  • Submit Media
  • RSS

Old School Scrolling

One of the things that can easily bring a Gameboy to its knees is having a tile map. Just having one. You're used to just making maps of any size you want and it'll work. Just make an array of bytes and use that to draw the tile map. On the Gameboy this becomes an impressive feat.

You get two sheets of 128x64 pixels you can combine for a maximum of 256 patterns. That doesn't sound as bad until you realize the upper sheet is shared with sprites and you have to also leave some for the system (windows, text, information, etc.). A lot of games would put the environment-specific patterns in one of these sheets, like Pokemon Red/Blue or Links Awakening:




So I drew some patterns that look like they're from Ruby Wolf. Each cell is a 4-color image and the colors here are just for reference. These colors are either just the 4 shades of grey or are actual colors from one of 8 palettes on the color system. I'm doing a dual mode game which is in color, but will work in the older system without it.



I've called these patterns instead of tiles. You cant just fit a sheet of tiles on an image like you're used to, there's no room. If we did that here, we'd only have 32 tiles. What we do is combine these patterns to make tiles, 4 patterns to a tile (some of the tiles aren't used yet, I marked them with purple to remind me). I've also made it so the tileset editor displays things closer to what an actual Gameboy Color system would actually show, it mixes colors oddly.



Games on many of the old console systems would go up to 256 tiles, I'm splitting mine into two groups of 128 tiles with the second set being tiles common for the entire game (item boxes, etc.). Tilesets also encode the collision and other flags with the patterns. The encoding I came up with uses 6 bytes per tile. This means it occupies 1536 bytes when unpacked so I've used up a little more than 1KB already. The Gameboy only has 8KB of RAM for you to use. If you made every tile on the screen a 1 byte reference, a 32x32 map takes up another 1KB and even larger maps like a 64x64 one would take up 4KB. You still need to leave room for your algorithms, objects, and the rest of the game engine!



There is video RAM. You can fit 16x16 tiles on the background map there which is even smaller. Some games simply do this, most notably Links Awakening where the action always takes place on one screen and it scrolls new ones in when you change areas.



If I don't want to waste the rest of my RAM and I don't want to squish maps onto single screens, then some sort of streaming system has to be made.

I found a good answer from a NES game, the original Final Fantasy. It encoded its large map as 256 tile stripes and would decode them into rows to look them up.

https://datacrystal.romhacking.net/wiki/Final_Fantasy:World_map_data

The scrolling window wraps around the background map if you go over the edge, so all you have to do is place new tiles as you move.



To test everything, I drew a quick amateurish hallway-room-hallway map that's 32x32 big (twice as big as what fits on the background) and encoded it as 32 stripes of 32 tiles each.



We're not done yet! I had to actually program this using LR35902 (Z80 like) machine code instructions. It runs at about 4.19Mhz and the fastest instructions take 4 cycles so at best you're getting a million cycles a second. The system runs at (basically) 60hz (close enough) so this means you get about 17 thousand fast instructions. You will run out of time easily if you're not efficient.

In an RPG like this, you move on tiles. This means there's only 2 of the 16 frames you're walking where new map cells & tiles have to be loaded. Every time this happens, the system loads either 1 row from the map (if moving up or down) or 10 rows from the map (if moving left or right). It has to decode 10 strips and grab a single tile out of each one for left and right movement. You can't just encode the map in columns and add it to the data because then the result is larger than uncompressed, defeating the purpose.

I've somehow managed to make left and right movement fit in time with half the remaining frame to spare (BGB has a handy load indicator if you use low power CPU waits at the end of each frame). This means limits the width of the map to about 64 tiles because the decoding algorithm scales linearly with time. If you run out of time it makes everything jitter noticeably as you walk. I might have to do better in the future if I find 64 tiles wide isn't big enough, but for now I've got maps working. The answer will always be to get more creative..




Or you can open RPG Maker, scribble tiles on a map and hit play.