

The minimum spanning tree will ensure that all main rooms in the dungeon are reachable but also will make it so that they're not all connected as before. Again, either implement this yourself or find someone who's done it in your language of choice. In case you weren't doing this already, it's useful that your Room objects/structures have unique ids to them so that you can add those ids to the graph instead of having to copy them around.Īfter this we generate a minimum spanning tree from the graph. This procedure should be fairly simple provided you have a graph data structure/library at hand. As you can see from that interface, it takes in points and spits out triangles:Īfter you have the triangles you can then generate a graph. In my case I got lucky and Yonaba already implemented it. You either implement this procedure yourself or find someone else who's done it and shared the source. Now we take all the midpoints of the selected rooms and feed that into the Delaunay procedure. For the gif below the threshold I used was 1.25*mean, meaning, if width_mean and height_mean are 24 then rooms with width and height bigger than 30 will be selected. TKdev's approach here is pretty solid: just pick rooms that are above some width/height threshold.

The next step simply determines which rooms are main/hub rooms and which ones aren't. Roundm(ellipse_height *r * math.sin(t) / 2, tile_size) Local r = nil if u > 1 then r = 2 -u else r = u end return roundm(ellipse_width *r * s(t) / 2, tile_size), To spawn randomly inside this strip we can just change the getRandomPointInCircle function to spawn points inside an ellipse instead (in the gif above I used ellipse_width = 400 and ellipse_height = 20):įunction getRandomPointInEllipse( ellipse_width, ellipse_height) This ensures that the dungeon itself will have a decent width to height ratio: To fix this we can spawn rooms initially inside a thin strip instead of on a circle. The problem with this lies in how the physics engine decides to resolve its collisions whenever long rooms are near each other:Īs you can see, the dungeon becomes very tall, which is not ideal. For instance, consider the game I'm working on:Ĭombat is very horizontally oriented and so I probably want to have most rooms being bigger in width than they are in height. One issue that might come up is when you want to have rooms that are skewed horizontally or vertically. The gif below shows this in action as the blue outlines are the physics bodies and there's always a slight mismatch between them and the rooms since their position is always being rounded: The physics bodies themselves are not tied to the tile grid in any way, but when setting the room's position you wrap it with the roundm call and then you get rooms that are not overlapping with each other and that also respect the tile grid. In the gif I'm running the simulation normally but when you're doing this between levels you can advance the physics simulation faster. After you've added all rooms, simply add solid physics bodies to match each room's position and then just run the simulation until all bodies go back to sleep. TKdev used the separation steering behavior to do this but I found that it's much easier to just use a physics engine. There's a lot of rooms mashed together in one place and they should not be overlapping somehow. Now we can move on to the separation part. return roundm(radius *r * s(t), tile_size), roundm(radius *r * math.sin(t), tile_size) End - Now we can change the returned value from getRandomPointInCircle to: function getRandomPointInCircle( radius)
