≡ Menu

MiniDungeon – A Free Random Dungeon Jump Start for Unity

Over my holiday break I spent some time messing around with Unity on a basic random dungeon generator with lightweight RPG elements, and I’ve decided to post a version up here as a jump start in case anyone is interested in working on something similar. Hopefully this will help someone out.

I’ll start this post with a web player version and then the full Unity project download, and then go into a bit more detail below. I also want to throw out the caveat up front that this code is not polished and hasn’t been iterated on much or tested extensively.

With that out of the way, click the image below to check out MiniDungeon in the web player. There is a ‘walkthrough’ below.

MiniDungeonScreenshot

Project Download

This project is available on GitHub here: https://github.com/spgar/MiniDungeon

The Basics / “Walkthrough”

MiniDungeon starts off at a main menu, but the only real current option is to play the game. Clicking on Play takes you to the Home Base, which is what I envision as the hub in between adventures – a place to upgrade weapons/armor, train skills, shop for healing potions, maybe get some info from townsfolk, etc.

I also envisioned the Home Base as a quest hub, where you choose which adventure you want to go on and the future dungeon/storyline is configured to make this happen. So you might choose “Go Rescue the Princess” or “Go Slay the Dragon”, and the dungeon generator/storyline will be customized appropriately. In this demo, all you can do from here is click “Go on an Adventure”.

At this point you are launched into a randomly generated dungeon. There are some instructions on hotkeys in the upper-left, and then some info on your character in the upper-right. This randomly generated dungeon floor includes stairs up (green) and stairs down (red). If you move around (with WASD) to the stairs down, you can press spacebar to go to the next level. Note that the dungeon floor counter in the upper left will increment. As you go down each level, there’s a random placeholder story segment to advance the future story.

If you want to see a larger view of the dungeon, hit ‘Z’ to zoom out and then back in. You can also hit ‘Tab’ to skip ahead to the next dungeon level. Zooming out and then repeatedly hitting ‘Tab’ will show you the range of dungeon floors that can be generated.

Every once in a while you will hit a random battle vs a giant toad. Press ‘X’ to defeat him, you’ll notice that sometimes you’ll lose HP from this battle. If you run low on HP you can hit ‘I’ to open up your inventory and use a Healing Potion. Defeating a bunch of toads will level you up and increase your max HP/MP.

That’s about it – nothing staggering, but probably a pretty good jump start if you’re interested in making a random dungeon game. The only real complicated aspect of this project is the random dungeon generation, so I’ll go into a bit more detail on that.

Random Dungeon Generation

The random dungeon generation algorithm included (in the DungeonGenerator class) is something that I worked out off the top of my head. I did some quick research and couldn’t find an algorithm to do what I was looking for, but it’s possible I just didn’t look in the right place. My goal was something similar to the iPhone game Deep Deep Dungeon (link here), and I’m definitely happy with the results. The algorithm is definitely not optimal or optimized, but it works well enough and should get you started.

We start off with sixteen dungeon building blocks. Here’s a page from my notebook that shows what we’re working with along with my naming convention.

MiniDungeonBuildingBlocks

The prefabs that represent these can be found in Prefabs/Dungeon Building Blocks. These are what we’re going to piece together in order to create our dungeon.

In the DungeonGenerator object, you are able to specify the size of the dungeon – NumBuildingBlocksAcross and NumBuildingBlocksDown. The default values create an 8×8 dungeon, but it should work for most size specifications. I just tested a 1×8 dungeon floor (not very interesting), and a 100×100 dungeon floor (took a while to generate) – which both work.

