Tag: NES

Game Genie codes for Spook-o-tron

Spook-o-tron copies have been shipping out this month after the successful Kickstarter campaign last spring. I recently received my copy of the backer-edition cartridge and, as expected, the difficulty is pretty brutal. Given that and that there are probably many active players at the moment, it seemed like the perfect time for a follow-up to my previous Game Genie codes for The Incident post with (wait for it) Game Genie codes for Spook-o-tron!

Spook-o-tron Title Screen

As always, this post will get right to the codes so you’ll find them in the table below and I feel like this is a pretty good set. This time around I’m opting not to describe how each code works in detail like I did previously for The Incident. My thinking right now is that I want to get these out while they’re still fresh and I just invested allot of time in The Incident post so it’s hard to do another really long one right now. However, if you’re interested then shoot me a tweet on Twitter (where else would you do it?) and maybe I’ll do a followup describing the details.

The Codes!

Just some quick notes on these codes. I created them from my backer edition copy of the cartridge. All I can say with certainty is that they seem to work for me with my copy. As usual, my standard disclaimer applies, and I can’t be sure they’ll work for your or that they’re even safe to try. I assume everyone else with a backer edition copy probably has an identical ROM so they should work for those copies too.

If you have one of the higher tier copies then they might work–or not. It would really depend on if the numbered edition copies moved things around on the ROM image. The differences might be superficial as far as the program layout goes or it might not be. There’s no way for me to know without examining a numbered cartridge which I don’t own. The same goes for any eventual standard releases that might come out post-kickstarter–they might be the same and the code might work or they might not work.

Standard disclaimer: I provide these codes with the hope they are useful but I make no warranty to their usefulness, fitness for any purpose, or safety. You assume all risk associated with their use including but not limited to liability for any and all damages.

SXETYVVK Infinite Lives (they never decrement)
VOOGGSNO
VOOKGSNO
VOKKZSNO
Earn lives 10x faster
EXOGGSNP
EXOKGSNP
EXKKZSNP
Earn lives 10x slower
OXOKPIES Never earn any lives
PEKIGYLA Start with 1 life
ZEKIGYLA Start with 2 lives
GEKIGYLA Start with 4 lives
OXKKVLES Kill 1 enemy to win level
SZNTAIAX Enemies don’t move
AUKNSTAY Turn both cartridge LED lights on
EUKNSTAY Turn red cartridge LED light on
ENKNSTAY Turn both cartridge LED lights off

Obviously, some of the codes would conflict and shouldn’t be used in combination like the speed of extra-life earning or the number of starting lives.

Most of these codes make the game easier but a couple could be used to make it harder if somehow you are looking for an ever greater challenge. I agree with Brad Smith when he said that once the game is in your possession how you play it is really up to you–what the developer originally set is just a suggestion.

Cutting Room Floor

A single Game Genie code is just an instruction to change a single byte in the game’s ROM. You are essentially writing a patch or hack but you are limited by the number of individual codes the device allows you to enter and the number a user is actually going to be willing to transcribe. So, while in principle it’s possible to pretty much do anything, in practice we’re limited with what we can actually do with a code to only what can be accomplished using simple changes. That said, there’s a couple of codes that I tried to create but wasn’t able to.

First, I really wanted to make an invincibility code. I actually wrote one and it worked but it had a fatal flaw. If you don’t die when the enemies reach you then they tend to bunch up all in one spot. It seems that there is a bug (that otherwise probably can’t manifest) with the game where it locks up if too many bunch up in one spot (seems like a big issue for ghosts). It’s probably possible to fix this bug but probably not with just one or two codes so invincibility just won’t work.

Second, I wanted to find away to just make all the enemies die instantly so you’d get the points and go to the next level. This doesn’t work since we don’t even get close to this code until the blaster shots are checked for collision. An alternate would be to short circuit the collision so that a fire shot immediately kills an enemy without getting anywhere near it. This could have worked but the game checks collision in multiple places so there’d be too many bytes to change to make it all work.

Lastly, I tried to create a code where touching the player would cause the enemy to die instead of the player. This would have been really cool and given pretty much the same effect as I was looking for with the instant death code. This was a long shot and it didn’t work. The idea here was just to replace the code at the start of the kill-the-player subroutine to jump into the subroutine to kill an enemy after a bullet hit. I expected it would just crash but actually it just gave an invincibility effect but didn’t kill the enemy (it still suffered from the same invincibility crash issue I described earlier). I didn’t spend allot of time trying to understand why it didn’t work but the two pieces of code are in different parts of the program so it’s probably related to them expecting different parameters.

Game Genie codes for The Incident

