Dungeon generation


The crossword/dungeon is at the core of the game.  The crossword is used as the layout for the dungeon, but not directly. I had to take a few steps to get to an algorithm that generated accurate and aesthetic dungeons. Here is how I did it.

Data source

First, I needed some crosswords. I considered using (or writing) a crossword generator, but for the initial pass of the game I "borrowed" existing crosswords from old online newspapers, specifically I used 2025 crosswords from the Washington Post. Crossword data is stored in a format called ipuz. I was able to fetch the ipuz data from the WP crosswords and I wrote an ipuz logic module to work with the data. 

I learned that not all crosswords are designed the same way. American style crosswords are very dense with almost no gaps between letters, while British style crosswords only file half of the grid, leaving gaps between letters. I went with the dense American style.

Inspiration

I had an idea in mind of what I wanted the dungeon maps to look like. From previous projects I was aware of a one page dungeon generator that made dungeons that looked like this. I liked the tilt and the grid lines.


First attempt

My first generation attempt simply rendered the entirety of the small demo crossword from the ipuz reference:

Small crossword exampleSmall crossword as dungeon

This worked just fine for the small demo crossword, but for a full sized crossword it was way too large!

A full crossword as a dungeon

The sparse dungeon algorithm

I wanted 5-20 words per puzzle based on level, so I needed a way to select only some of the words from a full puzzle. I also needed the selected words to all intersect. At first I was just going to randomly remove words from the full puzzle until arriving at the desired word count. But that risked creating unconnected groups.

A better approach was to randomly select a starting word, then randomly a letter from it and add the intersecting word, and continue that process until reaching the desired word count. This guaranteed a single connected sub-group from the puzzle. But there was a big problem with this approach.

The problem occurred if two selected words were adjacent and parallel. Each adjacent cell would form 2 only letters of a complete word (recall that I used the dense American style of crosswords). This left incomplete words in the puzzle which wouldn't work. I considered "expanding" any partial words until all words were full, but this would grow to cover the entire puzzle, defeating the point.

The final algorithm

My ultimate solution was to only use the odd rows and columns of crossword data and follow the same approach as above. This made it impossible for any partial words to exist. It also had a benefit that each puzzle could be used twice with no word overlaps (odds, then evens). The only other adjustment I made was to weight word selection based on shorter word lengths and centroid proximity to favor generating smaller, easier, denser dungeon shapes.

Final dungeon generation algorithm

Extras

The final touch was to include colorization, simple lighting effects, and special bonus rooms to give the random dungeons unique character and diversity. I came up with half a dozen special rooms with unique generation rules in non-letter squares, which filled in some of the gaps in interesting ways and finished the visual aesthetic.

The final cross word dungeon generation algorithm

Leave a comment

Log in with itch.io to leave a comment.