We are a 3 person team. Here are our games so far:

Announcing Human Resource Machine

Human Resource Machine title

We here at Tomorrow Corporation have been busy getting married, making babies, and other wasteful, unprofitable activities – but we’ve also managed to build a new game!

Job Applicant Number OneHuman Resource Machine is a puzzle game for nerds. Use your little workers to solve each level’s puzzle, and get promoted up to the next floor. Repeat. Each level is one year.

Self improvement tip: Our previous games have all taken 2-3 years to build so far. This one took only 9 months – as much time as it takes to build a new human – and it’s felt exciting and liberating the whole time. We hope you have as much fun with it as we have!

Trailer and more info in a few days…

Konichiwa, Japan!

LittleInferno_JP_titlescreen
Thanks to Nintendo of Japan’s outstanding localization team, Little Inferno is officially out in Japan for the Nintendo Wii U! Tomorrow Corporation was honored that the Big N chose to bring over Little Inferno, and even more honored when it was announced on Japan’s Nintendo Direct broadcast last week.


Success!

Localization was a success.

Beyond translating the game, NOJ was a big help coming up with new combos for the Japanese audience – especially since we here at Tomorrow Corporation are woefully behind on our Japanese puns and humor. I would not have heard of the phrase “Marshmallow Girl” or known that there was a rabbit that lived on the moon were it not for the localization team’s tireless efforts.

Arigato, everyone!

And arigato to everyone following our site. It’s been a while since we’ve posted news, but that should be changing in the next month or two. Stay tuned…

Retro Game Internals: Punch-Out Passwords

The NES game “Mike Tyson’s Punch-Out” uses a password system to allow players to continue from certain points in the game. Each password consists of 10 digits, each of which can be any number from 0 to 9. There are 2 kinds of passwords that the game will accept, which I’ll call “regular” and “special” passwords. Special passwords are specific sets of 10 digits that the game looks for and reacts to in a unique way when they are entered. The complete list of special passwords is as follows:

  • 075 541 6113 – Busy signal sound 1
  • 800 422 2602 – Busy signal sound 2
  • 206 882 2040 – Busy signal sound 3
  • 135 792 4680 – Play hidden circuit: “Another World Circuit” (must hold Select button and press A + B to accept password)
  • 106 113 0120 – Shows credits (must hold Select button and press A + B to accept password)
  • 007 373 5963 – Takes you to fight against Mike Tyson

The other kind of passwords that the game accepts are the regular passwords. Regular passwords are a coded representation of the progress that you’ve made in the game. The game data that is encoded into a regular password includes:

  • Number of career wins
  • Number of career losses
  • Number of wins by knockout
  • Next opponent to fight

Encoding Passwords

We’ll use an example game with 24 wins, 1 loss, 19 knockouts and starting at the world circuit title fight against Super Macho Man to see how passwords are generated.

The process of encoding this game state into a password begins by collecting your number of wins, losses and KOs into a buffer. The game represents each number in binary-coded decimal form with 8 bits per digit and 2 digits for each value. So for our 24 wins, that’s one byte with the value 2, and a second byte with the value 4. Then comes the pair of bytes for the number of losses and one more pair for KOs for a total of 6 bytes of data. The diagram below shows these 6 bytes with their values in both decimal and binary on the bottom.

punchout01

The next step is to generate a checksum over those 6 bytes. The checksum byte is calculated by adding the 6 individual bytes together and then subtracting the result from 255. In our case we have 2 + 4 + 0 + 1 + 1 + 9 = 17 and then 255 – 17 = 238.

Next we shuffle some of the bits from the 6 bytes into a new buffer. We can think of the new buffer as a single 28-bit intermediate value that we’ll begin to fill in piece by piece. The bits from the first buffer are split into groups of 2 and moved around to different hard coded positions in the second. This is the first of a few steps whose sole job is to obfuscate the data make it difficult for players to see how passwords are generated.

