Advertisement

Map file storage... speed vs. size?

Started by March 23, 2001 09:31 PM
14 comments, last by MatrixCubed 23 years, 10 months ago
Hey folks, I'm working on my worldmap data file, and I came across a conundrum... here's my tile class:
    
class CTile
{
// omitted methods...

public:
	unsigned char	m_cHeight;
	unsigned short	m_iTerrain;
	short		m_iZLevel;
}
    
I can do a couple of things... if I compile the map file by writing each individual data member, I can save 1 byte of space per tile. That means a savings of 16,777,216 bytes (16mb) with a 4096x4096 map size (the intended size) compared to if I just write the object directly without accessing data members. The main thing about this is if I write the entire object to disk, the code is easier to maintain... if I add or subtract data members I simply have to rewrite the compiled datafile without worrying about editing the code too. This way is likely a little faster also. But writing individual data members means that there's a little more work, the payoff is file size. Any ideas on how to decide between these? MatrixCubed
http://MatrixCubed.org Edited by - MatrixCubed on March 24, 2001 10:33:20 AM
What exactly are you trying to do, and what do you mean by writing and removing data members? Also, a 4096x4096 map is Incredibly Huge! Most games I believe have maps of the size of 256x256.

Possibility
Advertisement
I''m talking about the game data map, not a texture (256x256 textures are fine, but a 256x256 tile map would not suffice).

When you write an object to file using fstream methods, it writes the entire object as well as an extra byte (not sure why here). If you write individual data members to file, you avoid that one byte.

I''m pondering, for code/object compatibility reasons, to simply write the entire object, not have to worry about recompiling the code (and possibly causing more debugging than necessary) each time the objects need to be updated... and bite the bullet regarding the extra byte-per-object.




MatrixCubed
http://MatrixCubed.org
Have you tested to see if writing an object to a file always writes an extra byte no matter what class it is? It could be possible that your compiler is padding your class with garbage data out to a size that ''fits'' better. For example, most compilers will pad data to fit in 4 byte (32-bit) chunks. I suppose it is also possible that some compilers pad out to 2-byte boundaries in some cases (since it looks like your object should be about 5 bytes as it is).

You might be able to find a data size that the compiler doesn''t enlarge, but still conveys the info you need. There also might be a directive you can use to tell the compiler to pack your data into the minimum amount of space. However, this can cause memory accesses to be slower.

Anyway, those are just my guesses at what might be going on. I haven''t experimented around with that myself and I am not able to at the moment, so I can''t give any more help than that Good luck!
Okay, after some testing, I found that the compiler is indeed padding the class with an extra byte as soon as I put an odd number of bytes'' worth of data into the class. Oh well. I''m going to add an extra data member, 1 char in size, and save it as ''flags''. It will come in handy later on.

Thanks for your ideas!


MatrixCubed
http://MatrixCubed.org
quote:
Original post by MatrixCubed

Okay, after some testing, I found that the compiler is indeed padding the class with an extra byte as soon as I put an odd number of bytes'' worth of data into the class. Oh well. I''m going to add an extra data member, 1 char in size, and save it as ''flags''. It will come in handy later on.



I should have paid attention to this post earlier -- I know in Microsoft Visual C++ there''s a compiler switch you can use to set structure alignment. I think the default is 8 bytes, but often times when writing structures to disk you want to turn that to 1 byte to avoid the extra padding bytes. You can tell the compiler to eliminate the padding bytes and it should fix everything automatically.

"All you need to do to learn circular logic is learn circular logic"
"All you need to do to learn circular logic is learn circular logic"
Advertisement
It''s a pragma switch: #pragma pack(1) (I think) to set the padding to 1 byte (which is effectively eliminating the padding).

cu,
Prefect

Resist Windows XP''s Invasive Production Activation Technology!
One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
Tried that, but for some reason my other project that uses the same code, compiles, links, then illegal ops all to hell because of the misaligned data structures. And anyways I don''t want to eliminate possible optimizations because of one particular data set. I''ll resort to designing the data set better.

MatrixCubed
http://MatrixCubed.org
After doing some quick math, I noticed that a 4096 * 4096 map gives you:

16,777,216 individual tiles.

Your data set is 5 bytes which amounts to:

16,777,216 * 5 = 83886080 bytes or 83mb per map.

How would anything smaller not suffice? You will also have to keep track of all the characters on said map, which considering the size of your map, would be a lot. What are the minimum requirements for your game?

Your data set looks fine, but you might want to rethink your game design. Or have some sort of data compression scheme to cut down on the file size.
I''ve actually lowered the map tile size to 4 bytes, so the entire game map is 64mb even. (2 bytes for z level, 2 bytes for type). I can ditch the height and just spoof it with a lookup table.

The map isn''t all going to be held in memory at once, only a very small portion (configurable on the client, maybe between 32x32 up to 128x128 tiles at once... whatever needs to be seen on the screen). The server program on the other hand will handle quadtree-ish regions of the map, which are configurable in a text file, so that multiple systems may be used to host the game.

Basically, the client is only responsible for that tiny 32x32 area. The server is responsible for the whole map, but I''m working on an allocation/deallocation scheme depending on where the action is so that the server isn''t overloaded.

This is an online persistent-state-world game, by the way.


MatrixCubed
http://MatrixCubed.org

This topic is closed to new replies.

Advertisement