Random dungeon generation given rooms?

I am trying to make a top-down Rougelite, but I really have no idea where to start for the random generation. As I said in the title I want it to generate a dungeon made of premade rooms, witch all are the same size, but my only solution was to have a check find what the room needed to be (ex: a exit to the north and south) but then pick a random object from the list of rooms, but that causes terrible lag and crashes, how should I be doing this?

I forgot to mention, for the rooms I am using a ScriptableObject to define what prefabs they use, and what doors they have

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Room", menuName = "Room")]
public class Room : ScriptableObject
{
    [Header("Doors")]
    public int NumDoors;
    public bool NorthDoor;
    public bool SouthDoor;
    public bool EastDoor;
    public bool WestDoor;

    [Header("Prefabs")]
    public GameObject WallTilemapPrefab;
    public GameObject FloorTilemapPrefab;
    public GameObject Spawns;
}

What a MASSIVE area of study, so much to learn and so crazy complex!

Oceans of digital ink await your consumption.

Here is one example:

https://journal.stuffwithstuff.com/category/roguelike/

Beyond that, source code for almost every roguelike is open source, so you can always study what the classics do, such as Rogue, Angband, Moria, Atom, POWDER, etc,

As for the crashes, start small, like 10x10 dungeons, no more.

And if you botch a loop exit condition, Unity will lock up.

Unity will lock up 100% of the time EVERY millisecond your scripting code is running.

Nothing will render, no input will be processed, no Debug.Log() will come out, no GameObjects or transforms will appear to update.

Absolutely NOTHING will happen… until your code either:

  • returns from whatever function it is running

  • yields from whatever coroutine it is running

As long as your code is looping, Unity isn’t going to do even a single frame of change. Nothing.

No exceptions.

“Yield early, yield often, yield like your game depends on it… it does!” - Kurt Dekker

Yeah, I know that my old solution sucks, I’m trying to make a new one, I just don’t quite know what to do yet. I have an idea for how it would run

  1. Generate a room to start in from a StartingRooms list
  2. Place said room on the tilemap, and add the position and Room prefab to a list and dictionary that takes values from said list
  3. Look at an empty space that a room has an exit to
  4. Find out what exits it needs, and if a maximum number of rooms has been met
  5. Take the values of the list of rooms, and then make a new temporary list that stores the rooms that match the criteria
  6. Pick a random room, and generate, then repeat from step 3 until all rooms exits have been satisfied.

Sounds awesome! Get coding… you could even throw that step list into ChatGPT, telling it that you’re working in Unity, and it would probably spooge out a simulacrum of a starting framework for you to fill in.

Just be absolutely sure you go back and understand 100% of what Chat gives you otherwise you won’t be able to move forward with it.

As you go, debug constantly because abstract graph theory problems like dungeon creation are really really really easy to get confused with. Do yourself a favor and prove every step of the way or you’re gonna have a very very unpleasant end time trying to go back and figure out where it went off the rails.

As you develop your dungeon, here is how you can begin your exciting new debugging adventures:

You must find a way to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the names of the GameObjects or Components involved?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://discussions.unity.com/t/700551 or this answer for Android: https://discussions.unity.com/t/699654

If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

If your problem is with OnCollision-type functions, print the name of what is passed in!

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

“When in doubt, print it out!™” - Kurt Dekker (and many others)

Note: the print() function is an alias for Debug.Log() provided by the MonoBehaviour class.

I’ll keep that in mind! Thanks!