punchout02

Notice that not all of the bits from the original buffer are transferred into the new intermediate buffer. These bits are ignored because they are known to always be 0. Your number of losses in particular only needs to contribute 2 bits of information to the password because of the rules of the game. If your total number of losses ever gets up to 3, you’ll get a game over and never get a password. Therefore, you only need to be able to represent the numbers 0, 1 and 2 for your number of losses and that requires only 2 bits.

Next we shuffle more bit pairs into the intermediate buffer. The first four pairs come from the checksum value that we computed earlier. The other pair of bits comes from the opponent value. The opponent value is a number that tells which opponent you’re going to fight next after you enter your password. There are three possible opponent values that can be used:

0 – DON FLAMENCO (first fight of major circuit)
1 – PISTON HONDA (first fight of world circuit)
2 – SUPER MACHO MAN (last fight of world circuit)

Since we wanted to generate a password that puts us at Super Macho Man, we’ll use 2 for our opponent value. The checksum and opponent value bits are then shuffled into the intermediate bits as follows:

punchout03

The next step is to perform some number of rotations to the left on the intermediate bits. A single leftward rotation means that all of the bits move one place to the left, and the bit that used to be the leftmost bit rotates all the way around to become the new rightmost bit. To calculate the number of times we’ll rotate the bits to the left, we take the sum of the opponent value and our number of losses, add 1, and take the remainder of that result divided by 3. In our case we have 2 + 1 + 1 = 4. Then the remainder of 4/3 is 1 so we’ll rotate the intermediate bits to the left 1 time.

punchout04

At this point the intermediate bits are thoroughly scrambled and now it’s time to start breaking them apart to come up with the digits that make up our password. Passwords need 10 digits so we’re going to break our 28 intermediate bits into 10 separate numbers that we’ll call password values P0, P1, P2, etc. The first nine password values will get 3 bits of data each, with the final value getting just 1 of the intermediate bits. To round out the final password value, we will also include bits that represent the number of rotations we performed in the previous step.

punchout05

Finally we add a unique hard coded offset to the password value in each position. The final password digit is then the remainder of that sum divided by 10. For example in the seventh position we use an offset of 1, so we have 5 + 1 = 6, and then the final digit will be the remainder of 6/10 which is 6. In the fourth position the offset we use is 7, so we have 5 + 7 = 12, and then the final digit is the remainder of 12/10 which is 2.

punchout06

Now we have the final password digits which we can try out in the game.

punchout07

Decoding Passwords

The process of decoding a password back into the numbers of wins/losses/KOs and the opponent value is a straight forward reversal of all the steps outlined above and is left as an exercise for the reader. There are two notable mistakes however that the game makes when decoding and verifying player supplied passwords.

The first mistake happens in the very first step of decoding a password which would be to subtract out the offsets to get back to the password values. The original password values contained 3 bits of data each, which means their values before the offsets were applied must have all been in the range 0-7. However, a player might supply a password that results in a password value of 8 or 9 after the offset is subtracted out (modulo 10.) Instead of rejecting such a password immediately, the game fails to check for this case and instead allows the extra bit of data in the password value to pollute the collection of intermediate bits in such a way that passwords are no longer unique. Because certain intermediate bits could have either been set by the password digit that they correspond to OR the extra bit of a neighboring password value, there are multiple passwords that can now map back to the same set of intermediate bits. This is why you can find different passwords that give you the same in-game result, where as they would have been unique otherwise.

The second mistake is a bug in the logic the game uses to try to validate the data after decoding the password. The conditions that the game tries to enforce are:

  • checksum that is stored in the password matches what the checksum should be given the win/loss/KO record stored in the password
  • loss value is 0, 1 or 2
  • opponent value is 0, 1, or 2
  • rotate count stored in the password is the correct rotate count given the loss value and opponent value that were stored in the password
  • all digits of win/loss/KO record stored in the password are in the range 0-9
  • wins is >= 3
  • wins is >= KOs

