Donkey Kong Forum

General Donkey Kong Discussion => General Donkey Kong Discussion => Topic started by: AAB on February 15, 2016, 12:57:06 pm

Title: The Anatomy of a Donkey Kong Bomb Barrel
Post by: AAB on February 15, 2016, 12:57:06 pm
WARNING: This is a long and pretty technical post with little, if any, insight into DK playing strategy.  It will likely be of interest only to those interested in DK code reverse engineering.

Having played DK in the arcades when I was a child, I relatively recently rediscovered the game and became interested in bettering my score.  As many before me, I reached a point where wild barrels were my biggest stumbling block.  So, I decided to look at the disassembled DK code with the goal of modifying the DK MAME cheat file to add options to make all barrels wild barrels and to choose what type of wild barrels will be thrown (type 1, type 2, type 3, bombs, etc.).  I know there’s a ROM hack out there that causes the game to throw only type 2 wild barrels, but I wanted something much more versatile that would allow me to choose what wile barrel types I wanted on the fly and without having to change ROMs.  In the course of reverse engineering the wild barrel algorithm in the original DK code, I found something pretty interesting (to me, at least).  Although it’s not free from doubt, I believe that the programmers never intended to create “bomb” wild barrels and that, instead, these bomb wild barrels resulted from the programmers overlooking to clear a certain part of RAM when DK throws a barrel.  For those more technically inclined, the following is a more detailed explanation.

The DK code reserves a space in RAM that stores information about the various attributes of the barrels on the barrel screen.  For each barrel, these attributes include, for example, the status of the barrel (such as whether it is being deployed, or has been deployed and is on screen, or is not currently being used), the X and Y screen coordinates of the barrel, its horizontal speed, whether the barrel is “wild” or “normal,” whether the barrel is blue, etc.  Each attribute is represented by an eight-bit number (i.e., a byte), and each barrel has 32 bytes worth of attributes (which I will call “variables”).  The code reserves enough RAM for eight barrels, and I will call each a “barrel record.”  Programmers would call this memory structure a “variable array,” and the fact that there is enough RAM reserved for eight barrels in the array means that a maximum of eight barrels can be displayed on the screen at the same time.  When DK picks up a barrel, one of these eight barrel records in the array will be selected to store the variables for that barrel, and the variable that stores whether the barrel is being deployed will be “turned on.”  Because DK will inevitably throw more than eight barrels on each barrel screen, the barrel records are recycled, meaning that once a barrel is no longer on screen, the barrel record that was used for that barrel will be freed up for use when DK throws a new barrel.

When I gained enough understanding of the wild barrel algorithm, I wrote code in the DK MAME cheat file that would cause DK to throw only wild barrels.  When I turned the cheat on, something interesting happened.  DK would start throwing only wild barrels, but after he threw the eighth barrel, each subsequent barrel he would throw would be a bomb.  How could this be?  I set out to find what was causing this.  First, just like there is code that determines whether each barrel that DK throws will be a wild or normal barrel based on some probability, I guessed that there would similarly be code somewhere that determines whether the barrel will be a bomb.  I couldn’t find any such code, however.  So, I had to look deeper into the general wild barrel code.  Any seasoned player will know that a wild barrel’s trajectory changes only when it hits a girder.  Specifically, when a wild barrel hits a girder, it bounces and changes its trajectory.  I noticed that what is unique about bomb barrels is that they do not bounce on any girder except the bottom girder (there is an exception to this, which I describe below).  This led me to look closer at the code that determines when a wild barrel has hit a girder and causes the barrel to bounce and change its trajectory.  I found that, sure enough, whenever DK throws a bomb barrel, the code that is supposed to change the barrel’s trajectory when it hits a girder is never executed, and this is because the code that is supposed to determine when the barrel has hit a girder never registers a hit until the barrel has hit the bottom girder.

Why?  The answer has to do with the reuse of barrel records in the barrel array.  As mentioned above, when a barrel goes off screen, the corresponding barrel record in the barrel array is reused for a new barrel.  Ordinarily, you would expect that the program would “clear” out the variables in a barrel record once the corresponding barrel is no longer on screen, so that when that barrel record is reused for another barrel, there would be no unintended consequences arising from old values in that barrel record.  Well, it turns out that the program does not clear one particular variable in the barrel record, and this can cause the next barrel that uses that barrel record to be a bomb.  That particular variable is a variable that’s used only for wild barrels, and it is supposed to keep track of the Y screen coordinate of the last girder that the wild barrel has hit.  Specifically, when the code registers that a barrel has hit a girder, that barrel’s Y screen coordinate is saved into this variable in the barrel’s record (which I will call the “last girder variable”).  The code uses the last girder variable to determine when that barrel has hit the next girder.

