At the core, all you need is a number of elements each identified by a unique number and some two dimensional array structure where you write numbers. Each cell contains a number that points to one of the elements.

As you see I gave a very generic definition which does not even contains the words "tile", "graphic" or "map", the reason is that this concept applies to quite many things, not only game graphics.

A good example would be a text video mode as you can see on a booting PC, or everybody's all time favorite: Windows Blue Screen of Death.

At first glance this does not seem very obvious, but if you just think about it then it all makes sense:

A text screen is like an array typically containing 25 or 50 rows of 80 cells

Each cell contains a value which will be displayed as a character

In such video mode, if you write the value 65 in the first byte of the video memory, you will generally see an A appear on the screen.You can use any of the supported codes (in my example I used the ASCII1 encoding) in any of the rows and columns to type any message you want, or even make ASCII Art if you feel like it.

I can feel your suspicion. Right now you are wondering how one jumps from the text mode error messages of MS-DOS to 2d pixel graphics.

Well, once upon a time there was no such things as bitmap graphics - heck, there was not even personal computers -, all you had was boring terminals able to display text. Still some creative people managed to make graphical games using this primitive technology, using characters and symbols as graphics.

As you can see, this "screenshot" is actually just made of text. Despite that I hope you will admit that it's not difficult to imagine that this represents some rooms linked by tunnels.

Some more recent games have been building on this idea, you can try Dwarf Fortress2 for a more colorful example.

Moving from this textual representation to something more graphical is really not that difficult: All you need is to manage your own "screen" and draw you own "characters" on it. Let's see how to do that.

Because the concept is so generic, I will not use any particular language or framework. Instead I will use some pseudo code with comments to explain things. It will not be optimized either just to keep it simple.

Here is what would look the pseudo code to generate and draw the "space station"3 example I was showing in the previous article.

// This returns an array of 3 tiles each containing a picturetiles = ["tile_starfield", "tile_metal_plate", "tile_metal_plate_painted"] as Pictures

// We now iterate through all the cells, column by column, row by rowFor row From 1 To tileMapHeight For column From 1 To tileMapWidth// Read the tilemap to find the number of the tile at this location tileIndex = tileMap[column][row]// From the index get the picture from the texture array tileToDraw = tiles[tileIndex]// Draw it at some magical coordinates that matches the tilemap ones :) DrawPicture(tileToDraw,column,row) Next columnNext row

This example is easy to extend, all you need is to adapt the pseudo-code to fit your needs for a larger tilemap or for more tile variety.

Obviously in the real code the tilemap data would be created with a nice editing tool and then loaded from a file, but that's conceptually identical.

This pseudo-code sample was so simple and minimalistic that obviously nothing could be wrong. After all each cell is being read and displayed only once; can this even be improved?

There are a number of problems in what this code is doing:

It does not scale well when the size of the tilemap is increased

The number of DrawPicture calls can be very large when using small tiles on a large screen

Zooming or rotating the tilemap would be difficult.

The first problem will happen when you start really developing your game using some really large tilemap.Seamless large worlds are cool, so obviously instead of a 8 by 8 tilemap you feel like your game deserves at least 1024 by 1024 tiles to look cool, perhaps even more.

With 8 by 8 tiles, we perform 64 iterations and calls to DrawPicture.

With 1024 by 1024 tiles, we perform 1 048 576 iterations and calls to DrawPicture; let say that it is a significant increase in work for the CPU. And the worse is that most of this work is not even displayed on the screen!

Indeed, when using 16 by 16 pixels tiles, our 8 by 8 tilemap is drawn as a 128 by 128 pixels square on the screen.

On the other hand, a 1024 by 1024 tilemap actually represents a 16384 by 16384 pixels square; way bigger than your screen4!

Even if you have a super awesome screen in the 2600 by 1500 resolution range, you can still only see about 1.43% of your tilemap on the screen: 98% of it is invisible, what a waste of resources!

Obviously, rendering tiles that are not going to be visible is not very efficient. The solution for that is called "clipping".

Now, there are two ways (at least) to implement clipping: The good way, and the bad way.

The bad way would be to add something like that in the code:

// We now iterate through all the cells, column by column, row by rowFor row From 1 To tileMapHeight For column From 1 To tileMapWidth// Make sure the coordinates are in the visible area If (column>leftClip) And (column<rightClip) And (row>topClip) And (row<bottomClip)// Draw the tile(previous code) EndIf Next columnNext row

For sure, you are not going to call DrawPicture one million time anymore, but now you are going to perform one million pointless comparisons.