Level structure

Levels are one of the most common things in roguelikes. Yet, there are different ways of representing them, each with their own advantages and disadvantages. This post shows how they are implemented in pyherc.

Floors and walls are implemented as lists of list (essentially modelling a two dimensional array). Each cell contains an ID of tile that should be displayed there. If a wall tile is None, then there is no wall there and creatures can move in that tile (unless something else prevents it, of course). It would be possible to combine these two things together, since the floor is not visible from below walls. However, that would require to somehow code where characters may move and where the walls would block them.

Ornamentation are all those little details and trinkets that don’t have any direct effect on the game play. Currently torches on the wall are the only example of this type of items, but in the future more will be added (dirt and stones on floors, cracks on walls, moss growing here and there and so on). They are stored in a similar data structure as walls and floors and handled in the same way. They are on a separate data structure, because most of them contain see through portions that reveal the tile (be it floor or wall) beneath of them.

Herculeum_024_crop

Items and creatures are both stored in their respective lists and drawn on top of other tiles. The difference here is that while walls have a two dimensional data structure that has a reserved space for each location, items and creatures are simple lists. Amount of objects in each list is relatively small and each element can hold its own information about the location. Checking whether some specific location contains an item or a creature is a bit slower, but so is memory consumption too (not that either one of those really matter in a modern computer).

Last data structure contains portals (usually stairs) and it is handled in the similar manner than items and creatures. The biggest difference is that content of this list is never drawn on screen. The stairs shown on the image above are actually stored on the floor data structure. I made this choice, because it makes it much easier to place that small border around the stairs that is shown in the picture. The routine that does that is the same routine that handles the border that runs alongside of the walls.

Portals are used when player tries to descent stairs. The engine checks if there are an object in portals list that has the same location as the player. If such an portal is found, then player is moved to a new level and new location within that level (required data is stored in the Portal object).

Mostly Level objects in pyherc are just lists and more lists. Levels are then linked together via Portals and form a treelike graph. There is also a portal that has a special flag turned on. If player ascends these stairs, he leaves the dungeon and the game ends.

Advertisements

2 thoughts on “Level structure

  1. Have you though of using a dictionary to represent your levels instead of an array?
    In many games, lots of a level can be blank space, neither walls or floor, in that case it’s just junk data taking up space in your array but not contributing anything to the game. If you use a dictionary, you can store the tiles of your map by creating a key, for example: “34$45” (the dollar sign serves as a separator). Then when ever you are doing a process that accesses your map data you can simply check if the key for that tile is in the dictionary or not.

    My tiles contain lots more data, such as the kind of tile (is it walkable or not) if the tile is occupied, and other data. Because only part of my map is actually walls and floors it saves space (and makes accessing it quicker), leaving me the option of making the tiles more useful (for example they can contain a list of any objects laying there, or traps, or monsters etc…, you could use it to store info about A* “swamps” or dead ends, or shadow maps or anything else which could make the game run smoother or make it easier to program).

    • I had not thought of that. With the size of the levels I have, I’m not that concerned about the memory consumption. But with dictionary, I could even negative index for tiles, which would make it easier to make levels procedurally. It also would be possible to grow the level while playing it.

      I don’t have a separate tile class for storing all the information you mentioned, but it’s starting to look like it would be a good idea. Thanks for the ideas, I’ll have to think about them and see what to do with my level structure.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s