Kwirk and its sequel Amazing Tater are two of my favorite puzzle games for the gameboy. Like most great puzzle games they have very simple mechanics, yet manage to combine them in dastardly difficult ways. Being a die-hard puzzle game fan, I figured it would be nice to be able to create custom levels for them.
A few notes before I get into the technical stuff:
- Kwirk and Amazing Tater use the exact same gameplay mechanics, so I've chosen to hack/document Amazing Tater since it is the most polished of the two games (main draw being the tutorial mode).
- I'm only going to focus on custom levels for the "Puzzle Mode", as this mode lets you choose your difficulty (Easy, Average, Hard, Pro) and then lets you choose which level you want to play from within that difficulty (10 levels per difficulty, the last 3 only being unlocked once the first 7 are completed). The levels from the other modes could be edited just as easily, but unlike puzzle mode they do not give the player a menu to select which level to play.
Here is what I've done so far:
- Found level data location in the ROM
- Figured out how level data is stored
- 2 bytes for size of level
- X bytes for entity locations within level
- Y bytes for entity IDs (in order)
- Reverse engineered how this data is interpreted to load the levels
- Expanded ROM to give room for custom level data and custom menu options
- Did a little assembly hacking to use the MBC to load either default level data, or custom level data depending on player input (pushing start at title screen loads default levels, pushing select loads custom levels)
- Changed title screen to show these two options, and changed "Puzzle Mode" menu option to "Custom Mode" if the player has chosen to load custom levels
- Hex edited a few basic levels into the game
Title Screen and Menu (this is the menu you see when you push select at the title screen. If you pushed start, the second option would say "Puzzle Mode"):
Two custom levels:
You might be wondering why I chose to put custom level data in a new bank instead of overwriting the existing level data. The reason has to do with how level data is stored: every level has 2 bytes for its size, but the X bytes for entity locations depend on the size of the level, and the Y bytes for entity IDs depend on the values of the entity location data. What this means is that every level takes up exactly the minimum amount of data necessary for its size/number of entities, and there is no unused space between levels in the ROM. The problem with writing custom levels with the data in this format is that if you want to expand a level, you would have to shift EVERY level after it up however many bytes to make room, and then repointer EVERYTHING (there are 3 pointers per level, one to size, one to entity location data, one to entity ID data). Or if you want to add an entity to your level, you would have to add 1 byte of entity ID data, and then shift everything after it up 1 byte and repointer it all. You can see how this would cause a headache very quickly.
So, to avoid this, I have expanded the ROM and created a sort of "standardized" level structure with the luxury of having extra space. Instead of restricting levels to the minimum amount of bytes, I've expanded them to take up close to the maximum. The 256 bytes are broken down into 2 bytes for size, 48 bytes for entity location data, and 206 bytes for entity ID data (this format supports levels up to 18 tiles wide by 16 tiles tall, with up to 206 entities). This allows levels to be edited without having to shift other data around or repointer things repeatedly, and also preserves the excellent default levels and tutorial mode. The two levels in the above screenshots are stored in this format in the expanded area of the ROM.
....So yeah. My goal now is to either get a basic level editor working, or just hex edit a few more levels in.
Oh, and if anyone wants to try out what I have so far, I could upload an ips patch.