Forum Replies Created
Good job figuring it out!
Let me know if you need anything else!
Great! I’m super happy that you’re having fun and making progress! Let me know if you need anything else. 🙂
Good luck with your project!
Yeah! I’m glad you got it to work! 😀
Sure I can give you some pointers.
1- I’m not entirely sure what you mean by “how many dungeons deep”…
Do you plan to string together multiple dungeons: enter one, leave this one to go straight to another and another, etc? If that is the case, unless there is something I’m missing you should probably consider doing a single dungeon and designing multiple levels. You get to decide how levels are attached together, so you can add your boss room or exit only in the final level and give it a priority so you are sure this room will be there in the game.
If you don’t plan to string together dungeons but plan to have them live side by side (ie: you leave town to enter a forest, or go down the town well to an underground cave, but the cave and forest do not connect), then I guess you should have some sort of mechanic to track if a dungeon is completed or not. Find an item, defeat a boss, free a princess! 😛 When your character achieves that, track this in your character data. Then, in each dungeon, you could add a spawnable (let’s say a portal) that only activates when your character has the proper data (completed x number of objectives) . So your boss room or exit should not have to be a part of any dungeon at all. It will be easier to customize a memorable boss room or exit room if it lives outside your dungeon. Your dungeon only allows connection to this place when the proper conditions are met.
2- I think loading the dungeon in its own scene is a good idea. But, if you allow your character to return to the town hub with a direct back’n’forth in the middle of your dungeon, I wouldn’t unload the dungeon. In fact, I would use additive scene loading (see Unity docs for that). So your hub always exists. (although when your character leaves it you can deactivate a lot of stuff to keep a good performance) When your character enters the dungeon the first time, you load the scene with the additive feature. As long as the dungeon isn’t completed, when your character leaves the dungeon, it stays alive. So you don’t have to transition between two scenes all the time and the loading time should be cut down dramatically. When your dungeon is completed and you don’t need to track where the character was when he teleported, you can then unload the dungeon scene. (If you do that and have multiple dungeons living side by side, you shouldn’t have 2 dungeons living at the same time though. A mechanic warning the player that entering a new dungeon would erase the progress in other dungeons could be a good idea.)
To keep things interesting, you can randomize the generation seed if the character wants to grind the dungeon and have a new layout.
I hope this helps you out!
I wish you the very best of luck in your project! 😀
Hi Mr Quaid!
There is a tool to help you debug your dungeon generation called “Dungeon Generation Report”. That will give more information on what went wrong. With the report info you can follow step by step how your dungeon is getting generated and when/where/why it fails. In fact, the first thing I need to help you is an export of that report.
Here is how to generate the report:
Select your dungeon game object in the scene and look at the Dungeon script in the inspector. You should see a checkbox called something like “dungeon generation report”. Check that box and launch the dungeon generation once more. You should see a new gameobject appear in your scene with the report attached to it. Once you select this game object, the script in the inspector has a button to open a report reader. From the reader you can navigate the dungeon generation timeline and there is also a button to create a text file export of the report. Remember to disable the report when your dungeon works: generating the report has a significant impact on performance, its not meant to be always enabled.
So, you can look into the report and try to identify the issue yourself, or you can send me the text file report and I will look into it for you.
Let me know how this turns out for you!
Cool! I’m glad you like it. Let me know if you try it out and how it turns out. 🙂
Hi Ermz! Nice to meet you!
Hmmmm… I never considered adding infinite generation to the Dungeon Master… Mostly because of the way the current generation works: it was planned to create coherent metroidvanias. Which means that the whole dungeon (or game) is generated and keys are distributed in a way that makes the game playable from start to finish with no unreachable zones. Adding a feature for infinite worlds would mean that the system does not create a “complete world” with distributed keys. The system cannot be sure that the whole world is reachable and coherent. It would need some major changes to create a seamless infinite world (or level).
Honestly, I don’t see myself implementing this feature in the near future (which means at least not in 2019, I have so many other things to work on) and I’m not sure if I would ever do this in the Dungeon Master. It would take time to investigate if it’s possible with the current asset or if it would be another separate asset.
There is something you could do though. It might be good enough for what you want to do, it’s an idea worth testing… But it wouldn’t create a perfect seamless world. There would be seams but I guess they could be subtle enough.
Since you cannot create part of a level or part of a dungeon and then play the game right way before the whole generation is finished, what you could try to do is to chain multiple dungeons together (actually alternating between 2). So at the start of your game, you would generate a first dungeon (let’s call it D1) and move your character inside of it. So imagine your character always moves from left to right:
D1 entrance D1 exit, links to D2 X----->------>------>------>------>------>------>------>X
When your character leaves through the D1 exit point, you store the D1 generation seed on a stack and you generate a new instance another Dungeon (called D2) with a new seed. D2 is located at the same location than D1, but it’s not fully rendered, so you have the entrance room of D2 rendered at the same time of the end of the D1 dungeon, so they occupy the same locations, but are not rendered at the same time: no clash.
So your character exits D1 to enter D2
D2 entrance D2 exit, links to D1 X----->------>------>------>------>------>------>------>X
Here, the same things goes, your character moves from left to right and when it reaches the D2 exit, you take the D2 generation seed and put it on the stack. Create a new random seed and regenerate D1 with this new seed. Transition from D2 to D1, and you’re into an infinite loop: an endless world.
If your character decides to travel back from right to left, as your reach the left entrance of a level, rather than generating a new seed, just take the latest generation seed from the stack and regenerate the previous dungeon with that seed: you get the same result you had and the player won’t see any difference. You then move the character from the entrance of the D2 to the exit of D1, etc. Keep alternating dungeons. So you really need 2 stacks to allow for travel in both directions: one stack for dungeons on the left and one stack for dungeons on the right that were already visited.
Things to keep in mind: you have to find a way to make a smooth transition between dungeons. A small cutscene? Opening a door? Passing through a wall? You need something to obfuscate the teleportation of your character from exit to entrance and vice versa.
Another thing to keep in mind: dungeon generation is fast, but can still take some time and create a small lag in your game. So you want dungeons that generate fast. Better to keep them small and simple. And you need a 100% generation success rate: multiple generation attempts are not your friend when you are looking for performance.
Also small dungeons would mean more seams to handle. So you would need to find a balance between generating dungeons very fast and not managing to many seams.
I think this could work pretty well if you find a creative way to handle the seams between dungeons. Something pretty cool: it wouldn’t cost a lot resource wise since you would be reusing pretty much everything. The only thing that could grow infinitely is the stack of generation seeds, which are mere strings. You could go on a very long time before crashing the game because of a lack of resources. Also you would never reach a point where the coordinates of your character would get ridiculous (like X=99999999999) because your character would always be bound between the entrance and the exit of the two dungeons and you control that.
That pretty much sums it up.
Let me know what you think! 😀
Hey, that’s a good looking navmesh. 🙂
Thanks for providing extra information about navmesh agent behavior. Let me know if you need anything else.
Good luck with everything!
Cool! I’m glad we solved one issue! 🙂
I agree with you, it’s more elegant to have the navmesh links included in the connectors.
Okay judging from the image you posted with your navmesh links, it looks like they are pretty wide but not very long. Navmesh links work best when they have a good margin around them both on the starting point and the destination point. You see the little “X” that appear in the middle of your navmesh link? I think this is in fact two heads of a bidirectional arrow. There are so close to one another that they look like an “X”.
I suggest you play around with your navmesh link attributes to see how this arrow works. To do this easily, drag’n’drop one of your rooms in the scene at design time. Use the buttons on the room script to render the room prefab and render one of the room connectors with a navmesh link. Now, select the navmesh link script and play with the length of the link. You can input big values for testing: something like 10 units long. You should see the arrow draw itself more clearly. Now that you see the actual arrow, you can rotate your link so that it points toward the next room (because now it looks like your links are actually pointing from the one side of your room to the other, rather than crossing the gap between two rooms).
Don’t be afraid to put the arrow’s destination point pretty far out in the next room, like I said, these like to have some margin. When it works well, you can then reduce the margin until it looks more natural.
Try this out and let me know how it runs out!
Good luck! 🙂
- This reply was modified 2 years, 3 months ago by vchevalier.
Nice to meet you!
Wow, that’s a messed up dynamic navmesh…
Okay I don’t have a lot of information, so I’m guessing based on the image you sent me…
Am I right in assuming that the floor are not the elements that have the “room navmesh” scripts (collider, mesh or primitive)?
Because even if the navmesh is misaligned, it doesn’t seem to have the proper size. Your floor tiles seem bigger than the navmesh.
Is it possible that you based your navmesh on colliders that are not aligned with the floor? Realigning and rebaking your default navmesh for each room might solve this issue.
Also I think you allow your straight corridor room to rotate along the y axis. This would explain why the navmesh of one corridor is slightly misaligned on the left and another one on the right. It’s okay to allow rotations for your room, but I would like you to confirm this, so I can consider that there are really only 2 cases of misalignment rather than 4. 🙂
Another thing to look at: are you using adjustments on your room prefab? (position, rotation or scale) If you use the scale adjustment, it may explain why the navmesh size and floor size doesn’t match. If you are using the scale adjustment also, it won’t work with the dynamic navmesh system because of a Unity limitation (I think I wrote about that in the user guide, I will verify this if you are using the scale adjustment).
Other than that, off the top of my head, I wonder: have you activated the track navmesh option? If not, try to activate it for a test. If you move your floor prefab around at runtime, does the regenerated dynamic navmesh now matches the floor or does it still have an offset?
Oh, of course, are you using baked navmesh for each of your rooms?
Ok, I will let you look into all of that for now. Please keep me informed of your progress!
Just for the sake of logging what happened: I went on a live debug session with Grimshad and we fixed the issue. The issue was that the rooms didn’t have wall connectors defined on the up and down directions, that prevented the level from generating.
Okay, so looking at the new log file, it seems the DM cannot find a room that allows for wall connectors toward the right, down and backward directions. You’ve shown me the level generation config with the specified wall type (thanks!) and a room’s left connector point (and it seems properly configured). Do your walls connectors have the same “wall connector type” than your level configuration or are there 2 wall connector types? (maybe one called “wall_type” and the other called “wall_connector_type”?) There is definitely something going on with your connectors / connector types. Can you give me more information / screenshots on your connectors, connectors types and connector points?
If you can’t find anything wrong with your setup, can you send me a zipped version of your project? If it’s not too big. I can debug it in my lab environment and find the issue for you.
For your level design concept, yes everything should be doable with regions, etc.
As for the mirror flip… Wow, that’s a first! The DM cannot do that right now. But I’m currently working on modular level generation. Which means, you could create your own level generation algorithm to implement the duplicating part (leaving all the other level generation algorithm as-is). It should not be too difficult, as long as your rooms allow to be turned along the y-axis. I’m actively working on modular level generation (since the last months, it takes time because it’s a huge feature), but I’m making good progress and expect to finish it before winter. If you can’t wait until then, then I suppose you could add code after calling the dungeon generation to actually copy all the elements and rotate them, but you would also have to do it for the map, etc. That’s a lot of work too.
Let me know what you find out about your connectors!
- This reply was modified 2 years, 4 months ago by vchevalier.
Thank you for providing the log file! That’s a huge help for debugging. 🙂
From what I can read here, an entry in the log file seems very weird. This sentence makes no sense:
(Suspicious Entry A): “Level Main has all its required rooms and is closed. Level has 1 rooms and min required rooms is 4.”
Okay, so going back to previous entries, I can also see:
(Suspicious Entry B): “Room Floor1 was selected to be added in the level. This was room was selected randomly within the full room candidates list because even if the level Main has not reached its minimum room amount (0/4), there are no open room candidates to use.”
And if we go even further back, we can see that rooms “Floor1” and “Floor2” were added to the list. So, there are two rooms, just like you said.
Okay, so quick context and explanation:
Since the Dungeon Master randomly selects rooms to add and since you want a random Dungeon that meets your criteria, the DM tweaks randomization by giving certain priorities to its rooms. In this scenario, you want your level to have at least 4 rooms. So, for that purpose, the DM will give priorities to rooms that allow multiple “open connections” (aka: something else than walls). When a room has a wall in a direction, it is not considered “connected” to the neighboring room if there is any. So the DM prioritizes rooms that have other connectors than walls to ensure you have enough connected rooms. When the minimum room amount is reached, this “open connection” priority goes away, and eventually your level is closed off with walls everywhere.
Back to your log file:
If we look at suspicious entry B, we can see that the DM tried to apply this “open connection” priority, but it couldn’t find any room with open connections. And since it couldn’t find any prioritized room, it fell back on the full list of rooms, crossing its fingers and hoping for the best. Well, “the best” didn’t happen and the generation failed. 😉
If I look back to what you told me:
“Only one connector type exists with 1 room connector. They spawn nothing, both rooms are setup so all connectors use this connector”
What I’m thinking right now (some things to verify on your end):
I get the feeling that the connector you added to your rooms all have the same type than the “wall connector type” of the level. If you go to your level generation config, there should be a connector type assigned to a property called “wall connector type”. This means that this is the connector type that should be considered a wall for this level. Now look at the connector points on each of your two rooms. If the connectors configured on these points all have the “wall type” of the level, then the DM thinks that your rooms never actually connect to anything, there are always surrounded by impenetrable walls.
Example of a working setup:
Let’s say we are generating a 2D top-down level with 2 different rooms in a 2×2 grid. To make it work and allow any type of room placement, here is what you need (I’m skipping over what I think you did correctly based on the log file):
1. 2 rooms with this connector setup: left-right-forward-backward room connector points have 2 possible connector configs: 1 is the wall connector, the other is something else (let’s say door). So you have 1 wall connector to allow the level to close itself and 1 other connector to allow rooms to connect to one another. The top and bottom connector points of your two rooms should only have the wall connector type. Since this is 2D, we don’t instantiate rooms over or under the first layer of room, so there are only walls on the Y axis. You rooms also both need a dungeon connector point, since we don’t know which rooms will appear, you need a starting point somewhere and all rooms should allow it. Your room generation config should allow for multiple copies of each room (at least 4 since this is the max amount of rooms in the level).
2. Your level generation config needs a min room amount of 4 and a max size in rooms of 2,1,2 (2 rooms wide, 1 room high, 2 rooms deep).
3. Your dungeon needs a dungeon connection (defined in the dungeon script panel), in your level.
I think, that’s pretty much it.
Please let me know how this turns out. If you get other errors, please let me know.
Cool! That looks interesting! I guess the boss should stay as the preset room then. Let me know how it goes! 🙂
Nice to meet you!
Ok, so I just want to make sure I get everything right before thinking about solutions:
The entrance at 2,0 and the exit at 2,19 are preset rooms? And you want to make sure they are always connected? Are these coordinates X/Y or X/Z? (I will assume X/Z with a top/down view since this is an outside dungeon)
If that is the case, unfortunately the DM doesn’t currently support “making sure all preset rooms are connected” in a level right now. I plan to solve this in the next release, but I can’t promise it yet since I haven’t started working on this.
Here is one solution for you:
1- Remove one of the preset room
2- Allow the entrance or exit to be spawned by any room that can show up at the level limit. (depending on your connectors/rooms setup. I can’t be more specific without more data on your dungeon configuration)
3- Use the “peripheral connector” feature to make sure your entrance and exit are always at opposite sides of the level. Your entrance connector should probably be “peripheral” with direction “backward” and your exit would be “peripheral” with direction “forward” (judging by your coordinates if they actually are X/Z).
I don’t know what your rooms look like right now, so you can determine which of the entrance or the exit would be the best candidate to be removed as preset room.
Try it out and let me know how it goes. Or if you need more information, please ask.
Good luck with your project!
Cool! Let me know how this turns out. 🙂