It didn’t take long after I first became interested in NES homebrew to notice that there were basically no Game Genie codes available for any of the homebrew titles. That just seems wrong to me; why no cheat code love for the homebrewers? So, I’m taking it upon myself to help fill this void and I’m hoping this post will be the first in an occasional series each devoted to a new game.

One of the very first homebrew titles I played was The Incident by KHAN Games and it was actually this game which first made me think about wanting some homebrew cheat codes. Seems like the logical place to start and so without further ado here are some Game Genie codes for The Incident. The remainder of this post will just discuss the codes in detail and explain more about how they were created and how they work.

Standard disclaimer: I provide these codes with the hope they are useful but I make no warranty to their usefulness, fitness for any purpose, or safety. You assume all risk associated with their use including but not limited to liability for any and all damages.

SXNSYXVK
OXXONIEN
Purchase solutions for free
PAVNELAA Auto-play from next puzzle to end of floor
SZOGXTEY
SZNYKPEY
Purchased solutions still give credit for solving
XZKUUIEI
OXVTVYES
Enable sound test
EYKYPYAY Turn off both LEDs
ALKYPYAY Turn on both LEDs
ELKYPYAY Turn on the red LED only
SZUVPAAX Skip loading saved data

I don’t currently have functioning vintage hardware so these codes have been created and tested using an emulator and a RetroUSB AVS system. I believe they’d work with an original Game Genies and NES but have no means to test them at present.

Purchase solutions for free

I think this is the most obvious code for The Incident which allows you to “purchase” the solution for the current puzzle without spending any solution points. Solution purchasing is a built-in feature where you are awarded one point for every three puzzles you solve manually that you can spend to see a pre-recorded solution played back without having to solve it yourself. The codes SXNSYXVK and OXXONIEN allow you to do that without actually spending a point.

There’s two codes for this since there’s actually two operations involved with spending the point. The first is to check that you actually have at least one point to spend and so the code OXXONIEN suppresses this check. The number of solution points the player has is stored at $00A5 in RAM and when the player attempts to spend the point the following instructions execute to check that the value isn’t zero. The BEQ instruction jumps around the code immediately after it if the value is zero which is what skips starting the auto-play if you don’t have any points.

9DAA LDA $00A5
9DAD CMP #$00
9DAF BEQ $9DC1
9DB1 LDA #$01
...
9DC1 RTS

The cheat code changes the byte at $9DAF from $F0 for the BEQ instruction to $A9 for the LDA instruction (immediate mode). This prevents the jump regardless of the value so that the code to start the auto-solution playing always executes. The side effect is that the accumulator register gets set to $10 which was the offset being used by the BEQ instruction to jump down to $9DC1. This doesn’t matter since the next instruction is another LDA so the value is immediately valid again.

9DAF LDA #$10
9DB1 LDA #$01

The SXNSYXVK code suppresses the actual subtraction from the number of solution points owned. A single instruction at $D2FF accomplishes this by directly decrementing the RAM address using a DEC instruction:

D2FF DEC $00A5
D302 RTS

The cheat code replaces the $CE byte for the DEC instruction with $AD which also transforms it into a LDA instruction. This stops the decrement but has the side effect of setting the accumulator register to the number of solution points. This is not a problem since the subroutine exits immediately afterward and the caller doesn’t expect any particular value in the accumulator.

D2FF LDA $00A5
D302 RTS

You’ll always want the decrement cheat code since that actually prevents the solution count from being altered. The first code which skips the check is only necessary if the available points count is actually zero since the check it skips is satisfied anyway in any other case. If you suppress the check but not the decrement and have zero points then the 8-bit value wraps around and you end up with 255 points. This also works but is way more than you ever should be able to get and it doesn’t display correctly in the menu. It would also wrap around to again to zero if you happened to earn another point.

Auto-play from next puzzle to end of floor

This one is a little kludgy, I think, but its very important if your goal is to get The Incident to play itself. What this cheat code does is engage the same auto-play mode used by the game when you purchase a solution so that each puzzle just solves itself in continuous succession all the way to the end of the floor. The catch is that it doesn’t engage until you complete the initial or current puzzle so you have to either solve the first one manually or purchase the solution from the menu.

There’s a function located at $FB29 which is called every frame but just quits without doing anything except at the end of a level transition animation. This function does various things but one of those things is to clear the RAM byte stored at $007A which is the flag that indicates that a solution is being auto-played. This flag gets set when you select purchase-solution from the menu and then it stays set all through the auto-solving until this function clears it.