If any of these conditions are not met, the game intended to reject the password. However, there is a bug in the implementation of the final check (specifically when comparing BCD encoded numbers.) Instead of actually checking for wins >= KOs, the game will allow cases where the hi digit of wins is 0, the lo digit of wins is >= 3 and the hi digit of KOs is less than the lo digit of wins. For example, a record of 3 wins, 0 losses and 23 KOs will be accepted by the game (as demonstrated by the password 099 837 5823) when this was intended to be rejected (since you can’t have won 23 fights by knockout if you’ve only won 3 fights total.)

Conclusion

The particular details of this encoding scheme are unique to Punch-Out, but the general idea of taking some important bits of game state, transforming them in a reversible way to obfuscate their relationship to the original game state, and then using them to generate some number of symbols to show to the player as a password is fairly universal. Checksums can be used to make sure that accidental random changes to the password (if your finger slips while entering it) are most likely to result in an invalid password instead of some other password representing a random other game state.

If you’d like to offer feedback or keep track of when new posts in this series become available, you can follow me on twitter @allan_blomquist

(This is part 1 of a series – Next)

Talkin’ About Little Inferno

Title Screen

I gave a talk about the things we learned while making Little Inferno at GDC this year,but completely forgot to post it here. There were some difficulties with sound during the presentation, so I ended up singing half of the lyrics of the jingle on stage. With no back up audio. In front of 600 or so people.

Despite the technical difficulties, the talk went pretty well! If you’re interested in learning about the story behind Little Inferno, it’s worth a gander. Just please ignore my bad singing.

Something Else is Burning

In other news, we’ve been quietly prototyping a few different game ideas for a little while now. Nothing new to report just yet, but it has been nice to go back to our roots. Strange to think we wrote that paper almost 9 years ago!

 

 

 

Retro Game Internals: Contra Conclusion

To round out my discussion of Contra I’m going to cover a few miscellaneous topics that don’t warrant a full writeup on their own. Some of these things are details of the game’s programming and some are just interesting things about the game itself that I never knew before. I’ll start off with a table of contents for this series for easy reference and then dive into the last few details.

Previous Posts about Contra

Random Numbers

Contra has a single global 8-bit value that it uses as the source of randomness throughout the game. The way that it updates the random value each frame is kind of interesting in that it doesn’t implement any particular algorithm that you can call on once per frame to get the next number in the sequence. Instead, the next random value is generated by spinning in a tight loop during the time that the game is idle and waiting for the next display frame to begin (while waiting for the vblank interrupt.) During that time, the game continually adds the current frame counter value into the random number over and over again until the video hardware in the NES signals to the game that it’s time to begin processing for the next display frame. One consequence of this approach is that the particular sequence of random numbers you’ll get is heavily dependent on the exact cycle level operation of the CPU and the interaction between the CPU and the video hardware. That means that even if two emulators implement the logic of the CPU instructions perfectly, they will still generate different random sequences if their timing is not exact. You can see an obvious manifestation of this in the attract mode of Contra which plays back a pre-recorded stream of button input and relies on determinism to replay the demo exactly the same each time. Below is a side by side comparison of the same frame of the attract mode running on two different emulators. Notice that the running soldier that has randomly spawned on the lower right part of the screen selected a single spawn when running on Nintendulator and a triple spawn when running on NESten. This is because the sequence of random numbers being generated by the two instances of the game is not the same. Fortunately, the influence of the random numbers is small enough to not completely break the attract mode playback.

prng_difference

Structure of Arrays