Here is the basic algorithm that we use to generate a dungeon floor:

  • We start off by creating a grid of empty building blocks. The grid matches the size specified (discussed above), and the cells are defined in the (x, z) plane. (0,0) is in the bottom-left, (max, 0) in the bottom-right, and (max, max) in the top-right.
  • At this point we iterate through the entire grid, bottom-left to top-right, and choose a ‘valid’ building block for each cell position. What’s a ‘valid’ building block? I’m glad you asked!
    • If the surrounding cells are all empty, then we choose a building block type randomly. We leave out the ‘capper’ building blocks from this choice, which are the four blocks used to cap off dead ends (Nx, Sx, Wx, and Ex).
    • If some of the surrounding cells are not empty, then we choose a building block that matches the existing paths.
      • Let’s say we have a cell to our west that’s a passage from west to east. We’ll make sure that the block we choose has an exit to the west to match the existing path.
      • Let’s say we have a cell to our east that’s a passage from north to south. We’ll make sure to NOT choose a block that goes west, since it would create a disconnect with the existing path.
      • So basically we narrow down the possibilities based on surrounding cells, and then choose randomly from the valid building blocks.
  • After filling out the grid in this way, there’s the potential that the algorithm has generated ‘islands’. Sections of the maze that are separated from each other with no connecting paths. There might be a way to update the ‘filling out’ section of the algorithm to eliminate these islands, but right now I deal with it through some post processing.
    • I do a little bit of low-class pathfinding in the CellConnectedToCell() function to identify these islands and turn them into empty cells. There might be a better way to recover and connect the islands instead of deleting them, solid exercise for the reader.
    • Right now I consider an Island to be any section of the maze that has no way to connect to the center of the grid.
  • The final step in the pathway generation is to cap off dead ends. As mentioned above, there are four ‘capper’ dungeon building blocks that are dead ends. We go through the grid and identify any hanging passages that don’t connect to anywhere and cap them off with dead ends.
  • After completing the maze, we choose a random location on the path for the stairs up (start position) and stairs down (exit position).

And that’s it, we’re done! As mentioned above, there are some shortcomings and lots of potential optimization and improvements – but it works well enough.

Future Work

It’s not hard to come up with a list of future work for this project, since the possibilities are endless. Here are some ideas off the top of my head that should result in a pretty solid dungeon crawler:

  • Add in some real graphics, animation, sound, models, etc.
  • Create a real combat system, maybe stat-based and simulated or some sort of combat mini-games? Special abilities, magic spells, bonusus?
  • Add an inventory and loot system.
  • Add a shop/economy.
  • Extend the random dungeon algorithm to be more interesting. The one included works well, but is bare bones. Some potential extensions/improvements are discussed above, and there are plenty more…
  • Right now the dungeon building blocks are just basic passages, but there’s no reason they can’t be much more interesting.
  • Create different dungeon floor exit conditions. Maybe some levels need to be completed by defeating a specific monster instead of finding stairs down.
  • Make some real quests, and parameterize the dungeon to be different based on the type of quest you’re doing. Add some real storyline segments (talking heads, text, lots of possibilities here) that advance the story. Maybe add a branching quest structure?
  • Develop a hero.
  • Try using this approach for a different game genre. You could try making a FPS with random maps, for example.
  • Add support for additional building block ’tilesets’.
  • … and many, many more.

What Can I Use This For?

Feel free to use this project for whatever you want, I only ask that you take the time to drop me a message and let me know what you’re using it for.

Good luck!

Oh yeah, one last thing – here’s a link to a thread on the Unity3D forums for MiniDungeon:

MiniDungeon on Unity3d forums