The clearing of this flag is the only thing that prevents the auto-play from continuing on the next level so if this doesn’t happen then the next level starts playing itself automatically as soon as it starts just the same as if you had selected it from the menu. That’s why these two instructions near the end of the function clear the flag after each puzzle is completed:

FB67 LDA #$00
FB69 STA $007A

Together the two instructions clear the accumulator register and then write that cleared value to the flag address in RAM to clear it out as well. The PAVNELAA code changes the value set into accumulator to one instead of zero so that the next instruction always turns the flag on instead of off which is why it causes all the remaining puzzles to solve themselves regardless if the flag was on or off before.

FB67 LDA #$01

If you are using this code then you must want the levels to auto-play so the fact that this unconditionally sets the flag is no big deal. However, this kind of rubs me the wrong way which is why I called it kludgy. The code I wanted to create was one that just left the flag alone so that it stayed turned off if it was off or stayed turned on if it was on. This means you’d actually have to start the auto-playing going by selecting it from the menu before it would auto-play the current and all subsequent puzzles on the floor.

The reason I didn’t make the code work that way is because there’s no way to accomplish that using only a single code and it seemed better to a have a little wonkiness than to require a whole extra code be entered and have an additional code slot be consumed. The reason for this is because the function actually clears the flag in two different places:

FB32 STA $007A
...
FB69 STA $007A

We could neuter the store instructions by changing them to something else so they don’t write the value like we did with the purchase-for-free code to get this effect but since there are two writes we’d have to do it twice which means two codes. I don’t know why the game does this twice but my best guess was just that it was done on accident since clearing it twice doesn’t have any added effect that the first write wouldn’t have already. The double clear is also the reason the PAVNELAA code attacks the second write since if we did the first one then the second one would just clear it and there’d be no net effect. Anyway, if you want the codes to just nullify the two writes they are ILUYXUSE and ILVNOUSE.

Purchased solutions still give credit for solving

These two codes are kind of my favorite since when used in combination with the codes from the previous sections it basically can be used to get the game to play itself all the way through and reach a “perfect game” end state. The same as if you actually played the game all the way through without ever purchasing a solution (assuming you start from freshly erased saved data). This is a god-send for those of us (me!) who are too stupid and/or lazy to accomplish this feat on our own.

At $CE0D there’s a function that awards credit for solving the puzzle that is called after a puzzle is completed and advancing to the next puzzle on the same floor. There’s a similar block of code starting at $F96F which does the same job when it’s the last puzzle on the floor being solved. In both cases the first thing the code does is check the $007A flag discussed earlier which is set if a solution is being auto-played and just skips to the end if it was set so that the player doesn’t get any credit.

CE0D LDA $007A
CE10 CMP #$01
CE12 BEQ $CE3E
...
CE3E RTS

F96F LDA $007A
F972 CMP #$01
F974 BEQ $F998
...
F998 ...

We want both of these blocks to always execute regardless of the state of the flag so that we get credit even if we didn’t actually solve the puzzle manually. Like with the check for zero solution points we can just convert the branch instructions into a load accumulator instruction so that the code always falls through. This has the same side effect of affecting the accumulator value but again it doesn’t matter since subsequent code resets it before the register is used again.

CE12 LDA $002A

F974 LDA $0022

It’s unfortunate we have to do this twice and use two codes but since the game does it in two different places we can’t avoid it; otherwise we wouldn’t get credit for “solving” every stage. I think the reason the game duplicates the logic is because its part of the level-completed animation which is different for the end of floor so it has to happen in this second place in the program also. Alternatively, it might have been possible for the second block to just JSR the first function but that’s just not how it’s coded.

Enable sound test

After completing all 120 puzzles a sound test option appears in the menu on the title screen I guess as a kind of prize for beating the game. The codes XZKUUIEI and OXVTVYES will enable this option without actually completing the game first. The first code causes the menu option text to appear where as the second actually allows it to be selected. If only one of the codes is used then the option can be seen but not used or (more interestingly) can be used but not seen. This requires two codes because the two separate operations each perform the is-the-game-completed check independently on their own.

After finishing the last stage the flag at $00EB is set in RAM. I’m not sure if this value is used just for the sound test or if it also controls something else but this is the variable that gets checked for the sound test option. For the display code, there’s a function at $BD46 which is responsible for actually drawing the menu option text. The first thing it does is check the flag then jumps to the end if its not set.

BD46 LDA $00EB
BD49 CMP #$01
BD4B BNE $BD67
BD4D LDX #$00
...
BD67 RTS

Just as before, we can change the branch instruction into a load and then the code always falls through and paints the text even if the flag isn’t set. The side effect of setting the accumulator register doesn’t matter since the next instruction resets it to something else.

