We’re a gaming family here at the Backlog Odyssey household, and one of our favorite things to do is rev up the ole nostalgia motor by seeking out some of our favorite childhood games and gifting them to each other. This of course has had its ups and downs since not all the games we look back fondly on have turned out to be as good as we remembered, and certainly not always the easiest to find as well, but it’s fun all the same, even if all we get out of it is to relive our childhood. So, for this holiday season, I wanted to perpetuate the time honored tradition by finding a game that Charleen (OctoTako) has been eyeballing for a while now. A copy of DinoCity on the SNES with all of its accouterments. Because being able to hold the original box in your hand, and being able to read its manual, is part of the whole experience!
Now, I could have gone down the simpler path of finding a North American copy of the game, but after doing some research I found that when localized, some of the content was changed. Despite the fact that this game is based on an American film called Adventures in Dinosaur City, changes included sprite alterations because of Nintendo’s strict rule against the “over-sexualized depictions of women”, as well as the removal of the easier “Normal” difficulty. I’m sure it’s no surprise to those who know me, but once I figured that out, there was really only one option – to import the original Japanese version of the game! I mean, I’m not going to pass up the opportunity to see what the heck they changed, and if it was really as bad as it seemed. Plus the cover art for the Super Famicom version was way cuter! A major plus since it was a gift for Charleen.
The only problem was, the game is in Japanese, and neither of us speak nor read a lick of it. But, I was determined to play it, and in a spurt of overambition I thought it would be fun to cut my teeth on the ROM hacking world by trying to translate it myself. Plus, how cool would it be if I added a few extra tidbits to personalize the game and make the gift extra special? All with only 4 weeks until the holidays. So, without further ado, here’s my telling of the trials and tribulations of creating my very first translation hack for Dinowars – Kyouryuu Oukoku e no Daibouken (a.k.a. DinoCity):
ROM hacking to any degree is nothing short of intimidating. I mean, people have been doing it for decades now, so there’s a vast catalog of information out there if you’re willing to dig, but a lot of it is buried deep inside forums and it’s often cryptic in the worst ways. Fortunately, there’s a fantastic resource out there that tries to aggregate a lot of that information in one convenient place – romhacking.com. Truly an invaluable resource for a budding ROM hacker like myself. That said, I still had a ton to learn if I really wanted to execute on my ambitions! I’m sure it’ll be beneficial to learn 65816 assembly at some point, that’s the microprocessor (or a form of it) that the SNES uses, as well as compressions/decompression techniques, or whatever other crazy shenanigans the pros use, but I was lucky enough that what I wanted to do, and the game I wanted to do it to, wasn’t overly complicated. In fact, it only required a few tools, some investigating, and a lot of gumption. Also, it helped a ton that the game already had a localization, and I could reference that version to situate myself when needed.
Now that I was oriented, I needed to figure out where to start. I mean, I knew what I wanted to do (translate the dang thing), but where was that data stored and how? Did the Japanese ROM have an English font, or would I have to insert it myself? All valid questions, and to help me answer them, I needed to play it. Well, enough of it so I could see some Japanese characters. To do that I needed an emulator, but not just any emulator, I needed one that had debugging capabilities – an emulator like bsnes-plus. For those that don’t know, a debugger is a tool programmers can use to step through code, assign breakpoints, and pause code execution when those breakpoints are hit. Basically it lets you see what your program (the game) is doing at a specific point in time, or when certain conditions are met.
With the emulator in hand, it was time to run the game and get to a screen with some Japanese text, which again lucky for me was within the first few seconds of booting it up. Using the emulator’s debugger I was then able to pause the game’s execution and take a peek behind the scenes. One thing that’s really nice about emulators like bsnes-plus, is that through the debugger you are able to view a lot of the graphical assets stored within the video memory (VRAM) and within the actual game’s ROM. So, I pulled up the VRAM viewer, specifically looking at the currently loaded tile set for the current scene, and low and behold! Not only did the game have a Japanese font, but also an English one! Which meant it was time to figure out where in the ROM the text strings were stored, and which values were associated with which English font characters so I could start replacing them with my translated text.
There are a few different ways to insert translated text into a game’s ROM assuming the text itself or the font isn’t compressed. One of which is to create what’s called a character table, which has you mapping values to a font character and then using that to extract a sequence of text. Then you’d be able to translate that text and reinsert it into the same place using those values. This of course may be an oversimplification but, let’s say we had the word TEXT and each of the characters had the following values (in hexadecimal): T = 18, E = 19, X = 1A. If we wanted to replace the word MOON (e.g. M = 1B, O = 1C, N = 1D) with the word TEXT, we’d go to the location within the ROM where that string is located and replace its values (1B 1C 1C 1D) with the values of TEXT (18 19 1A 18).
Now, this is useful if you have a novel’s worth of dialogue in a game (like an RPG) or if the game didn’t use standard character encoding, but with Dinowars there was only about 30 or 40 lines of text that needed to be translated! Some during the intro, some during the ending, and few other labels here and there. So the whole character table thing seemed like overkill and would have probably taken much more work than the approach I actually ended up taking, especially since it seemed the game used one of those standard encodings. This is where the next tool I needed came in handy – the almighty hex editor! Basically it’s like a text editor, except you can use it to see the actual data stored in a file (the ROM), and modify it using hexadecimal values. In this case I used wxMEdit, because it had the added benefit of being able to view the data encoded in a format called Shift-JS, the aforementioned standard the game used. A character encoding standard used for Japanese characters that’s conveniently used in a lot of retro games. Which in turn allowed me to view the actual Japanese text found within the ROM. You see, another handy feature of a hex editor like wxMEdit is that within the editor window there’s a column that’ll show you the decoded data using your chosen encoding (Shift-JS), making finding any non-compressed text strings, and updating them, easier. Well, a bazillion times easier than trying to parse straight hex values off the top of your head anyway.
This is also where my inability to read Japanese started to get in the way. You see the problem with looking at a ROM’s data through a hex editor is that a bunch of these values/characters can show up all over the file, and it’s only at specific points, and in specific lengths within the ROM where strings of these characters will actually be associated with the text you see on the screen while playing the game. In short, some of it is data and some of it is actual text, and to someone who doesn’t read Japanese it all looks the same! The points within the ROM where this text exists isn’t technically random since they are most likely determined within the game’s code and when the game was compiled, but since we don’t have access to the original source code, it’s our job to hunt those locations down. Either by using the debugger, stepping through the disassembled ROM’s code, and extrapolating the info from there, or by brute forcing it and scrolling through the ROM’s data until you find it. In my case, I used the localized ROM to get an idea of where the text COULD be stored. I say could, because there are differences between the two ROMs outside of just their translation, which could and did shift some of the data a bit. Despite being in slightly different locations, comparing the two ROMs helped me track down where all of the text was within the game, and now it was time to try my hand at “translating” them.
The high from finding and extracting Dinowars’ text only lasted for a short time however, because there were a few other peculiarities with how the text was stored within the ROM that created more than a few roadblocks. The first rearing its ugly head when trying to translate the names of each of the game’s protagonists. For the most part it went smoothly, and when I added the translated text, it showed within the dialogue window just as I expected! Except for one name in particular. CHAR. The name I wanted to use for the second player, conveniently named after Charleen! You see, whenever I changed the text, weird symbols would show up above some of the font characters, and for the life of me I couldn’t figure out why. That is until I investigated the tileset used for the font. You see, in Japanese, a kana character can be modified by adding an “accent” symbol, similar to say the ‘~’ over the ‘N’ in jalapeño, and many of these symbols were found within it. So, to fix it, I just removed those symbols from the tileset. Well, technically they’re still there, but are now invisible. If I was much more thorough I probably could have pinpointed where in the ROM it triggered the use of those symbols and disable it somehow, but this simple fix worked for me, and my font based woes were resolved!
The next issue I ran into was figuring out how the game determines when a line of text should break to the next line, and when it should move on to a new dialogue window. Which was different based on which part of the game you found yourself in! For example, when you’re in an interactive dialogue sequence, a “\n” signifies a new line and “\r” signifies when to move to a new window when you press the confirm button. However, when in the intro sequence, or a cinematic sequence, each line needed to be prefixed with a specific set of hex values. Which mostly took some trial and error, as well as observing patterns within the text sequence’s data to figure out.
Aside from experimenting with line length between line breaks, there was one last puzzle to solve before I could truly start translating the text in the game. That my friends, was trying to figure out how the game distinguished between hiragana characters and katakana characters before printing them to the screen. Which took me way longer than I’m willing to admit! Before figuring it out, none of the dialogue really made any sense when I pasted it into my hackneyed translator of choice – DeepL. That’s because before it’s interpreted by the game engine, all of the text in the game is written in katakana. This Japanese character set is typically reserved for non-traditional or foriegn words. Meaning, when I pasted a line of text that was all katakana into the translator, it had no idea what the heck it was trying to say! That is until I figured out what these seemingly random “\H” and “\K” tags found throughout each line of text meant. I know, it seems obvious now, but yes the “\H” does indeed mean hiragana and “\K” means katakana. To say I was kicking myself, is an understatement. Anyways, after converting the line fragments tagged with “\H” to hiragana, and piecing it all together, everything fell into place! I was finally able to get legible translated text! Now, I still needed to “localize” the wording a bit so it felt a little more natural and a lot less “literal”, but I was well on my way to finally getting this “hexlation” up and running! Oh and one last thing, I realized the hard way that if you DON’T remove all the “\H” and “\K” tags after translating each line, your fancy new english text that you worked so hard on, will still show up in the game with Japanese characters! (╯°□°)╯︵ ┻━┻
With new tools and new knowledge in hand, it was all down to doing the work and getting the translation done. Which turned out to be super fun, especially when adding some small personalizations that weren’t true to the script, but would hopefully add that extra zing. It didn’t take as long as I thought it would either, so within a few days I had a working prototype of my ROM hack. However, there was one last thing that bugged me every time I booted the game up to test it: the title screen. Not that there was anything wrong with it per se, but after putting so much work into translating the text within the game everywhere else, it just didn’t seem complete to leave the title screen untouched and still in Japanese. The problem was, that text was stored as a set of sprites and a tile map, so I couldn’t just edit it by changing some characters in the ROM file. No, this time I would have to figure out how to modify said sprites and reinsert them into the ROM.
Luckily, I had some experience with this when I modified the font to remove those special characters that kept showing up over particular fragments of text. So, like when trying to find the font in the game, I booted it up in our trusty emulator, got to the title screen, opened the debugger and looked in the VRAM viewer to find where the sprites used for the title screen might be stored. Now the interesting thing about how graphics for the SNES are stored is that they can be found in different formats known as bit depths, which basically states how many colors within a given palette that any given sprite can use. With which there are a few (2bpp, 4bpp, 8bpp, and MODE7) and as long as you know where a palette is stored in a ROM and what bit depth it uses you can easily find those sprites with the proper colors when scrolling through a ROM’s data. Figuring that out is the challenging part. That said, with the aid of a few more tools like SNESPal to find palette sequences, and SNESTilesKitten to view the graphical data in the various bit depths, as well as the emulator’s VRAM viewer for reference, it’s made a whole lot easier.
Like when translating the game, once I had the proper tools and the proper knowledge it was just a matter of extracting the sprites, making my modifications and putting them back in. The only other hurtle I ran into was the order that the sprites were stored, so I had to chop up my modified sprite appropriately so it would render properly when drawn to the screen. Which more or less took some trial and error, as well as interpreting the patterns I was seeing with how the original sprites were stored. When it was all said and done, I was left with a brand new “translated” title that matched the style of the old. Again, it was a word for word localization, but a fun interpretation.
You know, going in I wasn’t sure if I was going to be able to pull this whole thing off. I knew it was ambitious, but ROM hacking has always interested me, and it seemed like a perfect opportunity to try my hand at it. Plus, if I was able to pull it off, I’d be able to produce something extra special as a gift to my wife. There were definitely ups and downs, but in the end I truly learned a lot, and now I’m much less intimidated by the phrase “ROM Hacking”, and I have no doubt I’ll be trying it again. I mean, now that I’m a seasoned noob, the possibilities are endless!
The best part is, we now have a personalized localization of one of Charleen’s favorite games, and now that the holidays are over, and the surprise revealed, we can enjoy it in all of its glory! No doubt we’ll be talking about it in the future.
If you’d like to try the translation patch for Dinowars – Kyouryuu Oukoku e no Daibouken you can find and download it on romhacking.net right now! As for the ROM, I’ll leave that up to you. And if you play it, I’d love to hear your thoughts, so tweet at @BacklogOdyssey and let us know!