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.