BD4B LDX #$1A
BD4D LDX #$00

For the selection cheat code, there’s a set of instructions starting at $EFE1 which decides whether you can select the sound test option in a long block that executes each time you press select on the title screen. Again, this code just tries to jump down if the flag isn’t set.

EFE1 LDA $00EB
EFE4 CMP #$01
EFE6 BNE $EFF5
EFE8 LDA $004A
...
EFF5 ...

So, we convert the instruction in the same way. There’s no side effect since the next instruction resets the accumulator. Yawn.

EFE6 LDA #$0D
EFE8 LDA $004A

Manipulate the cartridge LEDs

The Incident cartridge uses a GTROM circuit board and mapper. This particular board includes two LED lights, one red and one green, which can be switched on and off by the game at pretty much any time. This was probably intended more as a debugging or diagnostic tool for developers but it could also conceivably be used by a game as some kind of indicator to the player. The Incident chooses to just leave the green LED turned on and the red LED turned off pretty much all the time except for brief periods when saved data is being updated on the cartridge (which is so quick that it’s pretty imperceptible).

Since a single piece of code controls this we can manipulate it to turn either light on or off to suit our preferences (just because we can). The GTROM board contains a single register located at $5000 to control bank switching and the control bits for the LED are combined into this register. The Incident uses a single function located at $F73F to update the register for bank switching and it also contains the logic for controlling the LEDs.

F73F TAX
F740 ORA #$70
F742 STA $5000
F745 RTS

The lower nybble (4 bits) of the GTROM register select the page for bank switching. The left-most (most significant) bit controls the green LED and then the next one to the right controls the red one. The remaining two serve other purposes that aren’t important here. The function expects the caller to set the desired page in the lower nybble of the X register which then gets copied to the accumulator by the TAX instruction. Then it sets 3 of the four upper bits leaving the most significant bit as zero using the ORA instruction. Finally, the combined values are written to the register which actually updates things on the cartridge board.

The $70 value (0111 0000 in binary) is what controls the LEDs. For the two LED bits zero means turned on and one means off. The green bit is left zero and the red bit it turned to one and so that’s why we normally end up with only the green one turned on most of the time. The code EYKYPYAY changes the $70 to $F0 (1111 0000 in binary) so that both bits are set and so both lights are off.

F740 ORA #$F0

The code ALKYPYAY changes it to $30 (0011 0000 in binary) so that both bits are turned off which turns on both lights.

F740 ORA #$30

Finally, the code ELKYPYAY changes the value to $B0 (1011 0000 in binary) so that just the red LED is turned on because only its bit is cleared.

F740 ORA #$B0

Obviously, it only makes sense to use one of these three codes at a time since they all affect the same address in memory.

Skip loading saved data

You might think that this last one is a little odd–and maybe it is. As you know, The Incident saves your progress to the cartridge so you can resume playing from the same previous state even if you powered off the console between sessions. The way it accomplishes this though struck me as a little odd.

The 6502 processor that powers the NES has a special region of memory known as the “zero page” which really just amounts to the first 256 bytes of RAM. Accessing this memory is a little faster than the rest of RAM and it has some other super-powers that make it prime real estate. So, not terribly surprisingly, The Incident keeps pretty much all the vital game data in this space like the current level, solution points, and everything else that gets stored between play sessions.

What I’d generally expect to see from any program is that, when saving important data, the information gets neatly packaged in a dedicated data structure and then written to the storage medium just as a desktop application would store data to a file. The Incident doesn’t do this and instead just writes the entire zero page directly to the flash chip. This does write out all the vital information it wants to save but it also stores lot of other more tenuous state information that inhabits the zero page that really doesn’t need to be saved, is not useful when restored, and it just along for the ride.

From a purely efficiency based perspective this is quite clever since there’s no need for fancy packing and unpacking subroutines–the information is just loaded directly back into the zero page when the game is rebooted. There is a theoretical danger with this approach though since the game is not merely reloading the game but its actually reloading parts of it previous state of execution. Generally, a program likes to start from a cleanly initialized state but this causes it to have information restored that might then need to be handled or just otherwise explicitly discarded. In principle, if the game had a malfunction and stored bad state data then it might prevent itself from running again even after a reboot since it wold just continue to load and run in an invalid state.

In practice, I’ve never actually encountered this so it’s not a real problem at this point as far as I know. More to the point though is that The Incident has a built-in function to erase the saved data but all it does is reset the data points associated with the game progression. It doesn’t actually wipe completely clean the portion of the cartridge storing the data like it is again brand new and this just rubs me the wrong way for no particularly good reason.

