• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Binding Of Isaac-like Map Generation

Well, I'm having some problems figuring out how to make a procedural map generation.

What I know is that I want map gen like in Binding Of Isaac, where you have a list of pre-made rooms to generate the map of each floor.

The Algorithm is simple (in theory, of course):
  1. Before the Floor start, generate a new room with a big width and height
  2. Place the 'Starting Room' on the center
  3. Iterate through the available doors and select from a list, one of a group of previously created rooms
  4. Check if it matches the rules to be in that place
  5. If True, copies it, and pastes it next to that door.
  6. Then repeat until complete a map
I know that I can use layer_set_target_room() to get and manipulate information/instances of other rooms but I have no idea how to copy this entire room and paste its content on a specific coordinate.

Thanks in advance!
 

TailBit

Member
I would use an array and drop key rooms at different positions, then connect them with pathfinding or you could use some maze builder codes

Then I would check if there is a cluster of 2x2 rooms (or other shapes), and see if I want to tell them to be the same room (if they are all connected) .. if it would be 2x2 if I included empty space, then I would also consider that a possible spawn location for a big room

rooms that have spawn conditions would not be placed into the array before all the other rooms have been put down, then you could check for "closest to boss room, but only connect to one wall", "furthest from boss room" or "connected to the most walls" .. if there are more locations that could be valid, then you could visit the rooms that could have been, and tell some of them to have indications for it to not be (skinny room or blocked off wall edges)

then all the rooms can just be their own room, no need to combine them, you just have room transition make it seem like you go from one room to the room beside .. unless you want to see on the other side of the walls? (then I guess you could get the id of the surrounding rooms and draw their tiles on a layer)
 
Okay! Now I get it!
So I can just get the information of where I want the player to go when crossing the doors.

The only reason for me to draw the entire map was to make a minimap easier.

Since I want one very similar to this:
1640134819322.png

Probably will use some sprite function to generate this based on the results of my map generation.

------

But there's just one thing that I don't know how to do using GML.
Is there a simple way to iterate through every 'door' in a room and get their position information? Because sometimes when I do this kind of iteration in the GMS2 it stores the general OBJ and not individual instances of the same OBJ.
 
I'm a little unsure how you are going about your dungeon? Your dungeon generation should be stored entirely separately from the actual rooms or whatever. Run your dungeon generation once at the start of the game and have it decide on the entire set of rooms that will be encountered (plus how they are laid out, etc). Then if you need to draw the minimap, you have access to that information. The data is separate from the actions (i.e. the act of moving to a new room shouldn't be what determines what room the player is going to, the generator should already have that data and you just read from it). If you're doing it this way, the minimap is trivial to draw, just read the generated data and draw sprites based on that (you could draw it to a surface and only update the surface when something changes, to save on processing a bit).

And based off of your last question, you need to learn the difference between instances and objects. This is a very fundamental part of GMS. Loop through your door instances (perhaps using a with() statement) and store the positions for each instance in an array (or another appropriate data structure). You should never refer to an object index (i.e. obj_door) if there is more than one instance of an object.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I'm a little unsure how you are going about your dungeon? Your dungeon generation should be stored entirely separately from the actual rooms or whatever. Run your dungeon generation once at the start of the game and have it decide on the entire set of rooms that will be encountered (plus how they are laid out, etc). Then if you need to draw the minimap, you have access to that information. The data is separate from the actions (i.e. the act of moving to a new room shouldn't be what determines what room the player is going to, the generator should already have that data and you just read from it). If you're doing it this way, the minimap is trivial to draw, just read the generated data and draw sprites based on that (you could draw it to a surface and only update the surface when something changes, to save on processing a bit).
This is EXACTLY how it should be done. In a game like Binding, each level is generated before the player goers into the first room... So you define some kind of storage structure (eg: an array of structs, where each array entry signifies a room, and each struct holds the room data), then use a series of scripted functions to "fill" the storage structure with information. First, defining the "rooms" that will be required for a level (the number of entries in the array) and then defining the contents of each room (filling the room structs with data). After this, the player starts the game and each time they enter a room you simply get the data from the struct and create the required instances. This is essentially how I created my mini-game Alpha Dog. That game actually only uses TWO GameMaker rooms, and simply switches between them when the player enters/exits a game "room", populating them differently each time based on the contents of the data structure I created to hold the level data.

You will no doubt be thinking "How do I do this though"? Well, my suggestion is to break it down into smaller tasks and then work through them:

1) Generate "rooms" and store them using some form of procedural generation. You may find it easier to use DS grids to start with rather than arrays or anything else since they make it easier to visualise the data.
2) Generate connections between these rooms.
3) Generate content for these rooms (this may require multiple sub-steps to add gold, pickups, enemies, etc...)

Also, if it's any help, I have an asset that actually does all this: https://marketplace.yoyogames.com/assets/4813/rogue-like-room-generator :)
 
Top