{ 32 comments… add one }

  • Tim Miller January 21, 2011, 3:55 pm

    Steve, this is awesome! Thanks for sharing!

  • Code0wnz January 29, 2011, 11:37 pm

    This is great. Thank you for sharing your hard work!

  • Kalle Cederström March 4, 2011, 11:10 am

    Looks promising, but bit overwhelming.

    Since my unity 2.6.1 decided to upgrade your project, I’m now left with just code, prefabs and materials. Any change to get small How-To for building project from the scratch?

    Readme is a bit vague on those details and code does not contain any comments.

    • Steve March 4, 2011, 12:32 pm

      Hi Kalle,

      You are using Unity 2.6.1 Pro? The only thing I have tested this with is Unity 3, so there MIGHT be some incompatibilities – but I wasn’t doing anything exceptionally tricky, so I’d be surprised. I’m not sure what you mean about ‘building project from scratch’? You should just need to add all of the assets, and load the example project.

      The writeup in the blog is pretty complete, I hit a high level view of pretty much all of the components of the project… is there a particular section of the code that you’re having trouble with? Let me know and I’ll try to clear it up.

  • antonio rocha March 14, 2011, 4:54 pm

    hi
    i like it!
    wouldnt this look more interesting with 3D view assets?
    im more of a modeler/animator ,no programing stuff at all.
    this looks aperiodic tiling!
    i could help you with the assets,till i can master this by myself!

    • Steve March 14, 2011, 4:58 pm

      Yeah, better assets would definitely help! If you look at the example project, you can see all of the different prefabs that I used. Just replace those with sweet graphics and it all should just work..

  • antonio rocha March 14, 2011, 5:00 pm

    hi
    this looks like aperiodic tiling!
    im interested.
    i d like to help as modeler/animator.
    cause im not into scripts!
    i prefer 3D view for it,is it possible?

  • antonio rocha March 14, 2011, 5:04 pm

    how to change the view from 2Dtop to 3Dfrontal?

    • Steve March 17, 2011, 1:57 pm

      If you send me the new assets, I can update the scrips to provide a 3D version.

  • antonio rocha March 30, 2011, 10:25 pm

    ok steve
    thanks

  • Jot April 6, 2011, 11:10 am

    very impressive mini example! i´ve been WAY too afraid of the frog though :)

    thx!

    Jot

  • Smith May 5, 2011, 2:27 pm

    Hi Steve) can you make 3d generator) i have some stuff.
    for example…..
    can you moke for some models… WNES, WN , ES e t.c. =)
    but without Wx and WNS…

    Thanks =)

  • Smith May 6, 2011, 10:36 am

    oh…..another thing…….can you translate this to javascript?

    • Steve May 19, 2011, 11:41 am

      I’m not planning on porting this to javascript any time soon. If you, or anyone else, wants to do the port then feel free. It should be pretty straightforward.

  • Chris May 11, 2011, 5:24 am

    This is pretty fantastic! Thank you so much for sharing. I haven’t had the opportunity to explore this as much as I want but I was wondering if it would be terribly difficult to have randomly placed chambers/rooms scattered through the dungeon?

    I didn’t notice that mentioned in the post so perhaps that could be considered a feature request? Thanks again!

    Cheers,
    Chris

    • Steve May 19, 2011, 11:34 am

      You should be able to replace any of the hallway prefabs with rooms, as long as they still have the correct exits. You could even have a hallway and room version of each building block and choose randomly between the two.

      If I ever mess around with thus project again, I’ll probably add that – but it should be easy to do yourself if it is functionality you’re interested in.

      • Chris May 20, 2011, 4:57 am

        Thanks for the insight, Steve! Once I have some free time I’ll look into getting that added in. If you like, I’ll be happy to send you what I come up with!

        Thanks again,
        Chris

  • Gregory June 27, 2011, 2:45 pm

    Is there a way to add rooms? Or are there plans to make the dungeon have rooms?

    I would like to share with you my sample random dungeon generator I have made using javascript. You can set the number of rooms you want, min/max size of the room(s), and you can set how many key(s) you want. For example, if you set 2 keys, it will place one of the keys in a locked room. To unlock that room you need to find the first key in another room. It’s smart enough to do this for how ever many keys you want.

    I can send you the code or give you a link… whichever you want. I just want to try to help with this.

  • Laurence February 9, 2012, 6:12 pm

    I hope to build up this further and use it in a game. I hope this is OK thanks for sharing. 😀

    • Steve February 9, 2012, 6:16 pm

      Go for it man, us it for whatever you want. Please send me a link to your game when it’s done!

  • antonio February 18, 2012, 3:15 pm

    hi steve
    did you ever receive some .objs i send you back then?
    i supose you are finish with this but i wonder what could be achived by you:
    the whole dungeon on 3d with some stairs up and down.
    random 3d forms by using marching cubes
    animatonio@hotmail.com

  • Ataman Okuklu February 18, 2012, 4:31 pm

    Thanks for this great project. it is very helpful for me.

  • Stevedog March 28, 2012, 10:32 pm

    Thanks for sharing this. I’ve been playing around with various methods of creating randomly sized rooms for a dungeon but have yet to come up with an efficient way of creating tunnels that link them all together. Although I do have the added complication of trying to make it a truley 3D dungeon, that is by having rooms that are multi level and hallways that are ramps/stairs to the other levels. I was starting to think along the lines of what you spelled out here but hadn’t put it all together yet.

  • the12thplaya August 28, 2012, 11:52 am

    Thanks for the tiles suggestion i.e. the drawing of the corner tiles, t-junctions and straights as I’m going to use a similar approach for my 2D dungeon. I haven’t written the code yet but I’m thinking of doing the following to hopefully reduce or stop islands from appearing:

    * Loop through each row and check to see if there’s at least one tile pointing down. If a row hasn’t a tile pointing down, pick one randomly in the row and amend it so that it does point down, this might mean changing a left to right straight to a t-junction pointing down.
    * Then loop through each column and make sure that each column has at least one piece pointing right to the next column. Do the same as above if not.
    * After those checks place rooms randomly on the map, all of which should be placed on at least one corridor. This should also create extra joins to corridors that might still be drawn as an island.

    I’ve tested this on paper and it seems to work fine, but of course, there’s no guarantee that all paths would be connected to each other.

    I’ve got code at the moment that searches through all paths and assigns them a number and counts how many tiles are in that path. From that it finds the biggest path and deletes the others. This definitely works fine but it can be quite slow on maps that are bigger than 30 by 30 on the iPhone so I definitely need a new approach.

    • Steve August 28, 2012, 11:04 pm

      Good luck with your project man, let me know how it goes!

  • Wulfeous December 22, 2012, 2:54 am

    Has anyone considered adding teleportation pads to attach islands.

  • DENIS March 4, 2013, 4:16 am

    Огромное спасибо автору за это приложение, она мне очень помогло в освоении unity и C#!

    P.S. Извините что по Русские надеюсь с переводом сложностей нет

    • Steve March 4, 2013, 2:24 pm

      Thanks for the kind words, glad this helped you out!

      (My wife speaks Russian and she helped translate)

  • Nic September 7, 2013, 1:08 pm

    Hello! Nice nice project!
    Are you still developing it? I’m learning unity making a 2d game, something like zelda, and i’d like to try to use random dungeon generator. Do you think your project could be expanded to fit my game? Something like adding: rooms, items, more abilities and spells, enemies… and with RTS battle. ^^
    If you are making some progress, or you could gently help me to improve my game, it would be really nice! Even if you need some tests on changes you made. It’s an hobby for me, so if you want to collaborate! :)
    Have a nice day, best regards,
    Nic

  • Pete G October 12, 2013, 6:46 pm

    Hi, does anyone modified it to use rooms or other prefabs using more than 1 block? I really should appreciate it.
    Thanks in advance and good job!

    • Phil November 12, 2013, 7:00 pm

      To use more than 1 block per “room”, look for the following code:

      prefabBuildingBlockWidth = PrefabBuildingBlock_WNES.localScale.x;
      prefabBuildingBlockHeight = PrefabBuildingBlock_WNES.localScale.z;

      change it to something like:

      prefabBuildingBlockWidth = 28.0f;
      prefabBuildingBlockHeight = 16.0f;

      or however many blocks you want to use for either width or height.

      Thanks for this great piece of code! Currently trying to work with stairs placement, making it fit within the bounds of my rooms, any suggestions?

  • Ekats January 12, 2017, 5:47 pm

    Hi I’ll try to use this in my 2D unity game like Binding of Isaac, not sure how to exactly because the script is so long and don’t understand everything yet.

Leave a Comment