So, to bring this all together, the purpose of the SZUVPAAX code is to let you “start fresh” by skipping the load of the zero page data when the game first starts. Since all of RAM is erased at the very start of the boot process (pretty much all games do this) it means we end up starting from a zero-page that is completely zeroed out just like it would have been when the game was run for the first time. This really has no practical effect that’s any different than just using the erase function beyond soothing my paranoid psyche. However, if you did ever end up with a corrupted zero-page that prevented the game from rebooting this code could potentially rescue the cartridge by effectively purging the bad data.

The code itself is pretty simple. Early in the startup sequence at $E039, a call to the function located at $D3DA is made. The purpose of this function is just to copy the saved data from flash memory on the cartridge back into the zero page.

E039 JSR $D3DA

Again, we just change the JSR instruction to load the accumulator register from that address instead of jumping to the subroutine. The side effect of changing the register doesn’t matter since the function itself would have left the register in an undefined state after it returned anyway.

E039 LDA $D3DA

Wrap-up

Thanks for reading this far! I figure if anyone actually looks at this post then most will stop after the codes. I wanted to explain the codes a little bit but I didn’t mean to write this to be as long and it ended up being. If this does become a series of posts then I might just skip the explanations in the future but I hoped you enjoyed them none-the-less; writing Game Genie codes really is kind of a neat process.

An analysis of the Legends of Owlia password system

I’ve always been fascinated with video games that included “passwords.” There’s something mysterious and exotic about the whole idea. Especially as a child it gave me feelings of intrigue and mastery as if I was at the apex of some grand conspiracy. Games which framed the input of their passwords in this way undeniably contributed to this as did publications like Nintendo Power’s Top Secret Passwords Player’s Guide.

Of course, the wonder I experienced as a child falls away somewhat when you consider the business reasons for why game passwords were originally created and the fact they are really little more than tiny fragments of serialized data. Despite all that, I find that I still really like the idea of it beyond simple nostalgia and also especially enjoy the challenge of deciphering the coding systems and creating my own customized passwords. I’ve personally dismantled password systems from a number of classic games and learned some things about how they work and how they were put together in the course of it.

With my recent entry into the world of Nintendo homebrew I was delighted to find that the tradition of password driven NES games continues. Whether this is for purely nostalgic purposes or is still driven by the more pragmatic concerns of the developer isn’t always apparent to me but either way it has some intrinsic value in my opinion. I’m excited for the chance to study the creations of modern NES developers in comparison with classic titles.

My first victim, as it were, is The Legends of Owlia by Gradual Games and I’ll give my micro review of it right here: A good game but I wish there was more of it. This will be the first non-classic password system that I’ve deciphered and I’ll be speaking quite frankly about what I’ve found in comparison to other systems that I’ve seen. I don’t mean to be overly critical or for this to be taken as denigrative of the title. This was a game that I enjoyed playing and seems pretty well put together; I probably wouldn’t have expended all this effort on it if I had felt otherwise.

Encoding

Passwords in The Legends of Owlia are 10 characters long and use all the capital letters and all ten numerical digits as possible characters. This means that each character is one of 36 possible values or about 5.2 bits worth of data. Only 32 of these characters are actually used with the digits 6, 7, 8, and 9 being decoys that are never used in a valid password and automatically invalidate the entry if the player ever enters them into the game.

The use of decoys is common and is often employed by games to make it harder to randomly guess correct passwords or to just round out the set of possible inputs. In this case I think it’s the latter since Owlia presents the input selection as a nice 6×6 square matrix. A common alternative is to throw out completely one of the characters in a pair that are often confused for one another. So, Owlia could have just created (but did not) a 32 character set and threw out number 0 because it looks like letter O or throw out letter I because it looks like number 1 and so on. Neither approach is clearly better than the other.

Post2-Pic1

Owlia probably only uses 32 characters because that gives an even 5 bits of data per character and it is much easier to work with even bits than a fractional number. This means that the full 10 character password carries 50 bits or 6.25 bytes of encoded data. Each character represents a single number from zero to thirty-one and when you convert each character to the corresponding binary number and then paste them all together one-after-the-other you get the full 50 bits of data:

Post2-Pic2

Game passwords generally want to appear as random jumbles of letters and numbers and one method of creating this apparent randomness is to assign numeric values to the characters at random. This requires a lookup table to be built into the game so that it finds the value that was assigned to each letter as the user enters it. Owlia doesn’t do this and instead follows the much more straight forward approach of assigning the numbers in alphabetic sequence and then numeric sequence after that.