When the barrel screen starts, the entire barrel array is cleared, including the last girder variables for each barrel record.  When DK releases his first wild barrel, the last girder variable for the corresponding barrel record will be zero (which corresponds to the top of the screen).   The code interprets this to mean that the barrel has just left DK’s hands, and it will save the barrel’s Y coordinate into the last girder variable and will set the wild barrel’s initial trajectory.  The same thing happens when the barrel hits the first girder, except that this time, the code will also cause the barrel to bounce.  When the barrel hits the bottom girder, the code will not update that barrel’s last girder variable (i.e., the value of the last girder variable will remain at the Y screen coordinate for the second-to-bottom girder).  Instead, the code will cause the barrel to bounce and then update the barrel’s record to indicate that it is no longer a wild barrel.  This will cause the barrel to roll like a normal barrel into the oil can.  Finally, when that barrel goes off the screen, its barrel record will update to indicate that the barrel is no longer in use.  Now, consider what happens if the same barrel record is reused for a new wild barrel.  When the new wild barrel is about to be deployed, the code clears most of the barrel record’s variables, including the variable for the barrel’s horizontal speed, but it does not clear the last girder variable.  Accordingly, at the time the barrel is deployed, the variable indicating its horizontal speed will be zero but the last girder variable will indicate that the last girder the barrel hit was the second-to-bottom girder.  The code will update the barrel’s vertical speed, causing the barrel to fall down.  However, the code that updates the barrel’s horizontal speed when it hits a girder will never be executed because the code will not register a collision with a girder until that barrel has hit the bottom girder.  The result is a bomb barrel.

An interesting curiosity is the relatively extremely rare barrel that acts like a bomb and then turns into a normal wild barrel when it hits a particular girder above the bottom girder.  This happens when the barrel record for that barrel was previously used for a wild barrel that exited the screen before hitting the second-to-bottom girder.  This results in the last girder variable for the “bomb” barrel to indicate that the last girder it hit was above the second-to-bottom girder.  When the barrel reaches the next girder, the code that updates its horizontal speed will execute, and that barrel will turn into a “normal” wild barrel.

Did the DK programmers intentionally omit to clear out the last girder variable to create these bomb barrels?  It’s possible.  In my view, though, I don’t think it’s likely.  If I were in their shoes and set out to create bomb barrels, I would have just written code that draws a pseudo random number and, based on that number, determines whether the barrel will act like a bomb and just drop to the bottom girder.  I could be wrong, however, in which case the programmers came up with an incredibly clever way to add new gameplay dynamics without adding any additional code (to the contrary, by FAILING to add additional code!).

As for DK playing strategy, about the only worthwhile suggestion of the above is that the probability of bomb barrels will increase as DK throws “normal” wild barrels.
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: Adam_Mon on February 15, 2016, 02:26:10 pm
Welcome to DKF!

Love seeing these types of posts, admittedly it will take me a few reads to fully grasp this  ;D
There are a good few members here that are intimate with the DK code so hopefully someone in the know will chime in on what you have found who might have more info on it.

I've only tested the wild barrel hack that is already on here a few times and its pretty brutal, from what I'm reading you have been able to create a cheat modifcation where you can change the wild barrel types on the fly..

Is that something that you could upload here so that we could try? (I personally have very little knowledge on this stuff) but would love to practice different wild types, no worries if you cant though.

I'm pretty sure Hank Chien had a video displaying some of the bomb behaviour you mentioned but after browsing his YT channel I was unable to find it, maybe it was someone else?
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: AAB on February 15, 2016, 02:57:49 pm
Hi Adam.  I'm attaching the cheat file I'm using that includes the two new cheats I added. The first allows you to make all barrels wild barrels.  The second selects the type of wild barrel (type 1, type 2, type 3, bomb, first barrel on level 1, first barrel on level 2, and first barrel on levels 3+).  For example, if you want all the wild barrels in the game to be type 3 barrels, you'd just set the second cheat to "Type 3."  Alternatively, if you'd want to practice nothing but "Type 3" barrels, you'd also trigger the first cheat.

I put these together fairly quickly as I was reversing the code, so they're not as optimized as could be, but they do work exactly as intended.

