Project 2 – Dev Diary 1

With the development of Reflex practically complete and the release of the Android (and possibly Amazon Fire App) version within the next few weeks I decided to start prototyping what could be my next game.

For ‘Project 2’, obviously there’s no title at the moment, I wanted to try something different and something that would be replayable over and over.

So, I hit on the idea of making a twin-stick rogue lite/like game that uses as many random elements as possible. The first element in this process will be the level maps. I needed to come up with a way to create a multi-room map dynamically. Boy did this make my head hurt.

I started initially by creating an array that was 50 x 50 cells in size. This would make it large enough to cover all eventualities – not that I plan on having a level that could have up to 2,500 rooms!

I then assigned the middle cell in the array as the start room. The plan was to randomly decide which doors would be available (N,S,E,W) and then iterate through each possible direction adjusting the array until a preset room limit was reached – for this purpose it was 20.

Unfortunately, this method soon got so overwhelmingly complicated that I abandoned the code. It was fine for setting up the rooms, but when I started needing multiple arrays for different elements of each room it became too much. There had a be a simpler way.

So, I hit on the idea of using GameMaker objects instead. I could create a ‘room_object’ that would hold all the information needed, and I could use the objects themselves to determine the layout.

As before I started in the middle of the screen (no array needed) and placed down a 16×16 pixel object and set it’s room_type variable to ‘start’. In the Draw function, I would use a solid white rectangle to illustrate the start room.

Next, in the Create function, I would set everything the room needed. First, I randomised the door selection. These could then be drawn at the edges of the object’s sprite. For each door I would check to see if a room already existed (using a simple collision test) and would tell the other room that a new door was needed, this connected the 2 rooms; if no room existed then a new room object would be created, and this new object would go about creating it’s doors, etc.

Once the doors were set up the code would then sort out the special aspects. Does the room have a key in it, does it have a chest in it, or anything else that might be needed (at the moment just keys and chests). These would be drawn as small coloured dots just to help me visualise the map.

Finally, for rooms that only have 1 door into them I run another random test to see if the door could be locked or hidden (for secret rooms). If the door is locked a final test is made to ensure that the map has already seen a possible key – this is to ensure that the player will always be able to find a key to unlock the door. I’m proposing this step will get more complex by keeping track on how many keys the player has; this will prevent the player from having hundreds of keys and little use for them.

With the maps basic layout complete the main function does a few final adjustments. Firstly, it scans the map for a valid locked room and assigns it as a ‘boss/exit’ room (drawn as solid blue on the map). If it cannot find a suitable locked room it finds the room furthest away from the start position and uses that instead.

Any secret rooms are then resolved in the same sort of way, although they are always behind a hidden door.

As you can see above, the code is working really well. Each level is extremely varied and is working exactly as I wanted it to. There will be a lot more features added to the rooms over time, but this is just a very very early prototype just to prove the concept.

So, with the map created using objects the next step was to try and convert that back into usable data. As these are objects that aren’t actually connected to each other (like an array) I would need to form the grid myself.

For this, I iterated through every room object and worked out the top-left and bottom-right coordinates. This would give me the width and height of the final grid. In GameMaker I can then use a DS Grid structure to form the required date. For each cell in the grid I assigned a struct object that would hold all the information. For example:

Grid[1,1]={
   room_type: -1,
   room_number: 1,
   door_count: 2,
   door_left: 2,
   door_right: 0,
   door_up: 1,
   door_down: 0
}

As you can see this is a lot more information than a simple 2-dimensional array would handle. With the Grid and Struct in place, I can instantly find out that the room in cell 1,1 has a locked door (2) on the left, and a standard door going up.

That’s about it for now. I hope that this early insight is useful and informative and that you join me on this adventure to making a new game. I can’t wait to see how this project develops.