GP32 Map File Storage


JaqMs

Member
Joined
May 9, 2005
Messages
476
Hello. In my game, each level is comprised of 8x8 tiles, making the total tiles 1200 (40x30). For storing the maps as files, would it be best to:

1. Create a 40x30 bitmap, and read the bitmaps into a buffer
2. Convert the bitmap into a header file using GP32Converter
3. Use a file containing text, where each character represents a tile

Which method would be the most adequate to use? Is there any other method that is preferable?
 
I heavily suggest tiles. Even 3D games modernly use similar tile techniques.

as a quick example of what the file would look like

[HEADER], (Optionally[X SIZE][Y SIZE]) [DATA, STORED STRAIGHT UP]

Storing with tiles has its own very huge advantages, like being able to tell objects collision apart. As soon as i get my Dev-CPP to compile GP2X File correctly, i'm going to attempt a big port on WarGus, a stratagy game engine that is able to run Warcraft 2 from windows linux and more. Warcraft 2 uses tiles, and its future sequels did too. Warcraft 3 was a very nice tilebased games. Lets not forget those old command and conquer games, eh? also as an advantage, correctly storing this data, and not using a tile for every part of a map(400 tiles), can result in a very much more compacted game system with faster loading times and less use of the ram.

If a bitmap is used, then better graphics can be achieved. However, collisions and/or types must be stored in other methods if needed, and the size and ram requirements of the game will jet up... skyrocket... but its not my choice.

Other than these two, there may be an even better method to suite your needs. it all depends.

EDIT: Among meaning text, i meant binary for storing data, like if you only have 255 or less unique tiles, consider using bytes to store data, or if you only have less than 16, using HEX values to store it, it all can help your game compaction.
 
I don't think you understood my post fully. My game engine is already tile-based, but I want to know how to store the 40x30 tile levels. Bitmaps can be used, in which each pixel color can represent some kind of tile. They also take up less space than having a file with 1200 entries, but I'm wondering if either method should be used. I'm planning on a large amount of levels in my game, with all of them taking up the entire screen.
 
JaqMs posted on Feb 21 2006 at 04:56 AM said:
I don't think you understood my post fully. My game engine is already tile-based, but I want to know how to store the 40x30 tile levels. Bitmaps can be used, in which each pixel color can represent some kind of tile. They also take up less space than having a file with 1200 entries, but I'm wondering if either method should be used. I'm planning on a large amount of levels in my game, with all of them taking up the entire screen.

I would suggest a chat struct, offers 256 different tiles.
If you plan a user level editor, use text files. Like:

wweeqewqerwqrertztt
qwrtewreerwerwerezt
weqere"§$§%§"2eww
....
every char represent one tile.

Remeber a 600x600 tiled screen (no matter how big a tile is), only use 600*600=360.000 Bytes = 360k/1024 = 351kByte.
Thats not mutch for a 600*40 x 600*30 = 24000x18000 Pixel screen !!!
( you only see 320x240 @ a time :) )
 
Last edited by a moderator:
JaqMs posted on Feb 19 2006 at 07:56 PM said:
Hello.  In my game, each level is comprised of 8x8 tiles, making the total tiles 1200 (40x30).

It took me a few moments to understand this bit, but my guess is you're saying your tiles are 8x8 pixels in size, and you'd need 40x30 of them to fill the GP2x's entire screen (320x240px), correct?

Don't rule out the fact yet that in the future, you may want to make levels larger than the screen. Whatever you do, your best bet for extensibility is to save the level size with each map, so you can make small levels (10x10) as well as large ones (500x300).

Whatever the case, we're not talking giant loads of data here (just 1.2kB), so any method will be just as good as any other. With a few caveats about applicability of course...

For storing the maps as files, would it be best to:

1. Create a 40x30 bitmap, and read the bitmaps into a buffer

And have every pixel represent a tile to select? I wouldn't do that, on grounds of one reason alone: the data would be very hard to edit. You could create the bitmap with an image editing program, then color the top-left tile #000000 (for grass), the tile to the right of that #000001 (for a tree), etc.

Seems like it would get tedious? It does to me. To make it workable need to write a special map editor to get along with these files anyway... and then the file format is just silly.

