Jul 5, 2020

SIDETRACK: Super Bomberman 5's Item Randomization

For those of you still reading this and not already in the know, the computer which had my Castlevania project on it died (I think the hard drive is corrupted). I think I've managed to back up the files onto a flash drive, but all the code was in GM8 and I will now have to transfer it to GMStudio, so GMvania is on a temporary hiatus.


I have been working on a Bomberman clone as of late. It started out as just a quick peek into how Hudson handled Bomberman's movement in the NES original, but then I started tweaking the code to be more compatible with keyboards. From there, I got carried away and started adding the rest of the features that gamers have come to love in the Bomberman series. Unlike with Castlevania, I've hardly copied any of the original code; this Bomberman game's code is almost entirely original. I've worked many bugs out of it.

Anyway, when I finally got around to trying to figure out how to randomly place the items in the room, I had an unfortunate mental lapse. For the life of me I couldn't come up with something satisfying to me. The simplest idea I had was to create two lists -- one with all the bricks' coordinates and one with all the possible items -- then shuffle the lists and read them in parallel. I still think it's a good idea (for working within GM), but it was nagging me that clearly wasn't how Hudson did it. So, after many painstaking hours trying to get SNES9X's debugger to dump a readable CPU log, I finally located and translated the item randomization code for Hudson's Super Bomberman 5.

Unfortunately, I wanted to make the item quantities entirely random, but Hudson had the item quantities for each map pre-planned, in standard Battle Royale mode. The array would have the item ID and the quantity (followed by a 00 for some reason). When an item ID of 00 is found, the routine ends. So for example, the item array for the first arena in was:
02 08 00 01 05 00 03 04 00 0C 02 00 
0B 02 00 11 02 00 15 02 00 12 01 00 00

The items IDed as follows in the game:
01 Fire-Up
02 Bomb-Up
03 Skates
04 RC Bomb
05 Bomb Pass
06 Wall Pass
07 Armor
08 Clock
09 1UP
0A Sandals
0B Kick
0C Power Glove
0D Pierce Bomb
0E Full Fire
0F Landmine
10 Homing Bomb
11 Boxing Glove
12 Skull
13 Skull (glitch?)
14 Heart
15 Louie (random)
Thus, the item array reads Bomb-Up x2, Fire-Up x5, Skates x4, Power Glove x2, Kick x2, Boxing Glove x2, Louie x2, Skull x1.

The game grabs each item from the array and its quantity, then picks a random number up to 31. It then loops across the entire map, checking for empty breakable blocks. If it finds one, it decreases that random number. If the number goes negative, it puts that item in the block, otherwise it finds the next empty breakable block. For each item, the loop picks up from the last time.

var i = 0;
var randomizer = 0;
var start_x = 0;
var start_y = 0;
var item_count = 0;
var item_id = map_item_set[i++];
while item_id {
    item_count = map_item_set[i++];
    repeat item_count {
        randomizer = irandom(31);
        while randomizer > -1 {
            if global.MAP[start_x,start_y] == 2
                if global.ITEMS[start_x,start_y] == 0
                    if --randomizer < 0
                        global.ITEMS[start_x,start_y] = item_id;

            start_x = start_x + 1 & 15;
            if !start_x
                start_y = ++start_y mod 13;

And so ends today's lesson.
©TheouAegis Productions™. Powered by Blogger.