Monday, April 22, 2013

Planning Part 3 - Designing The Dungeon

Here we go, designing the dungeon and all its wonders. Let's start off with the dungeon dimensions as a whole:

The dungeon is a 4 x 16 room placement (Four rooms across, 16 rooms down) for a total of 64 rooms, each room being 64 blocks by 12 blocks, and each block 16 x 16 pixels. This means the dungeon is a total of 256 blocks across and 192 blocks down. That equates to a dungeon that is 4096 x 3024 pixels. And if we where to equate that to the 64 x 64 blockset, the dungeon dimensions are a whopping 16384 x 12288 pixels! My computer is sweating just thinking about it. So how would we go about constructing the dungeon? Well, we have an idea. Instead of creating 64 rooms in GM and laying out the tiles, we're going to create the room from plain text. We'll have one 4096 x 768 room for the dungeon, and using a room creation object, lay out the room depending on a variable received from the game.

So, in simple terms, we create two ASCII versions of the room, one for background tiles and one for the objects, and when the game lets the room know which room it's in, the room will draw itself.

Here is an example of what I mean:
This is what the first room looks like (MSX2):

Now this is the object layout in ASCII:


1211111111111111111111111111111111111111111111111111111111111111
1200000000000000000000000000000000000000000000000000000000000000
1200000000000000000000000000000000000111111111111100000000000000
1211111111111000000000000000000011111000000000000111011110000000
1200002000003000000001111111111100000011111111100000000111100000
1200012000001111111110000000000000011110000011111111111100000000
1200012000001111000000000000000111110000000000011000000000110000
1200012000000111000011111111000000000011111111001111100000000000
1111112000000011110000000000211111111111100000000000000000000011
1000002000000010000000000000200000000000000000000000000000000000
1000002000000010000000000001200000000000000111111111111000000000
1000002000000011111111111111111111111111111111111111111111211111

Here, 1 equals a wall, 2 equals a ladder, and 3 equals an interacting block. 0 equals nothing.

Now, using a for loop, we'll have the game put an object depending on the number in the corresponding place in the room.

We'll use this same technique for placing all the images from a tileset for the background.

Note: The wall and ladder objects will be invisible, but because of the tiles in the background, you'll still see the walls.

Now that we got that concept out of the way, let's go through each room and dissect it.

3 comments:

  1. Hi there, I read about your project on hg101. I do not have much experience with game programming, but still I`d like to give a small reply:
    Your way of creating the map by some ascii representation is a way to do it. Most games tile-based games are/were made that way afaik. But I think you should differ between what tile is shown and what functionality the tile has. If you think think about the ladder tiles in the example which connect the rooms, the tiles have the "ladder" property and the "change room" property, but this can`t be deduced by just the map data. Also I actually don`t know the game so I don`t know whether there are things like invisible or illusionary blocks or foreground tiles, but those would be difficult to program if you combine functionality and look of the map in one data set.
    So I`d recommend making a list of possible properties of a tile. Next step could be to put the list in a set of bitmasks/flags. For instance:
    c code:
    #define IS_SOLID 0x01 // means a tile which can`t be crossed
    #define IS_LADDER 0x02 // self explanatory
    #define IS_TELE 0x04 // doors, room changes, etc.
    and so on

    In a binary number system these would make the values: 0b0001, 0b0010 and 0b0100. Now if you`d want to define ladder tile which connects another room, you`d logical OR IS_LADDER and IS_TELE (0b0010 | 0b0100) which results in 0b0110 (hex: 0x06 or simply 6 in decimal). Now if your routine reads this value and you want to know what properties are true you can easily test that with logical AND: 0b0110 & 0b0010 (IS_LADDER) results in 0b0010 since it`s not 0 it`s true and we know the tile has the "ladder" property. Testing 0b0110 & 0b0100 (IS_TELE) results in 0b0100, this is not 0 so we know the tile also has the "change room" property.

    Now you could write a second map which would be called the property map. But as you have noticed 0x01, 0x02 and so on are not printable ascii chars. So instead of writing single numbers, I`d suggest you`d write 2-digit hex numbers for each tile. This might be not as comfortable, but it`s much easier to handle programmatically.

    Now that answer became longer than intended, feel free to write me if you`ve got any questions.

    ReplyDelete
  2. Sorry, obviously I read your article just sloppy, so I overread that your object map comes pretty close to what I mean by property map. Still I stand to the multiple properties per tile argument ;)

    ReplyDelete
  3. Actually, when it comes to room transport, we have the game ask the room if the character is off screen, and if so, switch the room accordingly, and fix the character's x or y position accordingly as well. This is so that we don't have to use more object than necessary.

    As far as having to use 16 base instead of 10 is actually not a bad idea, although we have not yet run out of space for tiles using a 10 base. So, we'll see what happens.

    ReplyDelete