This means that the character A is equal to zero, B is equal to one, and so until Z which is equal to 25. The missing six values are assigned to the digit zero starting at 26 thru the digit five ending at 31. Since the numbers are assigned in a logical sequence they can be converted through a simple algorithm. The downside of this is that the password will appear much less random especially at the start of the game when most bits are zero (the password would contain mostly A characters).

Owlia achieves the appearance of randomness through another common technique used by many other games before it. This is the only method employed by Owlia to scramble the password and it is effective on its own but it’s also not uncommon to see it combined with one or more other techniques in other games. The technique used here it to split the raw password bits out into bytes and then scramble each byte using exclusive-OR.

The 6502 instruction for exclusive-OR is EOR and it operates on each pair of bits between two bytes; one in the accumulator and one from an immediate value or a memory location. It’s not technically accurate to say this but, for all intents-and-purposes, this means the NES can only XOR complete 8-bit bytes which creates a slight challenge with the 50-bit value that we have. The only solution I’ve seen for this—and the only one that I can think of—is to just split the 50 bits into bytes and encode each one individually which is exactly what The Legends of Owlia does:

Post2-Pic3

Two things might catch your attention in this illustration. One is that two bits are missing near the end. The other is that when decoded nearly all of the bits in this example password are zero.

The reason for the missing two bits (25 cents?) is because fifty doesn’t divide equally by eight but forty-eight does. Strictly speaking, there’s no reason why the game couldn’t have made use of these two bits in a fractional byte since it’s much less difficult than fractional bits. For whatever reason though the game doesn’t seem to need them and so chose to discard them which results in the final raw decoded password being 48-bits long or exactly 6 bytes.

Post2-Pic4

Some form of unused or wasted space is actually very common with various password systems. Most games’ passwords have a few spare bits that are always zero in game-generated passwords and are not validated when the password is decoded. In those cases and in this one specifically, this creates some space where hacked or otherwise custom generated passwords can insert a little extra data without invaliding the password. This could be used as a form of watermark or for another purpose. In this case the two bits don’t provide much extra space but you could still set these dropped bits to create versions of any password the game itself would never generate but that it still accepts.

As for the decoded bits being almost all zeros, this is interesting for two reasons. First is that the example password used in the illustrations is the first password the game generates immediately after starting a new game. In this password basically all things the password tracks like items collected or doors opened haven’t happened yet so they are all zeros and this is reflected quite clearly in the decoded raw password bits.

Second, since the password itself is just a big zero-block the letters and numbers of this password itself basically reveal the key used to decode it. This is because when XOR is used to scramble data the effect is just that any bits that are set in the key simply invert those corresponding bits in the data. This allows the encryption to be performed or reversed by just XORing the data and the key each time. In this case since nearly all the data bits can be assumed to be zero we know that nearly all the bits that are set in the password are set because they were inverted which in turn reveals which bits are set and not set in the key.

This basically makes it trivial to derive the key and decode—or encode—any password but this is only easy because Owlia doesn’t employ any other protections or randomizations on the data. As discussed earlier, the numerical value for each character is easily predicted but if they had been scrambled with a lookup table or another method it would have been much harder to crack by hand. In the next section as we delve into the actual payload of the password we’ll continue to see that protection of the data and prevention of tampering didn’t seem to be a big design goal for this particular system.

Data format

In the last section we reversed the encoding procedure used by passwords for The Legends of Owlia and revealed the password’s raw data bits which turned out to be a 48-bit value or just a block of 6 bytes. We know these bits contain all the information the game “saves” between play sessions because when we enter the password certain things like money, items, and the current level are restored. Therefore, we know this isn’t just a single long number but actually multiple individual values or numbers, which I will refer to as “fields,” that must all be smushed together to from the one larger value.

So, our next task is just to separate out the individual fields so we can see exactly what data is being carried by the password and how it’s being stored. At this point, since we’ve decoded the raw bits the easiest thing to do is just gather some different passwords and remember what we did in the game in-between those steps. Then we can just see which bits are changed by doing those things which reveals the location and purpose of the different fields within the longer binary value.

For example, the first thing I did was to get some passwords with different numbers of bombs, lanterns, and hearts (health) since these are easily collected at any point in the game. This technique allowed me to pretty quickly and easily break apart the password into all the separate fields which, for the sake of brevity, I will just document in illustration below:

Post2-Pic5

As we can see, the values are neatly packed in a simple way that makes it easy to find and understand the value. All the bits of a single field are grouped together and are consistently stored left-to-right with the most-significant bits first. This continues the theme from the encoding where it seems like the game doesn’t care too much about trying to prevent someone from cracking the code, as it were. The developer could have tried to scramble the order of the bits which would have increased the complexity of the encoding and decoding programs but would have also made deciphering the meaning more difficult.