Pros:
  • You get map width and height dimensions for free (since it's embedded in the file format);

  • If you use a 256-color bitmap, you can use RLE to compress the files.


Cons:
  • Editing would be tedious;

  • You get a lot of BMP header overhead, all of which is unnecessary;

  • It's really abusing a file format for something it wasn't intended for. Bitmaps are for graphics, not map data.


2. Convert the bitmap into a header file using GP32Converter

Quite possible. There's a trade-off here: ease of deployment vs. modifiability. If you include all data inside your executable (graphics, sound, map data), it's just one file to send around (quite like a ROM, actually), but you'll lose the ability to change or extend the game data without recompiling the application.

I wouldn't do this but you can make the choice for yourself.

Pros:
  • No external datafiles needed


Cons:
  • You'll need to recompile the application each time you add a level;

  • Your executable becomes larger (= bigger download, longer time to load). More of a theoretical concern, with such small data sizes you won't really notice the difference.

  • No end-user moddability. It may depend on whether you want to allow this, but no other people than you will be able to add levels to the game.


3. Use a file containing text, where each character represents a tile

I'd say that this would be the most common way to solve this problem, and it's the method I would choose. I know it's a pretty long post to make that simple point, but I wanted to show you the reasoning behind my choice.

Anyway, to round it out:

Pros:
  • It's simple. It's convenient. Everyone gets it.

  • You can do map editing with something as simple as a text editor, or roll your own level editor, whichever you prefer.

  • You can always add levels later on without touching the application.


Cons:
  • Extra files, but that's basically it. Not a big concern on the 2x.

  • You'd need to use readable characters like 'a' and '#', where you'd really just
    want an integer index into a tile table. Alas, ASCII 0, ASCII 1 and so forth are not easily inserted with a text editor.


Is there any other method that is preferable?

Well, you could go for binary files if you really wanted to. This has a few advantages and disadvantages of itself.

Pros:
  • Easier to read in than text files: block-read a file into a buffer and you're ready to go -- no more parsing. With text files you'd need to strip things such as newlines, and convert something like 'a' to tile index 0.
  • Easy to add something like compression to if your map files start to get really large, but I doubt that they would, as their size would most likely be dwarfed by the tile graphics themselves
  • They'd be (marginally) smaller than the same textfiles: no newlines!
Cons:
  • Harder to edit. You'd need a hex editor or a level editor.
 
Last edited by a moderator:
Can you give me an example of using a binary file to represent a map so I can get a basic understanding of them?

By the way, I'm using the official GP32 SDK.
 
Well, a binary file is much the same as a text file, except it will not normally be readable by a text editor because it contains all kinds of non-printing characters. The data inside is not for meant for human eyes.

You can read and write it just like any file, you just don't have to restrict yourself to printable characters when you put stuff in it.

I'd design a binary format like this:
Code:
+-------+--------+-------------------------------
| width | height |   width x height bytes of map data...
+-------+--------+-------------------------------

Which you could read or write with the following routines for example (not tested):

Code:
typedef char Tile;
typedef short int Dim;

Tile* loadMap(char* fileName, Dim& width, Dim& height) {
  FILE* f = fopen(fileName, "r");
  fread(&width, sizeof(width), 1, f);
  fread(&height, sizeof(height), 1, f);

  int dataSize = sizeof(Tile) * width * height;
  Tile* data = malloc(dataSize);
  fread(data, 1, dataSize, f);
  fclose(f);

  return data;
}

void saveMap(char* fileName, Dim width, Dim height, Tile* map) {
  FILE* f = fopen(fileName, "w");
  fwrite(&width, sizeof(width), 1, f);
  fwrite(&height, sizeof(height), 1, f);
  fwrite(data, 1, sizeof(Tile) * width * height, f);
  fclose(f);
}

// Example:
// Clear the map data in level1.map

Dim w, h;
Tile* map = loadMap("level1.map", w, h);

for (int j = 0; j < h; j++)
  for (int i = 0; i < w; i++) 
    map[j * w + i] = 0;

saveMap("level1.map", w, h, map);
 
heh, you don't need to confuse him on concepts between 'binary' and 'text' format files. They're the same thing. Printable characters aren't magic. A 'letter' as you will, is a character which is 8 bits. 2^8=256. So here you can have 256 values but "0"-"9", "a"-"z", and all other symbols don't occupy all of that space (depending on the dialect.) So of COURSE you will have values which have no representation. That representation is font dependant. That's why you have things like wingdings that has some little picture for each character.. the values are just references to symbols in a font.. and yes, the letters and numbers have a standardized place in just about all fonts and you need to assume those values to be true. Now, there is a difference between writing into a file "1" and 1. This is where the difference lies. "1" is 0x31 (i think), and 1 is .. 1. In your program, if you make it write 1 to a file.. then dont expect to see a "1" in a text editor. If you write "1" to your file, then you will see a "1", because they are different values.

The problem with your question is that custom file formats are.. CUSTOM FILE FORMATS.. they are custom because they adhere to the particular needs of a particular program. There is no way we can really tell you how to structure your data in a file. Your format could yield new dependencies that you will stumble upon later and you'll have to restructure everything.. this is why they are custom. One size does not fit all. You may want to pack certain values into a particular byte... you may want to store them as text characters "1", "0", "1" for easy end-user customization .. who knows! ..

Play with it.
 
Back
Top