Skip to main content

ROM Hacking: How To Defuse an Atomic Zukan

Submitted by kmeisthax on Sat, 03/31/2018 - 12:50 in ROM Hacking

The Field Guide updates in Telefang patch v117 were so massive I joked that we could have just shipped them alone as March's update and left the rest for April. With such a massive redesign, our patch notes don't really do it justice. The process of such a redesign is highly involved, requiring assistance from programmers, UI designers and translators alike. So, I wrote up an in-depth breakdown of what the process of a major UI redesign looks like.

Step 0 - Know the code! (And the assets)

Before we can modify the field guide we first need to have the field guide in our build system. This means extracting all the code and assets that make it up. Most of the code in Telefang is structured as a state machine - a function that does different things based on a number in RAM. In this case, the current state (number $0C) handles all of the Pause menu screens, and it does this by nesting another state machine for each subscreen that can appear here. We're interested in the Zukan substate (number $18), which itself is a third-order state machine with states for loading graphics, handling input, fading the screen in and out, and so on. (Some screens go four deep.)

Given that we know what all the states do, getting the code is just a matter of tracing execution from the top-level state machine down into the one that runs the field guide. You can use bgb's debugger, or a decent disassembler, to get this code. Afterwhich, we clean up the disassembly, add in symbolic names for everything, and add it to our ongoing split disassembly project. This also applies to any unknown functions that may be called by a particular state implementation, recursively, until we run out of code for that section.

Depending on the the screen, resource extraction may also be necessary. Fortunately, many of the game's graphics and tilemaps live in resource tables that have already been extracted. In that case, it's just a matter of making sure all the loaded resources mentioned in the state are properly named and located, since most UI redesign involves modifying those.

This is what the field guide disassembly ultimately looked like as it was added to our Git repository.

Step 1 - The "Easy" Changes

The Game Boy hardware builds up it's screen using 8x8 pixel tiles arranged into a tile map. Telefang uses precomposed tile maps in order to form most of it's user interface. These are efficient for the slow 80s-vintage CPU in the Game Boy, and also useful for UI designers as less code is necessary to define a layout. I'd make an analogy to modern software development using something like Xcode's Interface Builder, but that might be a little bit of a leap, since the UI still needs to be driven by lots more code in this game. But it's still where our own changes have to begin.

Interestingly enough, the Japanese version actually does center the monster name a bit. It's a bit hard to tell, though, since many species names line up with the start of the actual monster description. When we started redesigning the field guide, we moved the species name to the top of the window. I swear it still is being centered, though, despite not being correctly positioned for it due to various hardware and software limitations which we will look into breaking now that we've finished the easy bits.

Step 2 - Text Window Shenanigans

Telefang has a single text drawing mechanism for the whole game. In our disassembly, we call it MainScriptMachine. (Yes, it is also a state machine.) This routine comes hardcoded with all sorts of useful things for dialogue boxes. There's animations for scrolling the text box up, newline support for moving text drawing to the correct position for the next line of text, and so on. However, all of these built-in mechanisms are hard-coded to assume two lines of 128px (16 tiles) width, which is a problem for us and our dreams of longer Field Guide entries. We want to add a line of text, which simply won't work yet.

Or it wouldn't, if we hadn't already fixed this before. So, there's this screen in the game where you can read text messages you've received from the monsters you've enlisted. For what I assume are thematic reasons, they designed this screen with a six line window, 48 pixels across. Of course, this is not the correct shape for Telefang's text system. If they were to format messages with a newline, bad things would happen, so their solution was to simply not use newlines. Telefang didn't ship with a proportional font, so those 48 pixels translate to exactly six characters. Hence, they just draw one massive line of text and rely on the tilemap to break it apart into lines.

