Random Generation Done Right

Diablo 2 will forever be one of my favorite games. There are many aspects of the game that they just got right – Itemization, skill synergies, and the variety of monsters (Including affixes), to name a few. But one of the best things about it was its randomly generated maps. The ever-changing landscape kept the game feeling fresh even after thousands of hours.

Fast forward 23 (!) years: I played a lot of Diablo 4 at and around launch, and while I really loved the variety of builds and the constant drip of progression (Skill tiers, class skills, paragon boards, legendary affixes, etc), one of the areas I thought fell short was the random generation of their dungeons. Here are some examples of randomly generated dungeon layouts in Diablo 4:

These aren’t inherently bad, but something that really stands out is that the grid is extremely visible, something designers should aim to eliminate in today’s age of random generation. The loops and chunks used to generated the levels are also obvious, leading to players easily noticing repeats.

So how can we make this better? Sometime around 2020, I worked on randomly generated “dungeons” in a AAA 3D action game. While doing so, I did a lot of research into how various games randomly generate dungeons and mocked up some 2D prototypes of what the randomly generated spaces could look like using GameMaker. My first iteration looked something like this:

(Ignore the red circle – That was just showing that some chunks aren’t connected to the rest of the dungeon. Remember, this was just a prototype to prove out an idea, so it didn’t need to be perfect).

Okay, so that attempt wasn’t great. The grid is obvious, and since chunks are just rotated, repeated chunks are extremely easy to spot even in a small 4×4 dungeon like this. But making games (And prototypes) is an iterative process. Let’s see if we can do better! Here’s the second iteration:

All right, that’s a little better, but it still has some of the issues mentioned above. The grid is still extremely obvious. But repeated chunks are a bit harder to spot due to the addition of black circles randomly within each chunk. In the final game, you could imagine these being any sort of blocker to break up the space a little differently, even when the same chunk is used – Boulders, pillars, statues, holes, quicksand, trees, etc. I call things like this “axes of randomness” – The more ways in which we can make an experience random, the harder it will be for players to notice repeated content. See below for more examples.

So we’ve made some progress, but let’s see if we can do even better! Here’s the final iteration of the prototype:

Looks pretty good, right? Using more organic-looking chunks, I was able to mask the fact that the chunks are placed on a grid. The random rotations and the randomized black circles help hide the fact that there are repeated chunks, even in a 7×7 grid like this and using just 20 unique chunks. At this point, we decided the idea was worth pursuing in the real game, so I got to work building the real thing, but here are some more improvements that could have been made to these maps and the actual spaces within the game:

  • Create more unique chunks used to generate the spaces. This only used 20 unique chunks, so we were guaranteed duplicates in a 7×7 dungeon like the prototype.
  • Make sure that the same chunk never appears in the same dungeon with the same rotation (Or maybe at all, if you have enough unique chunks).
  • Clean up the randomized circles so they’re placed in better areas, as opposed to randomly.
    • For example, we could use them to block off paths so traversal through the space was different even when the same chunk is used.
  • Add additional axes of randomness to mask the times when the player sees the same chunk.
    • Randomize enemy placements, types, and number within each chunk.
    • Randomize the textures that each dungeon (Or chunk) uses.
    • Randomize environmental effects – Fog, lighting, weather, spores, dripping water, etc. within each chunk (Or in the dungeon as a whole).
    • Randomize puzzle placement and type within each chunk.
    • Randomize trap placement and type within each chunk.
  • Block off exits that don’t lead anywhere with rocks (ie, a cave in), vines, walls, magic barriers (Like in Gunfire Reborn), etc.
  • This would be a bit more expensive, but when connecting these in 3D, you could use non-axis-aligned rotations and simply connect the entrances using something like sockets, allowing you to rotate these chunks at “any” arbitrary angle and escaping from the grid entirely.

In case you’re curious, here are the 20 unique chunks used in the final version:

Fun fact: The “dual entrance” design was inspired by Castles of Mad King Ludwig, a board game recommended by my lead when I started these prototypes.

Now, these are all just prototypes, but the bones of the design are definitely present, and turning this into a finished product is totally doable. Going back to Diablo 4, it’s not that Blizzard did a terrible job with their randomly generated dungeons – They’re fine enough and get the job done, and certain dungeons definitely have a different feel to them (I particularly enjoyed the Flooded Depths). My main gripe is that their dungeon maps are obviously gridded and have the tell-tale signs of being randomly generated, which I never really noticed in Diablo 2, a game the same company made over 20 years ago! Nowadays, with a little work we can do wonders to hide these things from players, making the dungeons feel much more organic and realistic. The Diablo series used to be at the forefront of random generation, so it’s a bit sad to see Diablo 4 fall a bit flat in that area.

Leave a comment