Sign in to follow this  

map file format

This topic is 4566 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I'm making a map class to use with my tilebased games. And I wonder how I should write the map data into a file. Right now I'm just writing the type of tile as a int and then a line break. This makes it really easy to write and read levels, but it feels so clumsy in a way. How should I save the data in abetter way? I've thought about a separator sign, just read untill I read the separator sign, and of XML. Is XML really as great and useful as they say? Thanks //walle

Share this post


Link to post
Share on other sites
Depending on how complex your maps are, I would say you should just write it out in binary so you don't have a lot of bloat (unless of course you want to edit your map files by hand). Then you could just write the width and height of your map, and then use that information to read in the correct dimensions.

XML is another possible solution, but would be more programmatically difficult. Since I don't know your skill level, nor the amount/types of data your map format will entail, I would just suggest my aforementioned solution.

Share this post


Link to post
Share on other sites
Well using xml makes spotting errors a lot easier.

Unless you are going to export a lot of nonsense data.
By nonesense I mean data that have no place in xml, 3d geometry, images
and so on. *This is my personal meening, If you are one of those who
use xml for everything, then please continue to do so..*


Then I would sugguest that you take a quick look on xml.
As binary formats have a way of getting out of hand when you
start to add lot of new stuff, and harder to debug.

I can recomand tinyxml
as its tiny, easy to use and great for beginning with xml.

Share this post


Link to post
Share on other sites
expat is an extremely simple to use XML parser api. You simply stream it XML as you get it using the XML_Parse function. It buffers the stream so you could feed it one character at a time if you wanted to. You register a couple of callbacks with the API that it will call when it enters a new element, closes an element, or finds character data. That's pretty much all there is to it.

Share this post


Link to post
Share on other sites
*cough cough*...
Shutup all you xml freaks he's storing a large data array for goodness sakes, not a hierarchical structure!

Sorry, you'll have to excuse that lot. You mention certain buzzwords like xml & somehow the actual problem seems to completely bypass their brains & they go into automatic lets-post-as-many-links-to-our-favourite-library-as-possible mode

Erm no. xml is certainly no good for storing tilemaps
It's use is for object based data
It might be usefull for storing entities within your map like characters or points of interaction
But the map itself is probally just gonna be a giant array of values so you'd be better off storing it the way you are, or using a binary format
The article Simple File I/O Using C++ covers binary input & output briefly, but I'm afraid you'll have to look yourself to find more indepth articles as I am tight for time atm
It should be noted that the method used there (dumping whole structs & classes @ a time) is safe for "simple" structures
That means no values stored remotely by pointers (like std::string etc)
Also the data would need to be solid state since any constructors would be bypassed upon reloading
However if you just want to chuck a simple int array into it via binary then it would work something like this:

unsigned int map_width=512;
unsigned int map_height=512;
int *map=new int[map_width*map_height]; //runtime allocated size, don't forget to free

//save
ofstream file("filename",ios::binary);
file.write((char*)&width,sizeof(unsigned int));
file.write((char*)&height,sizeof(unsigned int));
file.write((char*)&map,sizeof(int)*width*height);
file.close();

//load
//free any old map that has been allocated with the 'delete' keyword before entering here
ifstream file("filename",ios::binary);
file.read((char*)&width,sizeof(unsigned int));
file.read((char*)&height,sizeof(unsigned int));
map=new int[width*height];
file.read((char*)&map,sizeof(int)*width*height);
file.close();

That is a very simple example
(I delibrately avoided classes to keep it simple)
But that's the basics of how binary works
The data is dumped in raw form & as long as you reload exactly the same sizes of memory (or marked earlier in the file any sizes which change) then it should reread exactly as it was saved

Damnit gtg, sorry I couldn't of been more help

Share this post


Link to post
Share on other sites
No, he asked the best way of doing it & weather xml was a good answer
The best way of storing map arrays is in a binary form & xml is certainly not in any means a sensible answer to this

However, he may want to somehow append an xml block to the end of the file or prehaps use a second file for storing any object based data in the map (like entities), but that will probally come later

edit: hmm actually appending an xml block to the end would be kinda silly as you couldn't edit it by hand (isn't that the whole point of xml?)

Share this post


Link to post
Share on other sites
Quote:
Original post by walle
Is XML really as great and useful as they say?



No, but it is probably still well suited for your task, especially since that will likely not be your final map format, and XML allows for changing/expanding the format easily. If anything, XML should be the quickest to get working, so you can actually make stuff and worry about dumb stuff like map formats later.

And for those nay-sayers... What happens when there's actually objects in the tilemap hrrrm? No hierarchical structure now, but what happens when "map data" becomes "save game"?

Share this post


Link to post
Share on other sites
I thought that it would be easier to se if something goes wrong with XML...if I laid it out like this...


<MAP>
<name>Level 1</name>
<width>45</width>
<height>30</width>
etc.
<LAYER>
<layernr>1</layernr>
etc.
<TILE>
<xpos>0</xpos>
<ypos>0</ypos>
etc.
</TILE>
</LAYER>
</MAP>



