Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've been working on different tile-based projects, but never really bothered with being efficient memory-wise. Each tile was represented by a tile class which would hold the following:

  • X and Y ID of the tile
  • Solid boolean
  • Events for entities when leaving or entering a tile
  • Graphic data
  • Size

But especially now, when using a component based system where everything is an entity (which has some base functionality which already takes some memory), I've started to run into memory issues.

I started looking at existing tile engines and noticed that a lot of them don't even have a tile class, but just use an array of integers. I figured you could just use the index of the array for position and the actual integer value for the graphics.

But how would store the other data for this tile? With the events for example, would save them externally from the array or something? This would mean that you would need to have a list for every property you want to save, which sounds like a pain in the ass.

It might be good to know how they would have handled this on a more limited platform, let's say the SNES?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

A tilemap can be represented efficiently as an array of integers, as you noted, where each integer refers to some tile definition object. This is quite similar to palette-based image representation, and both techniques are applicable to memory-constrained systems (such as the SNES*).

In such a system, a tile class might represent a definition of a tile's properties and not, as appears to be the case in your original a system, an actual tile instance. This lets you entirely remove some data from the tile definition class (X and Y position, for example). It also means you can eliminate data redundancies. If your "regular grass" tile is tile ID 0, and your "solid wall" tile is tile ID 1, you can create a tilemap array of 0's and 1's and still only need two instances of the actual tile definition type.

Because a consequence of this system is that the tile object doesn't contain instance-specific data, if you need instance-specific data (such as for event triggers), you can use another data structure that is more suitable for such sparely-populated data. For example, a dictionary-like structure where the key is some hash of the instances X and Y position and the value is an object that represents tile instance data, such as the trigger list or the tile's "inventory" (the items somebody has dropped there, or whatever).

(*) It is, however, worth noting that older consoles like the SNES and GBA and such had specialized tileset handling systems "built-in." They operated in a similar fashion though.

share|improve this answer
1  
For even more savings you can use RLE (run length encoding) to compress all those big areas of grass and whatnot; sure it takes more code to work with but the space savings is decent depending on your maps. Working with tiles on SNES was a beautiful thing, such an elegant little system they engineered. –  Patrick Hughes May 17 '12 at 17:50
    
This is exactly what I was looking for, thanks! Still seems somewhat clumsy to have seperate dictionaries for all the instance specific data. Thanks for mentioning RLE Patrick, seems very handy for large patches of tiles indeed. I will look up how the SNES handled tiles, seems interesting. –  omgnoseat May 19 '12 at 22:12

As far as graphical things go, all you need is an integer and then later have this multiplied by the tile width and height values to get the bit of image from the sprite sheet. You can have -1 represent no tile.

For location, it's place in the array times tile height and width will give you x and y values, then add tile height and width to get the other side of the tile. I use 2D array for this because it makes it simpler to think about.

For being solid or not, I use three layers; background, mid-ground, and foreground. Anything in the mid-ground is collidable. I draw it background, then mid-ground, then entities, then foreground.

Tile width and height values are stored outside of the tile information as well.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.