# How should I store levels in a C++ game?

I am writing in C++. I am storing game levels as a 2-dimensional int array. This may be a hacky way of doing things, but I am not ready to change it unless I have to. I store values in the array and then draw them as I read the array. These are constant for me but I need to access them from multiple files.

How can I do this? If I put the level arrays in a header (.h) file and include it in many places I get a redefined variable compilation error. Is there a way to define a variable so it can't be used more than once?

• Sounds like a question for Stack Overflow. – MichaelHouse Dec 27 '12 at 23:07
• Shouldn't you just reference to one object that holds the level array? – Sidar Dec 27 '12 at 23:28
• The redefinition error is not really anything to do with level storage and more about a misunderstanding of how header files and the compilation process works. I wrote an article on such things many moons ago, which some find helpful. gamedev.net/page/resources/_/technical/general-programming/… – Kylotan Dec 28 '12 at 2:06

If you want a variable visible across multiple files, use extern:

// Globals.h
extern int Data[10][10];

//Globals.cpp
int Data[10][10];


However, it makes a lot more sense to load them from file. Even if you don't want to use standard library containers, loading and saving is trivial, and will help you to modify and add additional levels in the future. Also note that you will be able to supply an editor for maps.

Here's sample 2-dimensional C-style array serialization:

#include <fstream>

int Data[SizeX][SizeY];

// save
{
// You can use binary mode too!
ofstream File ("data.txt");
for (unsigned y = 0; y < SizeY; ++y)
for (unsigned x = 0; x < SizeX ++x)
// you'd need to change it to File.write(...) when using binary mode.
File << Data[x][y] << " ";
}
{
ifstream File ("data.txt");
for (unsigned y = 0; y < SizeY; ++y)
for (unsigned x = 0; x < SizeX ++x)
File >> Data[x][y];
}


You might also want to add some sort of header to your file - containing map size, game version, author of the level etc. However, loading of this data is trivial and I leave it as an exercise :)

I'd also take a look at std::vector. Contrary to your belief, it's a lot easier to use than C-style arrays. It was designed to be!

I made a tile based breakout game, and stored the levels in 1 txt file. 0 was no block, and a 1-9 was a block that would take that many hits. I suppose it could be expanded to use letters as powerups or special block. But they were formatted to be a certain width, and a certain length, with 1 line between each level.

ex

11111
00000
00010
11101

11001
02223
12321
11111

• +1 for coupling binary efficiency with ascii simplicity. What about whitespaces, though? – Bartek Banachewicz Dec 28 '12 at 13:34
• The white space is the end of the last level, start or the next. The code parses the whole thing as an array starting from zero till the end of level one. Then start from zero + llevel count + 1 for the next level. It doest need the space, just makes it easier to read. – ProtoJazz Dec 28 '12 at 20:46
• I meant more "what about accidental whitespace addition, if the user tries to edit the file by hand, for example?" – Bartek Banachewicz Dec 29 '12 at 11:59
• You could ONLY edit the file by hand. But your right, God help you if you add a blank line in somewhere, it wouldn't break anything but it would throw off all levels by 1 line – ProtoJazz Dec 29 '12 at 13:10
• Yeah, you could probably write a small function that would clean the level file, remove unexpected line breaks and So on. If you know hoes it supposed to be youcan form whatever is there into format – ProtoJazz Dec 29 '12 at 15:46

Unfortunately no, you can't define multiple variables with the same name. Suppose the compiler lets you do so, but when you're going to use it, how do you know which one are you talking about?

So in general you have three choices:

1. Make each level into a different variable. Instead of int[] level, do int[] level1, int[] level2 and so on. It's the easiest to understand, but scales the worst, as you have to hardcode everything, and will get bored writing everything as you reach more levels.

2. Make them into an array. Instead of int[] level, do int[][] levels, and store the first level in levels[0], the second one in levels[1] and so on. You can either initialize them statically in a single huge file, or dynamically with a bunch of files.

3. Make your levels load dynamically from data files. This is what professional games do, and is a very positive thing because you're separating code from data. So you keep your int[] level, but initialize it by reading a bunch of ints from a file. Google "reading ints from a file c++" for more information on how to do this.