But on the other hand, if I go with binary. I'll probably do that when I have the level editor ready, but untill that it could be good to see the level...

I know how to save a struct or class in binary form, but I have a
std::vector< std::vector<tile> > as my map array.
Should I go trough the whole array and save every tile by them selves?
Like:

for(int x=0; x<mapwidth; x++)
{
for(int y=0; y<mapheight; y++)
{
//save tile at map[x][y];
}
}



//walle

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Your intention to make it easier for human eyes to read the data is understood, We have no idea what kind of game this is and how big the world/level is going to be. Having the data in an xml file you would be loosing the graphical nature of the data.

What would be easier to read during early stages in development? Lets say that you are moving from 2,1 to 0,0. If it was in XML you would have to go to a scrach pad and determine which tiles were in the path. If I was working on the project I would perfer version A over any XML solution. Once a level editor is made and retail is around the corner I would switch from ascii to a binary file.

A.)
[map]
dimensions 2,4
# Each cell contains the following information
# (tile type) (height) ()
[001 030 304][000 003 002]
[001 030 304][001 010 002]
[001 030 304][001 008 002]
[001 030 304][000 003 002]

[entities]
#(type) (max health) (x pos) (y pos) (direction)
deer 180 1 2 270
tank 3000 2 3 90 6


Where a certain number contains data for the type of terrian, height, could also have the x and y positions in there to determine which tile is located where for reference purposes.

For the entities, keep in mind that you would read in the type and determine what is expected afterwards, such as a tank could have the amount of ammo it currently has were a deer would not have that data.

or B.)

Level 1
45
30
etc.

1
etc.

0
0
etc.


1
0
etc.


0
1
etc.


1
1
etc.


0
2
etc.


1
2
etc.





Share this post


Link to post
Share on other sites
Quote:
Original post by walle
Is XML really as great and useful as they say?


I'm no expert on XML, but generally "they" overhype XML. It has it's uses but it's not the solution for everything.

Using XML for a tile based map format may or may not be a good fit for you (I'm not sure what your requirements are for the map format).

However, as CoMaNdore pointed out, tinyxml is pretty easy to work with if you decide to take the XML route.

Also, two downsides of storing the map in binary format:
It's hard to look at the file and figure out where something is wrong
You will have problems if you port the game to another platform with a different endianess - however, this might not be an issue if you don't care about porting

Share this post


Link to post
Share on other sites
If you have a relatively small number of tile types (say less than 20), you might want to consider using a text file as the map file, with one character per tile, thus:



2222222 22222 22 22222 22222222222222222222222222222222222222222222222222222222222
2222222 2 2 22 2 2 22222222222222222222222222222222222222222222222222222222222
2222222 2 S 2 22 2 g 2 22222222222222222222222222222222222222222222222222222222222
2 2 k 2 2 k 2 2222222222222222222222222222
22 2222222D22222222D2222222222222222222222222222222 22222222222222222222222222
22 2 2 22222 2222222222222222222222222
22 2 k f ee3 22222222222222222222222222
22 2 p k f ee3 22222222222222222222222222
22 2 2 22222 22222222222222222222222222
22 2222222D22222222D2222222222222222222222222222222 22222222222222222222222222
22 2 k 2 2 k 2 22222222222222222222222222222
2222222 2 S 2 22 2 g 2 22222222222222222222222222222222222222222222222222222222222
2222222 2 2 22 2 2 22222222222222222222222222222222222222222222222222222222222
2222222 22222 22 22222 22222222222222222222222222222222222222222222222222222222222
2222222 22 22222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222222222222222222222222



The above is an actual level from one of my games.

As you can see, it's easy to visualise in your (fixed spacing font) text editor.

It's also remarkably easy to read in. In this particular case, I think I just read until I find a blank line, then stop, that gives the height of the map. The width of the map is the length of the longest (or first) line.

Mark

Share this post


Link to post
Share on other sites
No...I won't use xml for my mapfile format.

I tried to use binary format, where I ran trough all tiles (475 for the test map) and saved the whole tile structure...this resulted in a file at ~12 kb where my text based mapfiles for the same level was 1-2 kb. And in the resulting game I'll use larger maps (this was a non scrolling test map). So I'll go back and save the maps in text mode, I want the game to run on many platforms I use SDL...

My thoughts is just to save all data on a tile/enity straight down in a file...
and read it in like this (tile example):

for(int x=0, x<mapwidth; x++)
{
for(int y=0; y<mapheight; y++)
{
fin>>map[x][y].x;
fin>>map[x][y].y;
fin>>map[x][y].texture;
fin>>map[x][y].collidable;
}
}



Or something like this...

Any suggestions on this approach?

Ps. Thought this tread was dead... =) Ds.

Share this post


Link to post
Share on other sites

This topic is 4566 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this