Roguelike procedural generation help

could you make a wick file for that? this is kinda confusing

sure one sec

on the first frame it go’s to a random number and the second i go’s to a random of 3 color’s
My Project11-21-2022_1-15-20.wick (2.1 KB)

this helps a little, but I know how to make a random number or color generator, I don’t know how to make random rooms generate like in a roguelike. random generation in roguelikes means to spawn rooms next to each other with doors or hallways connecting them with random pathways, I need to know how to make rooms spawn randomly.

search up “roguelike procedural generation” and you will see what I need.

i know what you are talking about so best thing to do is make a set amount of rooms that connect in a special way and add conditions like

rc=random.interger(1-5)
if(r==1){r2.currentFrameNumber=rc} else if(r==2){r2.currentFrameNumber=rc} else if(r==3){r2.currentFrameNumber=rc} else if(r==4){r2.currentFrameNumber=rc} else
if(r==5){r2.currentFrameNumber=rc}

and move objects dependent on r2’s data and make r2 move dependent on r1’s data thus alowing only some rooms to connect is some ways

You can do it in so many ways from very simple to extrememely complex
Ask yourself what do you expect from your levels

  • are they infinite or there is a start and an exit?
  • what degree of difference each level should have from the others? could you make a predefined set of rooms to choose from?
  • do you keep track of all the visited levels or they fade (no more accessible) as you proceed to the next
  • objects and enemies in the level are random positioned or they need to be placed in relation of the point of entrance? will you find them all in the same position and state should you return to the same room
  • do you have to visit some room before others? (find a key to open a door)

you have to make a deep analysis of your requirements before starting to think how to implement your code

  • should have a start and exit.
  • a set of rectangular rooms that connect via doors.
  • keep track of visited rooms.
  • enemies are randomly positioned but the numbers of monsters are low and they never spawn within 3 grid spaces of a door so you don’t get swarmed, objects are not randomly spawned like enemies and the layout is chosen from a random set and are based on what doors there are and where doors are placed.
  • you do not need to get a key eccept for the boss room key (the boss key is in a random room and is floating in the air and isn’t in a chest).

this is what I want, I know how to do some but not others.
the ones I need to know are:

  • how to spawn rooms next to each other so that they connect via doors.
  • how to make a key spawn if there isn’t one already.

if I need anything other than those 2 then I will add to the list.

this is the generation I want, I just want it to be bigger and make itself.
image

This sounds interesting…

I decided to try this out, here are three random results I was able to generate




My Project11-21-2022_13-44-54.wick (3.2 KB)


When I first started working on this, I wanted to make it easy for others to use, so I decided to have a variable for settings. Here it is:

var rooms ={
    maxRows:7, // how many rows max
    maxCols:7, // how many columns max
    arr:[], // empty array of randomness
    startX:240, // start x (starting left, then going to right)
    startY:120 // start y (starting up, then going down)
    size:50, // size of every room 
    spacing:10 // spacing between rooms
};

You can find this in the first line of the default script of the first frame (top layer).
You can change these settings to whatever you want (I recommend increasing the size)

The room.clones array should contain all the rooms, and the path.clones array should contain all the path objects connecting the rooms (if a path’s clone’s rotation is 0 degrees, it’s a horizontal path, if it’s 90 degrees, then it’s vertical).

How maps are generated

When you have a room like this:


It means that my code had set the room.arr array to the following:

[1,1,1,1,0,1,0,0,1,1,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,0,1,1,0]

To make things less confusing, look at the array this way:

[
1,1,1,1,0,1,0,
0,1,1,0,0,1,0,
0,0,1,1,0,1,0,
0,0,1,0,1,0,1,
1,0,1,1,0,1,1,
1,1,1,1,0,1,1,
1,0,1,0,1,1,0
]

The 1 means that there is a room in that position, while the 0 means that there isn’t.
These random zero’s and one’s were randomly added 49 times (columns x rows) to the array.
:warning: If you have smaller arrays, you are more likely to have rooms that don’t connect


Examples of rooms I generated with different settings








You might have to adjust this system a bit more to make it work the way you want it to.

I’ve also crashed my editor 4 times only to generate these 50x50 maps (maximum possible rooms count: 2500). Although my editor had crashed, it was still worth it.

It is possible, however, to generate a map this large without crashing your editor- if you’re interested, check out my 500 clones zero lag test, and my (outdated) how to adjust path objects in wick, or let me know so I can try making changes, otherwise, I hope this project is enough to help you with what you need!

1 Like

what if I don’t want halls and I just want the rooms right next to each other? and also make some random spaces blank like my example above?

You can do that by setting spacing to zero, and removing all path objects that have a width greater than the room sizes




File for that: My Project11-21-2022_17-49-46.wick (2.9 KB)


If you’d like to have all rooms be connected, you can try using a different randomizing method in order to achieve this.

2nd randomizing method

For example, this map here:


Has an array of:

[
1,0,1,1,0,
0,1,0,0,1,
0,1,1,0,0,
1,1,0,0,1,
1,0,1,1,0
]

Which is set through this code:

for(var i=0;i<rooms.maxRows*rooms.maxCols;i++){
    rooms.arr.push(random.choice([0,1]));
}

This is setting every value inside the array to a random number- but what if you were to set the entire array equal to an empty string, have one point be set to 1, then have the points around this 1 be set to either 0 or 1 randomly, and repeat the same step for all the 1’s until all the 1’s are surrounded by 0’s or reach the ends. That way, you won’t have any squares like these ones:

To demonstrate, let’s say this 1 here is the first part of the array:

"","","","","",
"","","","","",
"","",1,"","",
"","","","","",
"","","","",""