We’ll start with the simplest and easiest fields. The fields labeled E, F, and G are, respectively, for the number of Bombs, Lanterns, and extra Hearts (“Health”) held by the player as seen on the pause screen. Nothing fancy here and all possible values from zero to seven are used as expected to just mean the number of the particular item held. Since only tree bits are allocated to each it means the maximum number of the item has to be only 7 (since 3 bits gives only 8 possible combinations including zero) which explains the reason why the cap isn’t 9 like we might have otherwise expected.

Field I is the heart of the password in that it keeps track of overall progress through the game. You could describe this as the “level” the player is on since it gets incremented each time a dungeon or major milestone is passed. This value starts out initialized to 1 at the start of the game and so is the only field which doesn’t start as all zeros. It increments to 2 when you speak with Silmaran in the forest and then once again after clearing each dungeon.

Value Level After Event
0 Not Used Breaks password
1 Town New Game
2 Forest Met Silmaran
3 Tundra Beat forest dungeon
4 Mountain Beat tundra dungeon
5 Island Beat mountain dungeon
6 Docks/Submarine Beat island dungeon
7 Mermon’s Fortress Beat submarine dungeon

This part of the password is very well designed. Some of the other systems I’ve seen have really messy methods of tracking the game progression using multiple fields that can conflict in odd ways. In those cases it’s often possible to write passwords were the system accepts the password but the game is in state which can’t be completed (although I guess shame on us from trying to break it like that?). That’s probably because those games just dump raw variable values from RAM directly into the password. I suppose that works but it’s messy and is not as efficient space wise. Owlia‘s approach on the other hand is just to increment this master-counter during major transitions and then supplements that with additional fields that get reused per level which we’ll discuss next. This is a very clean and efficient approach and I like it a lot; kudos to the developer on this one.

The single-bit entered-dungeon flag plus a byte of dungeon-specific flags are in fields B and C respectively and these fields are reset and reused each time the primary counter is incremented. For the dungeon flag it gets set once you first enter each of the five dungeons from their respective overworld or enter the submarine from the docks. Once the flag is set the game always starts at the dungeon entrance until the captive owl is rescued  even if you exit the dungeon and collect a new password.

The flags byte is just a collection of eight on/off switches and each one tracks whether a particular key has been collected, a particular door has been opened, or a specific chest has been opened. This field is really important to allowing you to save and resume your play of a dungeon since it basically tracks how much of the overall level has been solved. There are only eight of these flags though which is why it’s important that the field gets cleared and reused in each dungeon. Since the field is reused the meaning of each bit varies by each dungeon and not all the dungeons use every bit since they don’t always need all of them.

Bit Forest Tundra Mountain Island Fortress
1 Key 1 Key 1 Key 1 Key 1 Key 1
2 Key 2 Key 2 Key 2 Key 2 Key 2
4 Door 1 Door 1 Key 3
8 Door 2 Door 2 Door 1 Chest Key 4
16 Chest Chest Door 2 Key 3 Door 1
32 Chest Door 3 Door 1 Door 2
64 Chest Door 2 Door 3
128 Key 3 Door 3 Door 4

Overall, this is excellent execution and much better use of space then I have seen in some other systems. It’s worth noting the game doesn’t seem to validate the flags so you can enter combinations that don’t make sense such as unlocked all the doors but claimed no keys. It also doesn’t care if data is present in bits that are unused or for a “level” like the town or the docks that don’t use the flags at all. In those cases this is a little bit of additional unused space where extra data could be hidden but it’s not consistently available.

Field H is a little bit of a disappointment coming out of the previous discussion. This field is just a counter for the current number of keys held by the player. That is it’s the number of keys that have been found but not yet used to open a door. It’s really just wasted space because this information could easily be recomputed from the flags by counting the number of keys found and subtracting the doors opened. Three bits are used since the player might have anywhere from zero to four keys (5 possible values). The game doesn’t validate this value either so you can give more keys in a custom password than the game would ever award normally. I think this field was just added for programmer convenience but it’s not strictly necessary.

That leads us into the final remaining field but this last field covers half of the total bits in the entire password. This field took me the most time to identify and fully understand because it defied my expectations. Just from playing the game first I knew that money (GP) in the game was always collected in increments of 100 GP so the player’s total GP was always evenly divisible by 100. I also assumed (correctly this time) that the GP cap was 999,900. This means the password could store any amount of money using only 14 bits because it could be saved as a multiple of 100. I expected to find that 2 of the remaining bytes were used for money and the third for another purpose but it wasn’t working out and kept confounding me.

