thank you for this godsend of a tutorial and algorithm. its still procedural and yet im still able to build preset rooms, easy to adapt, and your tutorial is informative. definitely using this for my own roguelite, and ill recommend this to others if needed. you earned yourself a subscriber
Working on something similar, except I plan to have the rooms connect each other instead of using hallways. Did not expect to find a roblox tutorial, great job! :D
Script :- local ReplicatedStorage = game:GetService("ReplicatedStorage") local AssetFolder = ReplicatedStorage:WaitForChild("Asset") local function Generate(StartingPosition,Maxrooms) local CurrentRoomGenerated = 0 local function Branchout(Model:Model) wait() if Model:GetAttribute("Room") == false then for i,v in pairs(Model:GetChildren()) do if v:IsA("BasePart") and v.Name == "Waypoints" then local NewPosition = v.Position + v.CFrame.LookVector * 4.25 local CheckBox = Instance.new("Part", game.Workspace.Debris) CheckBox.Anchored = true CheckBox.Size = Vector3.new(7.5,4,7.5) CheckBox.Position = NewPosition local partsInCheckBox = game.Workspace:GetPartsInPart(CheckBox) CheckBox:Destroy() if #partsInCheckBox > 0 or CurrentRoomGenerated >= Maxrooms then v.Transparency = 0 v.Material = Enum.Material.WoodPlanks v.Color = Color3.new(0.588235, 0.403922, 0.4) else local NewTilePiece = AssetFolder:GetChildren()[math.random(1, #AssetFolder:GetChildren())]:Clone() NewTilePiece.Parent = game.Workspace.Dungeon local cf = CFrame.new(Vector3.new(NewPosition.X, StartingPosition.Y, NewPosition.Z), v.Position) NewTilePiece:SetPrimaryPartCFrame(cf) cf = CFrame.new(NewTilePiece.PrimaryPart.Position) * CFrame.Angles(math.rad(0), math.rad(NewTilePiece.PrimaryPart.Orientation.Y), math.rad(NewTilePiece.PrimaryPart.Orientation.Z)) NewTilePiece:SetPrimaryPartCFrame(cf) if NewTilePiece:GetAttribute("Room") == true then CurrentRoomGenerated += 1 end coroutine.wrap(Branchout)(NewTilePiece) v:Destroy() end end end else local possibleHallways = { AssetFolder:WaitForChild("Hallway1"); AssetFolder:WaitForChild("Hallway2"); AssetFolder:WaitForChild("Hallway3"); AssetFolder:WaitForChild("Hallway4"); AssetFolder:WaitForChild("Hallway5"); } for i,v in pairs(Model:GetChildren()) do if v:IsA("BasePart") and v.Name == "Waypoints" then local NewPosition = v.Position + v.CFrame.LookVector * 4.25 local CheckBox = Instance.new("Part", game.Workspace.Debris) CheckBox.Anchored = true CheckBox.Size = Vector3.new(7.5,4,7.5) CheckBox.Position = NewPosition local partsInCheckBox = game.Workspace:GetPartsInPart(CheckBox) CheckBox:Destroy() if #partsInCheckBox > 0 or CurrentRoomGenerated >= Maxrooms then v.Transparency = 0 v.Material = Enum.Material.WoodPlanks v.Color = Color3.new(0.588235, 0.403922, 0.4) else local NewTilePiece = possibleHallways[math.random(1,#possibleHallways)]:Clone() NewTilePiece.Parent = game.Workspace.Dungeon local cf = CFrame.new(Vector3.new(NewPosition.X, StartingPosition.Y, NewPosition.Z), v.Position) NewTilePiece:SetPrimaryPartCFrame(cf) cf = CFrame.new(NewTilePiece.PrimaryPart.Position) * CFrame.Angles(math.rad(0), math.rad(NewTilePiece.PrimaryPart.Orientation.Y), math.rad(NewTilePiece.PrimaryPart.Orientation.Z)) NewTilePiece:SetPrimaryPartCFrame(cf) if NewTilePiece:GetAttribute("Room") == true then CurrentRoomGenerated += 1 end coroutine.wrap(Branchout)(NewTilePiece) v:Destroy() end end end end end local StartingRoom = ReplicatedStorage:WaitForChild("StartingRoom"):Clone() StartingRoom.Parent = game.Workspace.Dungeon StartingRoom:SetPrimaryPartCFrame(CFrame.new(StartingPosition)) CurrentRoomGenerated +=1 Branchout(StartingRoom) end Generate(Vector3.new(0,10,0),500)
@@____________________________x Or you could've just followed the tutorial and taken only 30 minutes. Hate to say it but actually good games come from effort.
Thank you for the tutorial, was able to change things where i needed to change them and ultimately got exactly the type of dungeon generator i needed, god bless your soul 🙏
Once i heard AI voice I was gonna switch to another video, but you explained this perfectly and in a clean way, I got so fed up of those AI content creators that spread pure bullshit. But you're far from that, you earned a subscriber.
Hey y'all, if you're having trouble with generating rooms and it tends to bug out having weird rotations, make sure to make all the primary parts of every room ( except the starting room ) face the direction of the empty waypoint direction ( starting room just faces the direction of the waypoint )
@c00lbaconn what controls the empty spaces is the courotine.wrap(branchout) function, if all of the preset rooms are in the right order it should work as intended because it still generates them all the exact same way, aligning to the orientation of the openings in the hallways
oh my god dude you won't believe how long i've been looking for a tutorial like this. similar to how lethal company generates it's rooms. thank you so much dude lmao
Hey I have a request for you, can you explain wave function collapse algorithm to make random generation of a map? You do a lot of effort on your videos, thanks for making these videos.
@@TextChange Thank you for accepting my request, it will do a lot of help, I can't thank you enough, you made my day. It would be appreciated if you make the terrain like this ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-PTwqUfjFsac.htmlsi=gpckP_Rwxp5XTUJ- . If you don't know about it or have no idea then you can get an idea with this ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-MyMbbmWVCDw.htmlsi=1aoECPQRC0nua9E0 . Please help me if you could, my clueless brain can't figure out how to start.
@@TextChange Thank you for accepting my request, it will do a lot of help, I can't thank you enough, you made my day. It would be appreciated if you make the terrain like this ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-PTwqUfjFsac.htmlsi=gpckP_Rwxp5XTUJ- . If you don't know about it or have no idea then you can get an idea with this ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-MyMbbmWVCDw.htmlsi=1aoECPQRC0nua9E0 . Please help me if you could, my clueless brain can't figure out how to start.
Thanks for trying to respond to everyones comments, thats really nice! I wanted to ask you how much did you practice to get to this level of scripting?😅
@@TextChange How old are you, im asking because im curious about if school stopped you from learning scripting sometimes, because of homework study or other things😅
@@oleNikolic I recently graduated from college. you don't need to script 24 hours a day. usually I scripted only for 2~3 hour a day. just think it as playing game.
Well, without any information it is really hard to tell what is wrong with your model. But i assume you have different size rooms. This is a problem because this system wasn’t created to handle room with different size. You have to make sure that your all rooms are same size
I haven't finished the tutorial yet but it says SetPrimaryPartCFrame() is deprecated 6:05 so instead I'm using Model:Pivot() which is the same thing. Also from what I've seen you can put most of this in a module script
Yeah SetPrimaryPartCFrame() and Model:Pivot() is the same thing. It Just that I'm Used to using SetPrimaryPartCFrame(). And yeah you can use module script but i didn't wanted to make this more complicated.
Very clean and simple system for dungeon generation, though I have to ask, what's plug-in you use for tracking how many studs you scale/move a part with in the video? Appreciate you sharing your work, and am looking forward to future videos!
So I'm new to making things on roblox, if the Room/hallway has script based items(ex: doors) would I have to keep the scripts in the Room/Hallway to be replicated or would it be kept seperated
Hallways are overlapping with the rooms and becoming quite messy. There are also times they spawn under the map and rotated. do you have an idea on what the problem is?
What did you do? 😂 the overlapping is happening because you scaled up asset. After scaling you need to follow this part 6:35. And i don't know why they are spawning under the map and rotated
@@TextChangets no longer overlapping, I put the primary part to the floor instead of the actual middle of the room so my bad. I'll try to experiment around in the angles to fix it. Thanks for the tutorial
i love this tutorial, please keep making more of these, using and explianing the terms was also very nice, also how do you add Z levels to a system like this?
for some reason when mine runs it generates the start room and a part that is put in the debris folder and i think its supposed to be the checkpart but it appears under my starting room and like close to the primary part's x & z coords. im getting no errors and idk what i did wrong. ive set all my primary parts and waypoints to the correct direction and made sure they have the right names. Ive called all the functions and done basically everything said in any other reply under this video. is there something i missed with the checkbox part of the video or is it something else?
Maybe you messed up the coordinates. It is really hard to say what is wrong with your code. Maybe you should try the model i have provided in the description.
Pretty nice, and very fast. Btw, how could I go about having "specialty" rooms, ensuring that they are always placed somewhere in each dungeon? Like if I were to have say, a shop, and I wanted to make sure each dungeon has a shop. Of course I could just make it so the generation will check if it has placed a "shop" room already or not, and if yes, then exclude the shop from the usable tile pool, but otherwise it's entirely up to the mercy of RNG if a shop room is chosen. Then at the end of generation, if it sees that no shop room was placed, it'll regenerate the dungeon, repeating until it successfully places a shop. Now this will "work", but it's definitely not ideal, and becomes an exponentially bigger problem the more "special" rooms that are desired. Since if there's only 1 specialty tile, chances are the dungeon will end up having it. But if there's say, 5 specialty rooms I want each dungeon to always have somewhere in their layout, there's a much bigger chance one of them gets missed and the entire dungeon will need to regenerate. And it may be possible the dungeon will need to regenerate a dozen times, leading to a long wait time for players.
@@fearlesswee5036 here what you could try. Once all rooms are generated, list all rooms that have the same number of waypoints as your shop room. For example, if your shop room has 4 waypoints, find all rooms with 4 waypoints. Randomly pick one from this list and replace it with your shop room. If you want to have more then one shop room then repeat these steps in a for loop. It is still not ideal, because it is still dependent on RNG. Lets say you want 3 shop room (shop room has 4 doorways) But there are only 2 rooms with 4 doorways. You see the problem now? How to fix it? Instead of making special rooms, you should have your shop as a separate model. Now you can just select a random room from the dungeon and position your shop in that room. It is fast and easy method
@@TextChange Well the "shop" would be a defined room, for a special layout + set dressing. I plan to use large 100 stud tiles to have a lot of room for the room/hallway layout to deviate. So like a 4-way intersection might not be a straight path, but have more twists/turns. I didn't even think of placing them *after* the dungeon generates; finding a random 4-way room for example and replacing it with the special room. That's very smart. I could also probably use this to put an "exit" or "end room" for the dungeon, using a basic magnitude check to exclude room tiles too close to the start. Thanks for taking the time to respond and the tutorial!
@@the_actual_alex yeah it it possible. It will be a little hard work, so bare with me. First thing you need to do to make your room. And place it somewhere else. And then after generation process is complete, you have to make a table/array of all the room with the same amount of doorways as your intended room. For example, Let's say your intended room has 2 door ways. So you will make a table of all the room with 2 doorways that were generated. Now choose a random room from that array and replace it with your intended room. There are many other ways to do it. But this was the first thing thar came in my mind
Could you make a V2 of this tutorial that explains how to make a procedurally generated dungeon or city (whatever) with rooms of varying scales and roads of different sizes? Like you could have a room of 12x18 or 6x8 and roads of 8x3 or 15x3
he said in another reply you can achieve this by making the tile as big as your biggest room size, then make a bunch of halls that look like multiple smaller halls combined
is there a way to make it choose through different types of dungeons? like different colors of walls and floors, and maybe like make the rooms and hallways be restricted to a big box like zone?
Of course, after all possibilities are endless! it may not completely satisfy your needs, here are some ideas to consider. To confine dungeon generation within a specific area, you can implement a check during room spawning to ensure the chosen coordinates fall within the designated zone. For instance, let's designate an area within 200 studs from the origin (0,0) in each direction. When spawning a room, verify if the selected coordinate satisfies the conditions: (Vector3.X = -200) and (Vector3.Z = -200). If these conditions are met, proceed with generating the room; otherwise, transform the waypoint segment into a wall. (Assuming you're referring to themed dungeons like jungle or desert) Now, for different types of dungeons, organize themed rooms and hallways into separate asset folders. For instance, create a folder named 'Jungle' containing jungle-themed assets exclusively. Then, introduce a string value (let's name it "themevalue") to determine the appropriate asset folder dynamically. Here's an example: local assetFolder = ReplicatedStorage:FindFirstChild(themevalue.Value) I hope this guidance proves helpful! If you found it useful, consider showing support by liking the video and subscribing to my channel-it truly motivates me.
@@TextChange would love to learn how to do this for procedural dungeons. even a dungeon series tutorial would be awesome since there aren’t any on youtube.
How long did it take you to learn from scratch to this level of advanced lua scripting? It’s honestly amazing, I’m currently learning lua and I started a week ago, for now I only know the keywords, I have no idea how I can use this stuff I’m learning 💀
as far as i know doors doesn't use this form of dungeon gen with multiple branching paths and is usually just one path with side rooms (minus.. like 1 room in the mines and maybe something with the mines seek chase)
@@colin_the_protogen Doors uses a similar system probably but it has more straightforward rooms. The difference is in random events and itemspawns, which also happen on their own thread isntead of being predetermined in the room itself.
@@reduvicemaster 😅 People often use the code without understanding it, then mess it up and complain that it doesn't work. It's a sarcastic way of saying, 'Just take the code and get out'. If you take a look at the comments on this video, you will understand what i mean.
8:41 at the bottom, when calling the generate function, the second parameter is the maxrooms. As this was a kind of advance tutorial, i assumed people would get it easily
is there a work around for the room amount becoming too low? I've once gotten rooms in a 2x2 because they ended up connecting that way even though the max amount of rooms was around 1000 and I really would like for this not to happen.
Try the model i have provided in the description. I had solved that problem after the video was released. And i didnt bother mentioning. Sorry about that
How would I make it so I can have different sizes of rooms? Like what if I have a REALLY long hallway, but also a really small hallway? I tried doing the size thing but that doesn't seem to work at all.
You can do it if you can somehow make it possible so that Every rooms and hallways can be placed adjacent to each other. I really can't explain it to you without a separate video.
Hello, I noticed a slight difference between the video and the Place that you left under the video. In this place, your PrimaryPart is invisible and does not exist as a child object in the room. Do I have to do this in my Place? I just don’t know how, because you didn’t specify this in the video
Is the generation broken in the model that i provided? Anyway if there aren’t any PrimaryPart in any of the room and hallway the kindly make one as shown in the video. Being invisible or not does not matter
I found this video really informative and helpful! I'm new to Lua and Roblox Studio, and I was testing your script with some custom rooms I built, and I'm getting an error I don't know how to fix. Upon running the game only the starting room generates, and I get this error message: Model:SetPrimaryPartCFrame() failed because no PrimaryPart has been set, or the PrimaryPart no longer exists. Please set Model.PrimaryPart before using this. I will note that I trimmed your code to remove all the mentions of the 'room' boolean attribute because my game is trying to generate only rooms, no halls. Is there something obvious I'm likely missing or is there something I could try?
@@TextChange Thank You! That fixed one of the many bugs lol. I just assumed the part had to be named PrimaryPart and I didn't see that you had changed the property in the video. Again, thanks for this amazing tutorial!
I got the starting room to spawn but nothing else spawned around it. I saw that there were two scripts, one in workspace called, "Script" and one in Replicated First called "Nothing is here" which do I put the code in? Is anything supposed to be unanchored?
Hey do you have a discord or something? This tutorial is so cool but it's hard to make my own world generation based off this because I'm not sure how to limit it's reach or anything... would love to speak to you about it
I got the script to work now. But for some reason, nearly all waypoints are turned into dead ends. Even if it isn't a dead end. Is anyone else experiencing the same issue?
There is already a limit to how many rooms will be generated. At the very bottom of the script where the generate function is being called. The 2nd parameters is the number of rooms you want to be generated. Liking and subscribing is highly appreciated
man i even copied the exact code from the comments after typing it all out myself and it still didn't work for me, only generated the starting room and then gave nothing in the output console
@@imButterGuy In our generation process, waypoints are crucial. If there are no waypoints in the workspace, the generation of rooms or hallways can’t continue. Waypoints help us know where to place new rooms and keep the generation going. So make sure all the room in your asset folder has at least one waypoint.
Yo great video man this really helped me out, how would i go about adding varying room sizes for example a big hall room (For players to fight in) and multiple starting rooms that connect to each other with in the dungeon?
Heres some idea! Your tile size and checkbox size should be same as the biggest room. Now make smaller room and in the doorway try adding some parts so that the doorways match when rooms and hallways are placed side by side.
what if in a scenario one of the hallways have a waypoint that directly points towards the starting room, and as it already reached a max rooms limit it would try to generate a shop room INSIDE the starting room. is there a way to prevent this?
i keep getting starting room errors. my primarypart is in the middle of the room. I tried taking yours and upscaling it and yet it still does not work. Any fix?
Well there are many ways this can be done. But the simplest way is to place something(like a part) Where you don't want to generate the rooms. Because when the algorithm check for occupancy it will detect the part and will not generate there anymore. But this can be really annoying because its has to done manually.