Dungeon Generation Tutorial! Godot

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys today we'll be creating this simple dungeon layout generated and with this you can generate dungeons similar to those found in Solna or the binding of issac I'll be making this project in Godot but you'll be able to do this into any game engine the general idea will stay the same so I'll just start a new project the first thing we're gonna want to do as soon as loads is create a new C and our dungeons aren't going to be composed of rooms so we're gonna first want to define whatever it is we're not actually gonna be generating what's inside of the dungeons just the general layout so for our purposes our room is gonna be very simple but if you were to implement this in an actual game you'd have to add doors and transitions between rooms if you want I could create a tutorial about that later but today it's just a dungeon generation so we're going to name this room and add a script to it and it can be named room IgD and our room we don't need a ready function we just need a dictionary that holds if you're alright it out first [Music] [Music] so this dictionary called connected rooms its stores that has four items stored in it and each of them is a vector in a certain direction and each of them points to an object so a dictionary is basically a hash map if you've ever coded in Java or C++ or if you have but you don't know what they are hash map is basically it's like an array except instead of 0 1 2 3 & 4 leading to whatever you're trying to find it uses other objects to point it uses other objects as keys to point to the object you're trying to find in addition to this will also create another variable called number of connections and this will basically store how many connections this room has to other rooms you don't really need this variable you could actually just create a function counting the number of these that don't equal no but I find this more convenient for what we're gonna use it for later so that's all that needs to be done in room for our project and we're gonna now move on to the actual dungeon generation so our dungeon generation script is not going to be a scene like the room it's actually going to be a standalone script so you can just name it dungeon in relation and in order for this script to be able to be called by other scenes we're gonna have to add it to the auto load path so just select the script and project project settings and then go from general to auto load and just load this script over here and you can just name it dungeon generation and make sure that singleton is enabled and in the script the first thing we're gonna want to define is how large we want our dungeon to be so for maximum randomness we can define a min number of rooms and said this is a six for now and then we can also set a max number of rooms and this can be ten and every time we generate a dungeon we'll just select the number between the min and the max so not all dungeons are the same size and aside from that we're also gonna want to be able to use our room scene in our dungeon generation script so to do that in Godot we just do a bar a room equals pre load and then just the path to the room see so for me that's [Music] all right the next variable we're gonna want to define is the root generation chance and this is basically the chance that a root will spawn that a remote branch off of the current we're trying to spawn it off of this will make more sense as I get more into our dungeon generation algorithm actually works but for now just note that the higher this number is the more likely that a root will spawn but also with that I feel the less interesting our actual dungeon layout becomes so I'll just set it to 20 to start which means 20% well we don't need a ready function but we do need our generation function which will return a dungeon and in our generate function we're gonna actually want to accept a a number as an input which will be the room seed so that we in in case you want to generate random dungeon the same random dungeon for testing purposes you could use the same seed so to actually apply the seed to this random generation we do seed [Music] alright our dungeon is actually also going to be a dictionary it's gonna store where each room is and the actual room object itself so it's just just like our connected rooms dictionary it'll be a vector to to an object but it'll start out empty that's all we need out and we also need to determine for this dungeon how large it's gonna be so today that we just do size equals R and range and this will return a float between the mid number of rooms and max number of rooms but we actually want it to be an integer so we can solve that by just for the number that it returns so let's say it returned 3.5 it would return and to start our dungeon off we're actually going to want to create a loop in the center and that's where all the other they're gonna branch off of this will ensure that all the rooms in our dungeon are connected and that there's no like islands of rooms that can't be breached so this just selects the key in the dungeon where the vector is zero zero and we can set that to instance a new instance of of our room scene which is omega which is Huskies net story and since we added a new route to our dungeon we're going to actually want to decrease the size by one because a room has been added and now here's where the actual generation comes along so here's a visualization of what's actually occurring in our script in the beginning a random dungeon size is generated in this case eight for this dungeon and over here you'll see that generate a number between one and a hundred and if it's less than the room chance then a new room will created in this randomly generated direction so if we click generate you see 77 isn't less than 50 which is our witch for this script is our generation chance so seventy sevens not less than 50 so a direction wasn't generated and it keeps going until it generates a number that is less than 50 in which case a direction is generated and you see a new in this direction was created and the rooms left was decreased by one and it keeps going it cycles through all the existing rooms so you see before it was over here now it's over here and it has generated a number less than 50 and in the same direction it will generate a root of this number is randomly generated and it keeps going until rooms left is equal to zero now you can see rooms left is equal to zero so at this point our dungeon function would just return this dungeon as a whole and it'd be done to give another example here's another dungeon and as you can see it's branching off if this number is less than our generation chains and it keeps going oh in this case you see our dungeon generation algorithm was on this root and the number it generated was less than 50 and but the direction it chose was downwards and a room already existed in that position so what our algorithm does in this case is it just creates a new path between these two rooms and this dungeon is now done so that's basically what our algorithm will do and here we'll start with the actual generation so we're gonna want to create a while while size is greater than zero which means that there are still he was left to be generated and while the size is greater than 50 we're gonna want to through all of the rooms in the dungeon so to do that we'll just do 4i and then for all of the rooms in the dungeon we want to see if a room should split off at that point and that's determined by if the ran range 0 to 100 is less than our generation chance which basically gives us a 20% generation or a 20% chance that our room will generate from this room and now we're gonna want to select a direction if room were to be created in which direction it were to be created in so great a new variable and just name it direction and it will be a number between 1 and 4 or a 0 and 4 [Music] and then now all add a bunch of if Stevens checking the direction in which the room is all right so to create a room all we have to do is we know where the room we are on is that's I so I is the room we are currently on and in Direction one the room that's generated will be in position I plus of vectors so [Music] plus a certain vector so in this case we're gonna do vector 1 comma 0 which is to the right and what we want to do is we want to check that if a room if our room already exists in the dungeon at that position because if it does we don't want to overwrite it so in order to do that we can just do it if dungeon that has and if it has or if it doesn't have to do to check if it doesn't have we just add an exclamation point in the beginning of this so if it doesn't have it then we just create a new room in that position we do it the same way we did it over here so you just copy and paste that here except instead of except instead of vector 0 0 we do it in the new room position and that just creates a new room at that position and now we want to connect the two rooms and the two rooms will be connected based on what's inside of this connected room's dictionary inside of each room so let's say there is a room defined here that means that this room is connected to the left of that room so what we want to do here is I'll actually create a new function called Connect rooms and we're gonna want to accept a room or two rooms and a direction the directions going to be the direction of room to relative to room one [Music] so what we've done here is we've and over here if you remember we have the number of connections variable we just want to we're just gonna want to increase them that by one for both of the reasons once we get back here we're just gonna wanna connect throughs get the bad position I and then get the new room at the new position [Music] and detective [Music] [Applause] um we're also gonna want to decrease size by one after we create a new room so that this loop doesn't run forever so we just do sighs - equals one over here and we don't put this in the if statement because this is this only runs if a room doesn't exist in that position but if a room does exist in that position we don't want to create a new room but we still want to connect the rooms I create a path between the names of two rooms and all we have to do now is to just copy and paste this into all into the rest of these you could create a new function with just these contents but I don't think it's that necessary and for the rest of these make sure to change the vector to values and after all this all we have to do is return dungeon and it should give us a generated dungeon in order to test if this dungeon works we're gonna actually create a new scene where and this will show us where the dungeon is or show us the contents of our dungeon dictionary [Music] and I'll just provide the code to this probably in the description this isn't very relevant to what we're actually or this isn't relevant to the actual dungeon generation so I'll just give you the code [Music] and then inside of this scene in order to view what's going on we're going to want to add a camera 2d and we can scale it down into three point three zero three and we'll also add a button to generate new dungeons without having to open and close the program every single time in order to connect this button to the code just go over here from inspector to node click press click connect and make sure dungeon tester is highlighted and click connect and we're also gonna want to add a new node you may be mapped new and this is inside of this is where all the testing um sprites will be draw oh speaking of that in order for us to actually see what's going on in the dungeon I'll provide some assets to actually draw the dungeon down they're the ones you saw in the beginning of the video [Music] or the like this one disable the filter select both of them Gramercy to import and then make sure that filter is unchecked and that'll make sure that the pixel art is cleared because otherwise it would be blurred like this and we don't want now if we run our program we should see oh I forgot to you have to click on camera make sure that the current is selected and now when we run it should see our dungeon every time you click generate a new one should be present and so our dungeon generation algorithm is pretty good but sometimes it generates dungeons such as these with which aren't that interesting and probably wouldn't be that fun to actually play in a real game because it's quite linear unlike oh you'd want a dungeon to be which is mostly about exploration and in this case all you have don't the options you have is to go straight up or up into the left and to solve this I actually there's actually a real simple way to solve this go over here I just have to create a new function and it's going to be [Music] and instead just call it is interesting and it'll accept the dungeons input yeah so to define a dungeon is interesting I feel that our dungeon is interesting when there are at least two rooms there are at least two rooms with at least three connections so like over here this room is connected to now and down and down and this rooms connected to over here over here so this one would have qualifies interesting with tools with at least three connections over here this room wouldn't qualify because it only has one room with three connections this one would qualify I think no I like this one wouldn't qualify because there's only this one with three connections and the rest of these only have two and this one has two and that one only has one so that one won't be interesting this so in order to count the number of dungeons with three connections will create a variable that stories how many dungeons with three connection or how many rooms with three connections we found so far so just name it moves it through yet set it to 0 to start and then we're gonna want to loop through all the rooms in the dungeon so like we did before we're going to want to go through all the dungeon keys and then if but get I and so this gets the room that's associated with the key position and from if you remember in our room we have the variable number of connections and this is where it's put into play and if we just check it the number of connections is created than equal to three and if it is then three we had one two and then now after I'd sleep through all the routes we're just gonna want to return if it is created equal to two and then now actually we've actually added to our generation code so while while the dungeon isn't interesting [Music] while the dungeon isn't interesting we're gonna want to replace it we're going to want to replace it with a new dungeon but with a different seed because if we use the same seed and it would just keep on generating the same dungeon so to do that I like to do receive times and range and that'll just give us a new dungeon all right with this dungeon generated should alright I found out what was wrong so in our connector really code we're increasing the number of connections by one but we're not checking if a connection already exists in that direction so that means if the if the room were to try to create a connection in the same direction as one that already exists it would just it would be the same exact connection except number of connections would still increase by one which we don't want so it's as simple things we just do [Music] new rural position and disconnected news or access see this dictionary and then in this dictionary you want to get this vector position any want to check if it's equal to null which means that if a connection doesn't already exist in that direction and if it doesn't then we run the connect [Music] and remember to replace all the numbers in here with the same vector that you used over here in here instead of negative 1 0 comma 1 negative some of you may have seen it already but I don't know what I did I said no but I typed one quiet type 1 here you're gonna want to replace all these ones with them and now if we run it we should only get the interesting dungeons [Music] I found the problem instead of new room position here we're actually gonna want to do I in the checking if a room exists over there my bad this is because we're gonna want to check from the original room relative to the original room instead of the room we just created and now finally sure don't work that's good that is good that's good right so we're basically done but if you want simpler dungeons or you could just decrease this number to let's say five and eight I probably wouldn't go below five [Music] oh yeah here's an error that you might run into with your program and this occurs due to the stack overflow because maybe there's too many variables being created let's see 51 yeah at this generator so we're creating a new instance with every run of these but every time you replace the dungeon we're actually not destroying them so to actually destroy them and free up some space we're gonna want to through all the dungeon rooms again and we're just gonna want to destroy them and okay don't we just use [Music] and no I lied firm in number of rooms you want to keep it as six because if it's at five is actually impossible for it to have two rooms with three connections so if you were to want to have just a dungeon with five then I wouldn't use this check over here either that or I would decrease this number to one or maybe just check for numbers with two connections but yeah this part over here is still necessary but if you're gonna use the same is interesting function as me then don't go below six rooms but even with this the dungeons that increase it's still pretty cool all right and that pretty much wraps up my dungeon tutorial let me know if you want to know how to actually create the rooms or if you want any more tutorials this is my first video on the channel so I'm really not sure what I'm gonna do from here yeah thanks for watching maybe consider giving a like or subscribe if to follow the channel if you liked it the video and thanks
Info
Channel: weekend
Views: 4,859
Rating: undefined out of 5
Keywords:
Id: mwk_8Q-jz90
Channel Id: undefined
Length: 32min 40sec (1960 seconds)
Published: Mon Jan 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.