I eventually realized that all three of the remaining bits formed a single 24-bit field which is for the exact number of GP the player has. Bits marked A are the 8 least-significant of this value, followed by bits J in the middle, and bits D are the most significant. Since this value is 24-bits it can save any (unsigned) number from 0 to 16,777,215 but only 10,000 of those values are possible to appear in a valid password. This works out to a utilization of roughly 0.06% and so this is a large waste of space.

The other field I was expecting to find was a checksum field which was used to validate the entire password. Every other system I’ve investigated has included a field which is computed from all the others using some algorithm (usually simple addition) and this is normally what allows the game to tell the difference between something valid and a player just trying to enter random numbers. When the password is reentered, the same value gets recomputed and if the recomputed value matches the one in the password itself then the password is accepted and otherwise it gets rejected.

Owlia doesn’t have this and it was a bit unexpected to find it was missing. Owlia still has some mechanism for checking the password but it works differently. When a password is entered into Owlia the game checks to make sure the value of each field is valid and rejects the password if one or more fields are invalid. The issue with this is that the only fields that can contain invalid values are the GP and event counter fields. All the others are valid with any possible value so there’s no way to invalidate them. It can also reject the password if the dungeon bit is set for a level that doesn’t use it (e.g. the Town).

Since 50% of the entire value is covered by GP bits and since that field has such a low ratio of valid values it means that any random entry is still very likely to be rejected. For this field, any value that is larger than 999,900 or that is not evenly divisible by 100 is invalid and breaks the password. Any random combination that you punch in is likely to not meet these constraints and so does get rejected. However, the third, sixth, and seventh characters of the password do not contain any bits for the GP value and so you can change these values freely on any otherwise valid password and get it to work 100% of the time—try it and see! The eighth character contains the event counter which is also going to be valid most of the time so you can also change it and have it work in most cases.

This validation approach is less comprehensive than the more common checksum approach (some games do both) because it ends up leaving some of the characters “unprotected” from tampering. This seems to continue the theme from the previous section where the “security” of the password is not a large concern for Owlia. There really isn’t anything wrong with this; the developer doesn’t have to be trying to prevent players from casually modifying passwords. However, this also creates a usability issue since when I enter a password, I expect it to work only if I enter it correctly and for the game to catch my mistakes. Since nearly half the characters can accept any value it means that I can easily make a mistake and still have the game accept it. For the third character especially this could be a problem since that contains flag values which if incorrectly restored could remove some of my progress or worse leave the dungeon in a state where it’s impossible to complete it.

To conclude my commentary on this, the Owlia system makes a really strong showing on the tracking of progress and state information doing this part elegantly and efficiently. It falls short on overall space efficiency though and on data validation. My recommendation on how this system could have been improved would have been to allocate only 14 bits to the GP value as I described earlier. I would then suggest allocating an additional 5 bits to some form of checksum. This would improve the data integrity issue and use only 40 bits which means we could shorten the password to just 8 characters. This would improve the player’s experience by reducing the number of characters that have to be entered and be more likely to catch input mistakes. An additional optional change would be to jettison the keys field entirely since that value can be recomputed from the flags data. We could then add those bits to the checksum for added validation strength or use them for another purpose entirely.

Custom passwords

My intention with this article wasn’t really to teach the reader to encode or decode the passwords themselves (although there is definitely enough information here for that if you want to try) but just to break it down and examine the strengths and weaknesses of the system in comparison to others. However, when I’ve made similar write ups in the past I always included a table of custom generated passwords. So I’ll continue that tradition and end on this table of passwords that will take you to any point in the game with 100,000 GP and all the items maxed out.

Level Step Password
Town Overworld GCSKIHKRFW
Town Dungeon
Town Boss
Forest Overworld GCSKIHKSFW
Forest Dungeon GASKIHKSFW
Forest Boss GAVSIHKSFW
Tundra Overworld GCSKIHKTFW
Tundra Dungeon GASKIHKTFW
Tundra Boss GA3SIHKTFW
Mountain Overworld GCSKIHKUFW
Mountain Dungeon GASKIHKUFW
Mountain Boss GBMSIHKUFW
Island Overworld GCSKIHKVFW
Island Dungeon GASKIHKVFW
Island Boss GBMSIHKVFW
Docks Overworld GCSKIHKWFW
Docks Dungeon GASKIHKWFW
Docks Boss
Fortress Overworld GCSKIHKXFW
Fortress Dungeon GASKIHKXFW
Fortress Boss GBNSIHKXFW