Contra stores all of its data about enemies and bullets in structure-of-arrays format instead of the more object oriented array-of-structures format. The reason for this doesn’t have to do with CPU cache utilization or SIMD instructions like you might expect, but is instead a consequence of the NES having 16-bit memory addresses but only 8-bit CPU registers. If you want to access data indirectly through a pointer, you can’t store the address of the object in the pointer and then hard code the offset to the member you want in the load instruction because the address of the object probably won’t fit into a CPU register. Instead, you need to flip everything around and hard code the full 16-bit address of an array of members for multiple objects into your load instruction and then use the register to hold the offset within the array to get to the member that belongs to the object that you’re interested in.

Screen Space

In Contra, everything happen in screen space. The positions of the players and the positions of the enemies and bullets are all stored and manipulated within the coordinate system of the screen (i.e. a position of 0 always means the point in space that is currently at the left side of the screen, no matter where within the level the screen has scrolled to.) This is an optimization that seems a little counter intuitive at first because you would think that storing all of your positions in screen space would make things like scrolling a lot more complicated. Now instead of just changing a single scroll position variable to scroll the screen, you have to manually move the positions of every enemy, player and bullet every frame to simulate scrolling. The reason that this actually ends up being a good thing to do is that it saves a lot more time than it costs each frame. Scrolling is more complicated, but it really just boils down to adding 1 extra number into an object’s position as it updates each frame which is often just 1 extra CPU instruction per game object. The big win is that now all calculations related to the positions of things can be done using 8-bit values (the NES screen is 256×240 pixels so you can locate any position on screen with pixel precision using a single byte for X and Y.) Since the NES only supports 8-bit arithmetic natively this ends up being way faster than trying to emulate 16-bit arithmetic to handle 16-bit world positions. This of course only works for a game like Contra where the relationship between world space and screen space is a simple translation without any scaling or rotation possible (i.e. transforming from world to screen space happens to be commutative with other translations even though applying transforms is not commutative in general.) If the camera could zoom out in the game then things would start moving too fast and if the camera could rotate then things would go in the wrong direction.

Subtle Behavior

There are a number of things in Contra that change according to how many times you’ve played through the game in a single sitting, and which gun you currently have. The following is a complete list of the differences, where FINISHED would be 0 the first time through the game, 1 the second time through, etc. and GUN is 0 for your default weapon, 1 for Fire, 2 for Machine gun or Laser and 3 for Spread:

  • Level 8 mid boss and final boss HP = 55 + (16 * FINISHED) + (16 * GUN)
  • Level 8 mid boss projectile HP = 2 + FINISHED
  • Level 8 mouth things in wall HP = 4 + (2 * FINISHED) + GUN
  • Level 8 scorpions HP = 2 + FINISHED + GUN
  • Level 8 pods around final boss HP = 24 + (2 * FINISHED) + (2 * GUN)
  • Level 6 boss HP = 64 + (8 * GUN)
  • Red cannons that comes up out of the ground wait less time to begin shooting at you for greater FINISHED
  • Random enemy spawns are more frequent with greater FINISHED and GUN, and when FINISHED is 0 they take care not to spawn right on top of you and only spawn on the right side of the screen in the first level
  • Gray turrets in walls rotate to target you faster, and wait less time to target again after shooting bullets with greater GUN
  • Soldiers that shoot bullets tend to shoot more bullets per round with greater GUN
  • Cannons on screen for level 2 and level 4 bosses, as well as the bosses themselves, wait less time between shooting at you for greater GUN
  • Level 8 mid boss shoots 3 projectiles at a time when GUN is 3, but only 2 otherwise
  • Speed at which scorpions drop down on you from the ceiling during final boss fight increases proportional to GUN

Conclusion

Contra is one of my favorite games on the NES and as a game programmer it was a lot of fun to dive in and figure out exactly how it works. I’m always amazed at how much game developers of the time were able to get out of hardware that is ridiculously slow and limited compared to today’s consoles. If you have any feedback about this series of posts please let me know so I can come up with a plan for if/when/what I’ll cover next. You can reach me on twitter @allan_blomquist or comment below.

(Prev – This is part 7 of a 7 part series)