![]() |
#1 |
Swordsman
Join Date: Jul 2008
Posts: 308
![]() |
Over-engineering dungeon generation
I've been working on a new variant (yeah, I'll probably never finish it) and I decided to overhaul the dungeon generation code a bit. I'm sure my techniques are overly-complicated, inefficient, and generally involve more programming work than necessary... but I rather like the results so far.
A few quick notes: - I'm using the SAngband character set at the moment, mostly because I liked the doors - I'm writing everything in C# because I'm a lazy bum who doesn't like to deal with memory allocation issues - I've only implemented a handful of basic room types. It's very easy to add other types of rooms later, though. Here's a quick preview of the dungeon generation output. So why did I even bother writing a new dungeon generator? 1. IMO it's actually a very fun and interesting programming exercise 2. I wanted to be able to cram more rooms into a smaller space 3. I didn't like the Angband-style corridors; they meander a little too much for my taste From here I'll just describe the techniques I'm using. Feel free to tell me that I'm going about this all wrong ![]() Step 1: Make a random list of rooms At this point I don't worry about drawing rooms on the map or even deciding where they go. I just randomly create a list of 30-40 rooms with defined sizes. Step 2: Room placement I start placing the rooms by putting the 1st room in the center of the dungeon. The remaining rooms are distributed by essentially playing Tetris ![]() At each step, the algorithm considers the dungeon from a different direction: from above, left, right, or below. It really does play a form of Tetris at this point. It looks for the deepest hole into which it can slide one of the remaining rooms. The room is then placed into the hole, leaving 1-4 tiles as a buffer. We keep going until we run out of rooms or the Tetris algorithm has failed to work from every direction. Step 3: Which rooms should be connected? Now Angband just connects rooms randomly. It might (and frequently does) try to connect rooms on opposite sides of the map, and it doesn't care if the rooms between get turned into swiss cheese. Instead of random connections, I decided to use delaunay triangulation of the room coordinates. The resulting triangle edges form a pool of room connections that I construct the tunnels from. Not all of the triangle edges are used to make tunnels (that would make too many tunnels), but the triangulation ensures that tunnels are frequently drawn between neighboring rooms. From the edges that were obtained during the triangulation I construct a minimum spanning tree; this ensures that there are no disconnected regions of the dungeon. I use approximately 30% of the remaining edges to make additional tunnels, so that there are multiple paths between rooms. Step 4: Drawing tunnels Sometimes I like Angband tunnels, and sometimes they're totally crazy. They can move in and out of the same room multiple times, bend back on themselves, and generally behave in a very illogical fashion. I wanted my tunnels to be a little less erratic: more straight (on average), but with a few bends to add flavor and tactical complexity to the dungeon. I settled on using the A* pathfinding algorithm, with the following additional considerations: - Similar to Angband, tunnels into and out of rooms are only allowed in certain areas. We don't allow the pathfinder to move through certain types of rock. - The pathfinder incurs a cost penalty whenever the tunnel makes a turn. This forces it to prefer straight sections - I'm using Perlin noise in order to define invisible regions of "hard" rock. The pathfinder incurs a penalty for trying to move through hard areas. This prevents our tunnels from being completely straight. - It's cheaper to move through existing tunnels. Therefore the pathfinder will prefer to meet up with an existing tunnel whenever possible, creating intersections - Some of the tunnel intersections are artificial. One of the random "room" types is actually just a solid block of granite, but it still gets considered as a room when everything is connected. So when adjacent rooms gets connected to it it appears to be a natural tunnel intersection. This also causes occasional dead-end tunnels which are great for staircase placement. |
![]() |
![]() |
![]() |
#2 | |
Ironband/Quickband Maintainer
Join Date: Nov 2007
Posts: 1,009
![]() |
Quote:
Remember a dungeon does not consist only of rooms and corridors. If you can think of innovative ways of placing monsters, objects and other features, it will be a good thing. A.
__________________
Ironband - http://angband.oook.cz/ironband/ |
|
![]() |
![]() |
![]() |
#3 | |
Unangband maintainer
Join Date: Apr 2007
Location: Sydney, Australia
Age: 48
Posts: 872
![]() |
Quote:
That's quite a few rooms you've managed to pack into the level. What's the average room count per level (including or excluding 'room junctions')? Also, what's the line count for the implementation? Andrew
__________________
The Roflwtfzomgbbq Quylthulg summons L33t Paladins -more- In UnAngband, the level dives you. ASCII Dreams: http://roguelikedeveloper.blogspot.com Unangband: http://unangband.blogspot.com |
|
![]() |
![]() |
![]() |
#4 |
Vanilla maintainer
Join Date: Apr 2007
Location: Canberra, Australia
Age: 57
Posts: 9,465
Donated: $60
![]() ![]() |
This is very cool. I'm looking at revamping level generation for FAangband in the next version, so thanks for giving me some stuff to think about.
__________________
One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. |
![]() |
![]() |
![]() |
#5 | ||
Swordsman
Join Date: Jul 2008
Posts: 308
![]() |
Quote:
Of course it varies a bit depending on the sizes of the rooms. The number might shrink as I add larger room types. Quote:
Excluding the reused bits, the amount of new code (not ported directly from Angband) is probably about 300 lines. That count also excludes the code for picking room types, etc... That's C# code, though, so if the implementation were ported back into C then it would probably grow. |
||
![]() |
![]() |
![]() |
#6 | |
Veteran
Join Date: Apr 2007
Posts: 1,950
Donated: $40
![]() |
Nice dungeon, though I'd suggest that smaller levels than Angband uses at present are pretty much a good thing. (It used to be that dungeons would be much more size-variable than they are now.)
Quote:
![]() |
|
![]() |
![]() |
![]() |
#7 |
Apprentice
Join Date: Apr 2007
Posts: 72
![]() |
good work !
i've been always meaning to do a Dungeon Generator in C# , but somehow my line of work doesnt offer too many opportunities... or the time to! would like to look at that code there sometime !
__________________
"When you look into an abyss, the abyss also looks into you." - Friedrich Nietzsche. (does this mean the RNG learns my worst fears, mummy?) |
![]() |
![]() |
![]() |
#8 | ||
Swordsman
Join Date: Jul 2008
Posts: 308
![]() |
Quote:
- There's only a couple of streamers per level, so most of the tunnels are unaffected by them - Streamers are usually very long. The pathfinder just ignores them most of the time because crossing the streamer is inevitable. There's no benefit in trying to avoid it. But using perlin noise isn't much of a hassle. Since I already had the perlin noise function lying around, it was only 4 or 5 lines of code to tweak the pathfinder. Quote:
|
||
![]() |
![]() |
![]() |
#9 | |
Z+Angband Maintainer
Join Date: Jun 2008
Posts: 318
![]() |
Quote:
Of course, I maybe don't need the code. If I have to port it back to C anyway, I might as well just implement the algorithm myself. ![]()
__________________
----------------------------------------- Z+Angband: A Zangband evolution http://tinyurl.com/5pq2bd |
|
![]() |
![]() |
![]() |
#10 |
Swordsman
Join Date: Jul 2008
Posts: 308
![]() |
I've posted the source code for anyone who's interested in playing with it. It's well-documented (for me at least). Just a couple of notes:
- I'm using Visual C# Express 2005. But the code should also compile in VS 2008. - If you want to explore the dungeon properly then you might consider modifying the CreateRandomDoor function so that it only creates open doors. I haven't implemented lock-picking or searching for secret doors, so you might get stuck otherwise. |
![]() |
![]() |
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Display Modes | |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
getting past dungeon level 14 | Blackleaf | Vanilla | 6 | August 8, 2008 09:14 |
[FA] Found a dungeon | chris28 | Variants | 6 | June 4, 2008 22:00 |
Dungeon window size | Bodkin | Vanilla | 2 | March 30, 2008 04:48 |
Edit File For Dungeon Generation? | Zero | Vanilla | 3 | January 9, 2008 18:17 |
Dungeon Size ? | lugonn | Vanilla | 5 | September 2, 2007 12:11 |