We added proportional font support in our patch, which broke this hack, so we had to implement proper support for these differently shaped text boxes. This meant that our work here was halfway done! We just had to inform the text system that it needed to draw a three line window, 120 pixels across. (That's a tile less wide than the normal dialogue box.) This would have been fine, except we actually have translated entries longer than three lines already! What happens then is that MainScriptMachine's scroll-up animation takes over. It helpfully draws a continue triangle and then waits for you to press A to continue. However, since we only call MainScriptMachine once, none of that actually works and pressing A does nothing.

It was time to implement paging, a feature that's already built into the text system. In fact, my first attempt was to just run the text system again when you pressed A, so that you could scroll the text box and draw the next three lines. It turns out, however, that the text system's scroll-up animation is also not aware of our odd window dimensions. Hence, if you pressed A with that modification, it would roll up the text and break the tilemap something fierce.

This is what it looks like if we try the text roll-up animation on this screen

Not exactly what they meant when they said "roll up the rim"...

After a bunch of fiddling I eventually figured out how to kill the animation and just get it drawing the next three lines of message. I wasn't interested in actually fixing the text roll-up animation anyway. After all, it's a field guide, so the pages shouldn't scroll in - they should just appear when you press the button. Of course, this wasn't easy and we had to resort to various horrible hacks in order to get this working:

  • MainScriptMachine actually checks the player input on it's own to see if it should run it's roll-up animation. If we just call it again to print the next lines of text, it'll roll up, because it sees that the player pressed A this frame. Of course, player input is just another variable, so we overwrite it to effectively un-press the A button.
  • Any time we see the script system about to start the text roll-up animation, we cancel it and set it back to "drawing text".
  • We can also switch between entries in the field guide, and if we leave an entry with multiple pages, we'll draw the second page of the last entry. This is because most of the text system state isn't erased when we switch pages, and it thinks we've asked it to draw the second page. To get around this, we clear text state when pressing left or right to force drawing from the start of the new entry message.
  • We get a free continue indicator on paged entries because the text system just does that. But it doesn't go away on unpaged ones, so we have to remove it ourselves with a VRAM write.

Step 3 - Wait, Why Can't We Just Vertically Align This?

At the same time as I was working on getting multiple page field guide entries, the translator, obskyr, was also unhappy with all the limitations of our off-center text. I mean, why can't we just draw the text in the center? Well, because we have a tile grid to respect, and absolutely none of the text machinery in Telefang is designed to draw off-grid tiles. But wait! This is a Game Boy. That means we have sprites, so we could just put the name into sprites and then move it anywhere we want.

"Just" is a dirty word in software development and should be banned.

Hardware sprites are single tiles that the game software can move about the screen independently of the background layer. However, these are pretty tiny, so Telefang - like most other games - does not just draw sprites onto the screen. It instead keeps sprites organized into precomposed sprite lists, which are referenced from a structure called a metasprite. Every frame, the game takes all of the active metasprites and constructs a sprite list from those that the hardware can make use of. So we can't just put the name into sprites - it'd get erased the next frame over.

The correct way to put the name into sprites is to first create a new precomposed sprite list. We already figured out the format of these lists; so it was just a matter of adding it wherever it would fit. (Fun fact: Half of the time of a clean build of the Telefang disassembly is wasted on building precomposed sprite lists.) I had to walk obskyr through the process of creating a sprite list, which has a few unusual warts to it. Then he had to add code to fill out a metasprite structure with the necessary information. I wasn't privy to what happened later, but I heard phrases insinuating that this was harder than vertically aligning things in CSS, which I found a little incredulous. Eventually we realized that I had completely messed up our source format and switched X and Y around. Once that was out of the way, we eventually got some ceremonious cheers as the name was vertically aligned absolutely beautifully.

Step 4 - Evolution Indicators Are Fun

Drunk on our own sense of power, we decided that the evolution indicator had to go next. It's a graphic shared with every other place that uses evolution indicators, such as the encounter or contact enlistment screens. In the Japanese release, this is just four kanji. In the bootleg release, these are badly abbreviated (e.g. "NatMon" instead of "Natural Denjuu") to fit a disgustingly large font. Early on in the patch's lifetime, however, we drew translated evolution indicators using a unique, two line font that doesn't really match anything else. Most of the indicators fit, but we still had to resort to abbreviations such as "S.Machine Denjuu" in some places.

For whatever reason, we staggered the two lines; the top being left-aligned and the bottom being right-aligned. This fits the 64 by 16 pixel area the original developers intended, but it didn't look great in the field guide. Of course, we're fan translators, which means we can overengineer a solution without having to worry about pesky things like "budgets" and "time constraints". We altered the field guide to load a completely different set of evolution indicators that were wider. In fact, they're so wide that they hang off the edge of the window, so we just decided to include the window border as part of these new graphics to fix that.

The result is that we can dispense with all our abbreviations, since we have the width to fit "Super Machine Denjuu" in it's entirety... but only for this one screen. Unfortunately other screens do not have enough space in their user interface to fit these indicators, and I don't particularly expect us to go redesigning these screens just to fit wider indicators everywhere.

That covers most of the major things we undertook in order to make the Field Guide redesign work. In most official translations, you wouldn't bother with such attention to detail, unless you had a ridiculous budget just for localization. There are plenty of games that don't get this treatment, and ship with awkwardly cramped UI, or weird abbreviations and typos, or look like they were restricted to half the line length they should have had. To us, that's not good enough.

Keitai Denjuu Telefang
ROM Hacking

Member of The Internet Defense League

This block will automatically put an annoying banner on the site whenever someone decides to pass a bill the Internet doesn't like

Total jerks