Procedural Generation in Godot: Dungeon Generation (part 1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to another procedural content generation tutorial for Godot 3.0 in this installment we're going to be looking at making random dungeons for this demo our goal is to generate a random dungeon like the one picture here and for our purposes a a dungeon is a series of rooms connected by corridors that the player can wander around and explore and maybe there's things in the room maybe there's not we're not gonna worry about that at the moment we want to generate this layout it's randomly out of rooms and corridors now there's a lot of different ways to go about this there's a lot of different popular algorithms for generating dungeons this is something people have been doing for a long time some popular ones are to generate the rooms in different locations and then use maze generation like we've done before to generate the corridors between them but for this demo I wanted to try something a little different for this algorithm we're gonna take advantage of godot's built-in physics engine to create the map broadly speaking we're gonna split it up into three steps first we generate the rooms then we find a path that connects the rooms together generate the corridors along that path and then we turn it into a tile map that will be walls and open spaces that a player can actually walk around on and explore so we're going to start with the room a room in this context is a rectangular space large enough for the player to walk around in and that can contain objects of interest like treasures or mobs or whatever else you might be populating your dungeon with we're going to use a rigidbody 2d to represent the room this is where the physics comes in so we're going to start by making a an individual room object that we can instance a bunch of to create our dungeon so here's the node layout we have a rigidbody 2d for the room and a collision shaped 2d which I have not added a shape to yet we're going to do that in the scripts that we randomize it so let's attach a script to the room okay so this script is going to have a size variable to keep track of the size of our room and then we're going to make a function called make room where we give it a position and a desired size and that's going to create the collision shape basically so we set our position equal to the given position size is equal to the given size and we create a rectangle shaped 2d that's going to have its extents set to the size and we attach that to the collision shape 2d and that's our script to generate a room the other things we need to do are in the project settings we need to make sure we set in the physics 2d section the default gravity to zero I don't want the room's falling off the screen and for the room itself we're gonna set the mode to character and a rigidbody 2d in character mode can't rotate so for this dungeon we want to keep our rooms orthogonal so this will keep them from rotating if they as they collide with each other so now let's add a main scene that's going to generate our actual dungeon we're going to start with a node 2d this is gonna be my main scene and I'm gonna put a plane node in there called rooms that's gonna act as a container to hold all the rooms that we generate in the main scene script we're going to load the room scene so that we can instance them and then we going to set up some config variables that we're gonna use we're gonna have a tile size this is gonna be how big the tiles of our tile map that we generate will be the number of rooms that we want to generate we're going to have the minimum minimum size is the minimum number of tiles that a rooms width or height can be and max size will be the Mexico in are ready we want to call randomized to initialize the random number generator and then we're going to call our make rooms function and this is going to be the function that generates all of our rooms so we have a loop we're going to account to num rooms that's how many rooms we want to generate we are going to start out by setting them all to we just put them all at the center or at 0 0 we're going to set all the rooms to 0 0 to begin with we're gonna make an instance of the room and we're going to randomize the width and height so for width we want a random number between min size and max size so we get that by saying picking a random number exercise - min silence so we pick a random number between 0 and 6 for example and then add 4 to it and then you have between 4 and 10 we're going to do that for both the width and the height so now we have two random numbers so we can now call make make room on the new room we made pass it to position and pass it our size and our size is going to be that width and height times the tile size and then we're going to add that room to the rooms container all right so now we've generated 50 random rooms but if you were to run this you see nothing because these collision shapes don't have any visibility now we can test to see what's going on by turning on visible collision shapes and if we run that we'll see a bunch of squares are popping up and getting pushed apart but we need to zoom out to be able to see the actual rooms and the whole layout and we probably want to do some better visualization than the collision than just the collision shape debug because we don't want to leave this on during actual gameplay so we can add a camera 2d to this scene set the current on and we're going to set the zoom to 10 by 10 and that's gonna zoom us out a bit so that will help us see what's happening so you can see when we run the rooms are all pushing each other apart so that there are no overlaps because that's what the physics engine does for us so let's turn that debug back off and instead we're going to draw some outlines for the rooms so we'll be able to see them and we're going to do that using the draw function for a room in so for each room we want to draw a rectangle of its size so we'll use draw a rect and the rectangle that we're going to use is room room position - room size room size times - that's the size of the rectangle and we'll zoom in here so you guys can see and we also want to use a color I'm gonna pick a greenish color here and false we don't want the rectangles filled in and so that means that we just need to call this in our process function so that it will update the drawing now when we run the scene we just see the outlines of the of the rooms as they're generated let's also add an input function here so that oops let's get up here and give some space so that if we press the space bar so is action press that's UI select to be to start with so if we press the space bar I want to delete all the rooms and respawn them so just to give us a quick way to restart so we want to delete everything in the rooms container and then call make rooms again all right there we go so now we can respawn our rooms whenever we want by hitting the space bar and get a different collection of rooms ok so this is looking good but let's add a couple other things we're gonna add another variable here called ha H spread horizontal spread and what this means is how much we want the room layout to be biased to be horizontal so like a lot of games for example if we were doing if you're doing this to generate an isometric map you might want the player to spend more time walking right and left than they do up and down so you want the dungeon to be laid out more horizontally so this horizontal spread is going to add some pixels to the position when the room is spawned and so the bigger we make this number the more spread out they'll be horizontally so that just means that here what we want to do is change the starting position so that the X has this value in it between H spread and H spread and and so that means that when we run it now we'll have a more horizontally laid out dungeon okay the other thing you might notice is that it takes a little time for those rooms to stop moving as they're overlapping so we can influence that over here in our room script when we spawn the shape we're gonna set custom solver bias to about 0.75 and you'll see if I run it what that does is they're gonna stop moving a little bit faster when they they're gonna reach their finish point a little more quickly so next what we want to do is now that we've generated all these rooms we want to delete or cull some of them so I'm gonna make a variable called cull here and this is a percentage so if I set it to 0.5 that means when you go through and cull we're gonna call about half of the rooms so in make rooms what we want to do is after we've added all of them we're going to need to wait for the movement to stop right we need to give the physics engine a few seconds or a little bit of time to spread the rooms out and get them to stop moving so we can use yield and just make a quick timer I'm gonna do it for 1.1 seconds and you can adjust this based on you know how you want it to work we're mainly doing this because we want to be able to watch the room spread out and then we're gonna we're gonna call the rooms after this and calling the rooms mean as we go through each room and possibly delete it so for each room in the rooms container we're going to pick a random number and if that random number is less than the cull number we're going to delete the room we can also if we didn't then we're gonna set the room's mode to rigidbody2d up modes static mode static will turn this and turn that rigidbody2d into a static body so it means it's not going to move anymore or have any collision physics happening because we're done with that so now when we run it what we're gonna see is that our rooms are going to spread out and then some of them are going to disappear to give us a little more sparsely populated dungeon and again you can adjust now these numbers to give you all sorts of different layouts depending on what kind of dungeon you're going for all right so that's a good start to our dungeon generator we've got our rooms being generated we're going to stop here and in the next installment we're gonna look at how we connect these rooms together generating a path between them thanks for watching I'll see you in the next video you
Info
Channel: KidsCanCode
Views: 50,509
Rating: undefined out of 5
Keywords: programming, coding, tutorial, lesson, gamedev, game development, godot, godot engine
Id: G2_SGhmdYFo
Channel Id: undefined
Length: 14min 36sec (876 seconds)
Published: Tue Dec 04 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.