Random level generation

S

Simulacron

Guest
I'm trying to create a level generation, where my room is split up into mulitple cells (for example a 6x6 grid). Every cell represent a room, that can have an exit in all four directions (up,down,left,right). First of all I want to create a garuanteed way through the level. For this I pick a random room in the top row (f. ex. [1,4]) and try to asgin a random exit to one direction. The next cell in that direction is than used to create the next room, until we get to the bottom row, where the level generation stop. But the script I wrote so far doesn't work, the game doesn't even start because there's probably an infinite while-loop. Could anybody look at my scripot and teel me what I'm making wrong? Thanks for your help!
Code:
cell_w = argument[0]; //number of cells horizontal
cell_h = argument[1]; //number of cells vertical

var cell_x = 0; //curent x-position of cell
var cell_y = 0; //current y-position off cell
var next_cell_x = 0; //Varibable to store next x/y position
var next_cell_y = 0;

for (i = 0; i < cell_w; i++){ //Initialize 2D-arrays, that have the size of the cells in the room
    for (j = 0; j < cell_h; j++){
        room_up[i,j] = false; //Saves if cell has an exit at the top
        room_down[i,j] = false; //Saves if cell has an exit at the bottom
        room_right[i,j] = false; //Saves if cell has an exit at the right
        room_left[i,j] = false; //Saves if cell has an exit at the left
        room_has_exit[i,j] = false //Saves if cell has a connection to another room
    }
}

var random_pos = irandom(cell_w - 1); //Choose random x starting position
global.start_room = random_pos; //Save the position (used to spawn player)
cell_x = random_pos; //set starting cell_x to the random starting position
next_cell_x = cell_x //set next_cell_x to cell_x, so both start with the same value

while(true){ //As long as we haven't reached the bottom of the room, do following:
    while(room_has_exit[cell_x,cell_y] = false){ //If the current room has no exit:
        var r = irandom(4) //Create random int between 0 and 3
        if r = 0{ //If number is 0
            if cell_y < cell_h - 1{ //Look if your not at the boztom of the room and don't leave the array (the -1 is because the cell_h/cell_w is one bigger, because the array starts with [0,0] and not with [1,1]
                room_down[cell_x,cell_y] = true; //Save that the room has an exit at the bottom
                room_has_exit[cell_x,cell_y] = true; //Save that the room has an exit
                next_cell_y += 1; //Set next_cell_y one below, so the next room starts where the old one has an exit
            }
        }
        if r = 1{
            if cell_y > 0{
                room_up[cell_x,cell_y] = true;
                room_has_exit[cell_x,cell_y] = true;
                next_cell_y -= 1;
            }
        }
        if r = 2{
            if cell_x < cell_w - 1{
                room_right[cell_x,cell_y] = true;
                room_has_exit[cell_x,cell_y] = true;
                next_cell_x += 1;
            }
        }
        if r = 3{
            if cell_x > 0{
                room_left[cell_x,cell_y] = true;
                room_has_exit[cell_x,cell_y] = true;
                next_cell_x -= 1;
            }
        }
    }
    if cell_y = cell_h - 1{ //If the cell_y is at the bottom stop the while(true)-loop
        break
    }
 
    cell_x = next_cell_x; //Set next_cell_x/y to cell_x/y to go through the loop again (can't be done instantly becaus the while loop needs to check if the current room has an exit)
    cell_y = next_cell_y;
 
}

for (i = 0; i < cell_w; i++){ //Go through each cell and calculate a number, that auto-tiles the obj_cell object
    for (j = 0; j <= cell_h; j++){
        num[i,j] = 0;
        if room_left[i,j] = true{num[i,j] += 1}
        if room_up[i,j] = true{num[i,j] += 2}
        if room_right[i,j] = true{num[i,j] += 4}
        if room_down[i,j] = true{num[i,j] += 8}
     
        var idrem = instance_create(i * global.size,j * global.size,obj_cell);
        idrem.image_index = num;
    }
}
(This level generation is inspired by the way spelunky deals with it. Here's avideo that explains it, however this is not exactly what I want from my game! (1.36))
 
S

Simulacron

Guest
So, I started tweaking the code a bit. I added a array, that checks if there's already a room, where we want to create our way and removed the possibility for the rooms to move up again, so it have to get evetually to the bottom. I also cahnged the while(true) loop to a variable, just to make it more clear what is happening.
But it still doesn't work. I probably missing something obvious.
Code:
cell_w = argument[0]; //number of cells horizontal
cell_h = argument[1]; //number of cells vertical

var cell_x = 0; //curent x-position of cell
var cell_y = 0; //current y-position off cell
var next_cell_x = 0;
var next_cell_y = 0;
var exit_found = false;

for (i = 0; i < cell_w; i++){ //Initialize 2D-arrays, that have the size of the cells in the room
    for (j = 0; j < cell_h; j++){
        room_up[i,j] = false; //Saves if cell has an exit at the top
        room_down[i,j] = false; //Saves if cell has an exit at the bottom
        room_right[i,j] = false; //Saves if cell has an exit at the right
        room_left[i,j] = false; //Saves if cell has an exit at the left
        room_has_exit[i,j] = false //Saves if cell has a connection to another room
        room_created[i,j] = false
    }
}

var random_pos = irandom(cell_w - 1); //Choose random x starting position
global.start_room = random_pos; //Save the position (used to spawn player)
cell_x = random_pos; //set starting cell_x to the random starting position

while(exit_found = false){
    while(room_has_exit = false){
        room_created[cell_x,cell_y] = true
        var r = irandom(3);
        if r = 0{
            if (cell_y < cell_h - 1){
                if (room_created[cell_x,cell_y + 1] = false){
                    room_down[cell_x,cell_y] = true
                    room_has_exit[cell_x,cell_y] = true
                    next_cell_y = cell_y + 1
                }
            }
        }
        if r = 1{
            if (cell_x < cell_w - 1){
                if (room_created[cell_x+1,cell_y] = false){
                    room_right[cell_x,cell_y] = true
                    room_has_exit[cell_x,cell_y] = true
                    next_cell_x = cell_x + 1
                }
            }
        }
        if r = 2{
            if (cell_x > 0){
                if (room_created[cell_x+1,cell_y] = false){
                    room_right[cell_x,cell_y] = true
                    room_has_exit[cell_x,cell_y] = true
                    next_cell_x = cell_x - 1
                }
            }
        }
    }
    
    if cell_y = cell_h -1{
        exit_found = true
    }
    
    cell_x = next_cell_x
    cell_y = next_cell_y
}

for (i = 0; i < cell_w; i++){ //Go through each cell and calculate a number, that auto-tiles the obj_cell object
    for (j = 0; j <= cell_h; j++){
        num[i,j] = 0;
        if room_left[i,j] = true{num[i,j] += 1}
        if room_up[i,j] = true{num[i,j] += 2}
        if room_right[i,j] = true{num[i,j] += 4}
        if room_down[i,j] = true{num[i,j] += 8}
        
        var idrem = instance_create(i * global.size,j * global.size,obj_cell);
        idrem.image_index = num;
    }
}
 
J

JFitch

Guest
You may be reaching a dead end (you end up in a cell where all the adjacent cells already have a room created). Try finding a way to reset the entire process if that happens.
 
S

Simulacron

Guest
You may be reaching a dead end (you end up in a cell where all the adjacent cells already have a room created). Try finding a way to reset the entire process if that happens.
Thanks for this idea, but I don't think this is possible becaus I only go down, right or left. This means that after a number of tries, even if the hole row is full, the next room should be below
 
Top