Search Results

Sunday, August 7, 2011

Random Level Design Implemented in the BGE - Part 2

Hey. So here is part 2 of the fairly large tutorial series on random level design in the BGE. Part one covered a fair amount, and we will be looking into part 2, which will be a little more in-depth.

Okay, so in the first part, we covered how to randomly generate a list that will represent our level, with numbers representing our rooms (1 being a room piece, and 0 being a blank spot). Now, then - how do we make those rooms connected?

Well, in the source code for the RLG module that you can download below, we test to see if the rooms must be connected, and prepare the level specially for that case. Firstly, we make the middle cell in the level a room, to make it easier on ourselves. We now have a reference point to create the rest of the random level from.


if mustconnect:
  
        middley = floor(ysize / 2.0
        middlex = floor(xsize / 2.0)
        room[middley][middlex] = 1
      
        currentnum += 1

Utilizing a previously defined variable (mustconnect), we set the middle room to be filled. Next comes the somewhat harder part - filling the rooms around the middle one.

It's actually not too difficult - we simply choose a random room (cell) in our level, and then see if another room is next to that one via a function specially designed to check for that case. That function is the GetSurroundingCells() function in the source, which, again, isn't as complex as it looks. That function takes as arguments the room list, and the cell X and Y position to check. It has some checks in it to ensure that it will return a blank room if the specified cell to check is on an edge - after all, you wouldn't want an error, or to find a looped value, right? After it checks for these edges, it returns a list consisting of the surrounding cells, and the number of cells that connects to the 'home cell'. For example, in this list:

[
[0, 1, 0],
[0, 1, 1],
[0, X, 1]
]

you can see that there are two rooms connected to the room X. However, if you use the GetSurroundingCells() function, you'll see that it will return a 0 for the 'bottom' cell, as the home cell is on an edge. It could easily be modified to also return looped cell values, returning a 1 for the cell in position [0, 1] (remember, Y position first in our room list).

Now, then - back to the connected room generation. We've selected a random room, and we know which cells connect to our selected cell. In addition, we know at least one cell exists, as we spawned the first home cell outside of the connected cell loop, and it's spawned in the center of the level to ensure a nice and balanced room generation.

After that, it's a simple task to spawn rooms next to other rooms to form a level. There's one last little bit, and that's checking to see if we want only hallways or not. Basically, the theory here is that you may want a level with only hallways, and no 'clumped' rooms, like in the example below.

A, no halls:

[
[0, 0, 0, 1, 0],
[0, 1, 1, 1, 0],
[0, 1, 1, 1, 0],
[0, 1, 1, 0, 0],
]

B, only halls:

[
[0, 0, 0, 1, 0],
[0, 1, 0, 1, 0],
[0, 1, 1, 1, 0],
[0, 1, 0, 1, 0],
[1, 1, 0, 0, 0]
]

Well, you can use the same output from the GetSurroundingCells() function to check to see if a cell has more than one inhabited neighbor (and so is not a corner or a passageway), as the function returns both if there are cells next to the specified checking cell, as well as the number of neighbors. If so, then skip occupying that cell. That's it!

Part 3 will be probably the last tutorial in the series and will deal with using these values to actually make the level in the BGE.

You can download the source code, along with the RLG module in the BGE here. As always, have fun!

3 comments:

  1. Thanks for the tut.

    ReplyDelete
  2. I think there are more than two readers, who finding this tutorial series very interesting ;)
    Is there no part 3? Unfortunately, I do not see it...
    But THANK YOU anyway!

    ReplyDelete
  3. I have been searching the web for a tutorial like this, this is presented in a clear and concise manner. Thanks . . .

    ReplyDelete