Enjoy.
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: Adam_Mon on February 15, 2016, 03:41:45 pm
This is awesome, Thanks sir!
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: f_symbols on February 15, 2016, 04:16:32 pm
Really a great topic here.  It appears you've done a bunch of your homework, as you have presented, concisely, most of "what is known".  Jeff Willms actually encountered this very problem when he created the "wild barrel hack" and had to add specific code to reset the "girder counter" to prevent all bombs from occurring over time. 

Also, you mention the transitional bomb, I have a highlight of one below; at the very beginning you can see the wild barrel leave the screen on the left side, after hitting the 4th girder, then you see the resulting "transitional bomb".

http://www.twitch.tv/f_symbols/v/42064458 (http://www.twitch.tv/f_symbols/v/42064458)

Keep up the good work sir, and welcome aboard! :)
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: AAB on February 15, 2016, 04:56:02 pm
Thank you for the link!  I've only once encountered one but could never find a video of one online until now.
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: JCHarrist on February 15, 2016, 05:39:40 pm
Thank you for the link!  I've only once encountered one but could never find a video of one online until now.


I've had it happen in MAME. I probably only noticed this one because it hit me in the face. :D

! No longer available (http://www.youtube.com/watch?v=6DGlszIw76w#)

I love these topics. Welcome to DKF!
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: stella_blue on February 15, 2016, 06:21:55 pm
Here's another example of a wild barrel "hybrid":

http://www.twitch.tv/stella_blue/v/42775868 (http://www.twitch.tv/stella_blue/v/42775868)

With 3700 remaining on the bonus timer, Kong releases a wild barrel that exits the screen after striking the 4th girder.  The next wild barrel is launched at 1900, shortly after the bottom hammer expires.  It begins as a bomb, then transitions to a Type 2, striking the 3rd girder and bouncing sharply to the right.  Similar to Jeff, I take it in the face.

Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: marinomitch13 on February 15, 2016, 07:56:29 pm
Excellent investigative work! Welcome to DKF!
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: AAB on February 16, 2016, 11:25:53 am
Thx for the responses and vids.  It’s nice to see the vids line up with how a reading of the code suggests they should.  Perhaps a more useful corollary to all this is this—if you see a wild barrel go off screen before hitting the bottom girder, take note of which girder it last hit and stay away from standing under that girder near the trajectory of where a bomb would be dropped.
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: up2ng on February 16, 2016, 12:53:45 pm
Very nice description of how this works.  As mentioned, this has been known within the community for a while but detailed descriptions of this are likely difficult to find within the forum, if they exist at all. 

One correction . . .

Quote
The code reserves enough RAM for eight barrels, and I will call each a “barrel record.”

... and the fact that there is enough RAM reserved for eight barrels in the array means that a maximum of eight barrels can be displayed on the screen at the same time ... etc ...

There are actually ten barrel objects in memory and indeed the maximum number of barrels which can appear on the screen at the same time is ten.  This is probably a simple hexadecimal math error while reading the code.

I do hope that you continue to participate within this community.  Although the code is available, there are still many aspects of the game which are not yet understood at a code level, so if we have more folks investigating the code and posting their findings that would be quite helpful!
Title: Re: The Anatomy of a Donkey Kong Bomb Barrel
Post by: AAB on February 18, 2016, 01:18:28 am
Thanks, Dean.  You’re of course right regarding the number of barrel records (I flubbed the math).

dkshawn, the tools I found most useful for this particular project were dZ80 (a great disassembler for the Z80 main processor that DK boards use) and the debugger built into MAME.  You can also look at some of the commented dissasemblies of the DK code that exist on the net.  They are useful and took many folks some serious time to prepare, but be warned that they contain errors (as you would expect when any human tries to decode several thousand lines of assembly).

Since my goal was to create a MAME cheat file, I didn’t have to worry about reassembling any code.  All modifications I made to the code are poked into the ROM by MAME when you turn the cheats on.  A drawback you will find with the MAME debugger is that while it allows poking RAM, it does not allow poking ROM.

I still think there’s a lot more to learn about the DK code, and the more able people actively looking at it the better.

My next project (when I find time!) will likely be to update this cheat to allow you to specify the probability of each barrel being wild.  Since I started this whole project, my end goal was to create a cheat that helped me improve my DK skills, and a cheat that causes every barrel to be wild turns out not to be conducive to improving those skills.  Being able to set the probability to, say, 25% may create a better gameplay flow to learn how to dodge or avoid the wild ones.