The points with a “_” are the ones that will be randomized next, with either a 0 or 1

"","","","","",
"","",_ ,"","",
"", _,1 ,_ ,"",
"","",_ ,"","",
"","","","",""

Let’s say you got this:

"","","","","",
"","",0 ,"","",
"", 0,1 ,1 ,"",
"","",1 ,"","",
"","","","",""

Then the blank points around the 1’s will be checked next, which are marked here again with a _:

"","","","","",
"","",0 ,_ ,"",
"", 0,1 ,1 ,_ ,
"", _,1 ,_ ,"",
"","",_ ,"",""

Next, something like this:

"","","","","",
"","",0 ,1 ,"",
"", 0,1 ,1 ,1 ,
"", 1,1 ,0 ,"",
"","",0 ,"",""

Then:

"","","",0 ,"",
"","",0 ,1 ,0 ,
"", 0,1 ,1 ,1 ,
1 , 1,1 ,0 ,0 ,
"", 0,0 ,"",""

And lastly, here’s how it’d end:

"","","",0 ,"",
"","",0 ,1 ,0 ,
0 , 0,1 ,1 ,1 ,
1 , 1,1 ,0 ,0 ,
0 , 0,0 ,"",""

All the squares are connected, this is completely random, and you won’t generate a map that has disconnected rooms like this:

(Fun fact: I wrote this entire explanation before actually trying to code it, but now I’ll try to implement this idea into my code to make sure it works)

Results






File using 2nd randomizing method: My Project11-21-2022_20-16-32.wick (3.5 KB)
Note: I also added a “min” value that makes sure you have at least a certain amount of rooms before stopping the randomizer. If the min value is set to be lower than the maximum possible number of rooms, you could get stuck inside the loop and the editor will freeze- so avoid that.
And I decided to have the first 1 start in the middle of the array, then from there, have it expand out.

so the problem I found that I don’t think you thought about is what is I want doors like the ones circled in red to be closed off instead of connected, this would make it feel more random and keep it from being like a pattern.
image
(also I know the bottom right is ineccessable, I didn’t notice)

nice work hamza
I bet your editor crashed ! :grinning:
I’d probably render only the room the player are into. (maybe also the ones immediatly close by)
Should I show a map I’d build it and then explode all clips into basic vectors

2 Likes

that should be easy
it’s basically a variable isKeyAlreadyPresent=false
when you build your map you randomly place your key in a room, record your key position and then set your variable to true

1 Like

does anyone know how I could do this?

I see what you mean…

After some testing, I found a pattern to remove paths without making a room inaccessible

Here’s a color coded version of the map you showed based on the path objects.


I used this to decide which path objects to remove.

tests






My Project11-23-2022_11-49-13.wick (3.2 KB)

However, while working on this, I realized that there’s probably an easier way to do this… so I deleted all the code I previously had, and with only 2 scripts I was able to accomplish similar results

Tests







(Note: In this file below, I do break apart the rooms. It’s unnecessary, and you can delete that line of code if you don’t want it, it’s in line 14 of load script)
My Project11-23-2022_20-17-31.wick (2.4 KB)
How this works is that the maze will start at the first room’s location, it’ll make a clone of itself, face a random direction (-90, 0, 90, or 180 degrees), then move half the distance, record the XY values to place a path there, then move the other half of the distance. The next clone starts at the same x and y values as the last clone, and repeats these steps. Then, once all the clone clips are placed, the path clip places clones in the location of the paths.
This way, every room should be accessable and divided properly.

Me trying to crash wick editor again

(I’m breaking apart clones this time)


( I’ll stop here, wick didn’t crash here, but it was loading extremely super slow )


thanks. is there a way to say have another clip have all the possible door arrangements of a room to be layered on top of each room so each room can look better while having the rooms have collision?

@Hamzah_Al_Ani
So nice !!!
thanks for sharing your toughs and methods !!!

@gamer_boi
You’re working on a grid system and it’s likely you breaked apart your clips so collision (hittest) wont be efficient. It’s probably better to use your character position to know where you are

1 Like

Yes, it is possible, and yes, the rooms were broken apart in the last file! You can remove the break apart line of code by deleting line 14 of the load script inside of the rooms clip, but you don’t need to.

The path objects aren’t broken apart, however, which makes it easier to find the possible door arrangements of a room (not to mention an XY array I used that has all of the door locations marked, “rooms.level1.paths”).

Since there is a path object between every room, you won’t even need to keep track of the room locations after they’re broken apart.

I agree, the character’s position will play a major role in determining whether or not

Note

The first room isn’t broken, only the clones are, so it could be your starting point as well. You could also find the location of the last room easily, and add an end there, or if you want, we can calculate the distances between all the rooms and the beginning to find the farthest one based on the X and Y values.

Note about broken apart clips

It’s important to mention that if you’d ever want to change the size of the rooms clip, after the clip is broken apart, you will find that the path objects inside of the clip didn’t change size.


For this reason, if you want to change the size of the rooms, you’ll have to go inside of the actual rooms clip and change the size from there rather than from the project’s timeline.

There’s no need to detect the room, if you were to snap the rooms to grid based on their width, then you can have a create a wall clip that’s snapped on the same grid based on the x and y of the player, and rooms.level1.paths array should return the x and y values of all “doors,” so if you were to also snap a clip based on the width of the grid divided by two, based in the player’s x and y as well, and check if the rooms.level1.paths array has the x and y of that clip, then check if the player is touching that clip (make sure to give it a reasonable width+height), then you’d know whether or not the player is inside of a path.

My Project11-24-2022_22-15-42.wick (4.4 KB)
(^ note that this project is a bit buggy+rushed, it’s only an example of how to detect rooms for collision)