Trip World is a Gameboy game from 1992.
While some games now might really hold your hand and introduce you how to play the game, old games were different. Sometimes to know the story, controls, names of the characters etc, you had to read the instruction manual that came in the box.
It took me around 20 minutes of playing Trip World until I realized that you can turn into a fish!
Games then were arguably harder. Possibly to ensure that you would get your money's worth?
The fact I had to play the game in one sitting made it hard. The game has no battery so you can't save - although you can select the level you want to play. You have 3 lives and 4 bars of health and by the time I got to the 3rd boss I was dying a lot.
What the game looks like normally
I thought it would be a fun project to make a hack that makes the game a little easier.
I wanted to remove the 'lives' aspect of the game, so that you will never see a 'game over' screen. I really enjoyed playing Wario Land 3, a game with no health or lives, where if you get hurt you simply have to try whatever you were doing again. (Technically I think there were two expections to this rule in the game - anyway it was great fun)
If anyone would appreciate me making a video of (re)creating this hack, let me know in the comments below.
How I did it
- To start, I downloaded bgb (a Gameboy emulator and debugger) and loaded up the Trip World rom. Right click on the main screen and go to 'Other'->'Debugger' to get the debugger up.
- When in-game, I found the offset in RAM for where the lives are stored, via the 'cheat search' (bgb debugger, 'Window'->'cheat searcher')
This is basic cheat finding stuff, if you have 3 lives, search for 3, get killed and search for 2... repeat until you have 1 address.
- I set an 'access breakpoint' (bgb debugger, 'Debug'->'access breakpoints') that breaks (pauses) the game and shows you the current ASM instruction when a value is written to the lives offset. Kill the player, the lives will decrease by 1, and the game will pause.
- I then NOPed out the function that decrements your lives when you die.
NOP is an ASM instruction that does nothing (NO OPeration), and we use it to replace an existing instruction when we want to stop it from happening.
To change the ASM instruction in bgb, right click the line of the instruction, click on 'Modify code/data', and type in your new instruction - 'nop'.
That's quite simple and only took a few minutes. But I was then left with a useless lives indicator on screen. There's no need to show that I have 3 lives left if the game doesn't use lives anymore.
So I worked on removing the lives from the UI. When working with graphics, BGB's Tile Viewer comes in very handy.
How I removed the number of lives from the UI
- Set BGB to break when the lives are read in game - and so it breaks every frame to update the UI with the current amount of lives.
- From the ASM I could see that the number of lives were read, then 50 was added, and that value was used to fetch a tile that gets drawn on the UI. 2 lives + 50 = 52.
- When looking at the tiles, tile 50 was a graphic of '0', 51 was '1', etc. Tile 0 is blank.
- I changed the ASM so that instead of using 'lives+50' to pick the tile, always use Tile 0.
After removing the lives counter
This removes the number of living being displayed, but icons to the left ('🐇x') of it are still present and it looks strange. I want to remove them too.
Originally I did this in a cheap and dirty way, I simply edited the tile graphics in ROM so that these tiles were blank. Technically the game was still drawing the icons, but it was just drawing 'nothing'. I didn't like that method and wanted to do it neater, so I then tried again and found where the UI is defined in ROM and stopped the icons from getting displayed in the first place.
How I removed the player icon from the UI
- Open the VRAM Viewer and see the graphics that the game has currently loaded.
- On the 'BG Map' tab, I change the current map to '9C00', the Gameboy can have 2 background maps and the tiles I'm looking for are on the 2nd map.
- Get the 'Map address' of the tile we want. (9C0E)
- Go to the 'Tiles' tab on the VRAM viwer, and find that same tile and get the tile number - it's 86 for this one.
- Go to
9C0Ein the hex view of bgb, you should see 86, the tile number for the icon. Right click it, set a breakpoint when 86 is written to this address. It will happen when the game play starts, when starting the game or after dying.
- The game should break, look what's happening - the instruction above that just executed is
ld a, (de)and you should be able to see in your registers that a is now 86. We see that a is getting it's value from the byte at
de. Change the data at
deto 00 and you did it!
Repeat the same thing for the 2nd tile (the one that contains the 'x')
After removing the player lives icons
Now, there are no trace of lives on the UI, but I don't like how the score is two tiles longer than the health bar. Plus, this is a hack to make the game easier, so I'll increase the health bar to make it 6. Now it will line up with the score.
How I increased the health from 4 to 6
I used the same methods as above and found 3 instructions/places that we have to change from 4 to 6.
- Initializing your health value to 4 at the start of game play
- Drawing the maximum of 4 health pieces on the UI
- Recovering to full health when picking up a big heart recovery item
Replace these instructions to use 6 instead of 4 and you are done! See how far you get by yourself.
Note: I didn't realize there were 2 different health recovery items (the heart flowers) There's a big one that recovers all of your HP, I fixed that easily, but I forgot about the smaller heart that increases your HP by 1.
For the smaller one, the game checks to see if you are at max HP before incrementing. Well, it doesn't explicitly check to see if your HP is 4, it actually checks if bit 2 (the 3rd bit from the right) is set.
100 in binary is 4, so this works great. But we can't check a single bit to see if our HP is at the new max of 6, because 6 in binary is 110. We would need to check 2 bits, and I don't think that's possible in one instruction. We don't want to take up more instructions/bytes that the original instruction because otherwise we would overwrite and destroy the next instructions in the game.
Anyway, here's what's going on and how to fix it.
Fixing the small health flower that adds 1 to your health
What happens in the game:
Instruction 1 :
bit 2, a sets the 'z' (zero) flag if the value at bit 2 is 0.
So the 'z' flag will be SET if our HP is 1 (bit 2 is not set, value at that bit is 0, so 'z' (zero) flag is true - that makes sense), and UNSET if our HP is 4 (bit 2 is set, value at that bit is 1, 'z' (zero) flag should be false).
jr nz, 41B9, this jumps (skips code) and continues at 41B9 if the 'z' flag is not set (nz = not 'z'). The health incrementation happens before 41B9, so by skipping ahead it doesn't add 1 to your HP.
What we change those 2 instructions to:
cp a, 06 will set the 'z' (zero) flag if a-6 is 0.
Now, the 'z' flag is set if we are at max health, before, it was unset if we were at max health, we need to change the jump to handle this.
jr z, 41B9 will only jump after the health increment if our health is equal to 6. (We just take away the 'n' from the 'nz' before)
Thankfully it doesn't take any more space in ROM to change that instruction to
cp a, 06 which explicitly checks if our health is 6. If the
cp instruction did take more space in ROM (different ASM instructions can be made up of different amount of bytes), we would have to jump to a different area in the ROM with enough room, add the code we want there, and jump back to where we came from. It complicates things and I didn't want this small project to stay simple.
After raising max health to 6
Although, would it look better if the UI was centered?
I didn't perfect it, and I'm not sure if I really do want it centered.
I thought about having the text on the far left and the health indicators/points on the far right, but that would be harder and require more modifications to the game. The game only expects a certain amount of tiles to be written on those the 'LIFE' line and the 'SCORE' line. Moving the start position of the line isn't difficult, but adding more tiles to be drawn would be.
Below is a screenshot from when I was trying, health didn't (visually) decrement properly when I made it so this screenshot is just for fun.
Centered UI (health wasn't fully functional if not at max)
I've uploaded the hack in IPS form to romhacking.net, but it's still waiting to be approved (as of 2019-10-03).
Until it's there, you can get the IPS file directly from my site here and use something like Lunar IPS to patch it to the Japanese ROM which has a CRC32 of 11568E64.
The finished piece in action:
The modded game running on my real DMG (via a EMS 32M flash card - a card with no usb interface or removable storage!)