Storing 3D Tile based maps

Hey there!
I’m starting an Adventure Game and I’m currently starting to plan the structure of my maps.

The maps will be (because it’s easier to create) tile based.

But I have no idea how to store them efficiently. I thought of a three-dimensional array, but I’m not sure if this is efficient, since empty space have to be calculated too.

https://dl.dropboxusercontent.com/u/13341521/map.jpg

has someone an Idea on how to make this less space-consuming and more efficient?

I would go for an array, It will be the fastest. However if the world is going to be dynamically generated as a player walks about that won’t work. I’ve never attempted this so I’m not sure what the best path is.

I would start off with a HashMap<Vec3, Tile> and go from there.

You could also store the map in chunks and only load necessary chunks.

Just saying …take minecrafts rout, use chunks, create a array with all chunks in it

Haha as soon as i say that :stuck_out_tongue:

Hello Raildex :slight_smile:

I would use a raw three-dimensional array if it is for tiles/blocks only.
But what kind of map do you want to create?
If i look at your image, it seems like you have an area where the player will move in (‘free space’) and the rest is solid.
In case you dont need the blocks to be destroyable, or build stuff with blocks, i would not use tiles/blocks for the map.

If you have a map, like lets say in half life 1, it is way easier to create objects (can also be boxes) that you place in the world,
and do the collision detection on what is near.
I have worked with tiles/blocks a lot lately, and i find it to be easier to place objects at a certain spot or along a grid, without using blocks.
Do you need your map to be destroyable etc, in a minecraft-ish way?

Your example(on the image) could be made with 9 boxes or 125 blocks, in this case i would not use blocks, if i get your idea right :stuck_out_tongue:

Oh, I haven’t said that I don’t want to create another Minecraft Clone.
It’ll be a RPG like Grandia for example. The maps should be designed like the ones in Golden Sun: Dark Dawn:

But aren’t three dimensional Arrays too space-consuming? E.g. the picture Above is an [4][4][3] array.but the map in it is rather small, less than the half of it is storing information of the Environment.

[quote]But aren’t three dimensional Arrays too space-consuming?
[/quote]
Even when using raw arrays, i would advise you to use the ‘flyweight pattern’, here a good link: http://gameprogrammingpatterns.com/flyweight.html
And here the overview of chapters on that site: http://gameprogrammingpatterns.com/contents.html (one of the BEST sites you’ll ever know :P)
So basically, objects share as much data as possible, creating much less data to initialize, handle etc, your array objects will be smaller.You could share: Enum’s/Texture objects(allthough dont save that in the blocks! :x),/ Texture coordinates, you get the idea.

And when you want to use blocks, you don’t event need block coordinates, since you can ‘compute them at runtime’. When you use a three.dimensional array, you haveyour coordinates :slight_smile: Here another site that explains it nicely: https://sites.google.com/site/letsmakeavoxelengine/

[quote]…but the map in it is rather small, less than the half of it is storing information of the Environment.
[/quote]
That’s exactly what i meant, that’s the bad thing with voxels/blocks. You have a big amount of data (Air blocks and the like), that are not seen or used, you mostly just ignore them. Then you need to do some tricks, Rendering and update whise to keep the performance well.
But in this case it is not a problem, but your maps a likely to get a lot bigger than this :), so it depends.(Also the way you want to design the levels…)

If you use blocks: You can easily create an editor, or do it per text (or whatever really). Your collision detection won’t be too hard, but maybe just a bit time consuming. With collision, you will need, off course, to just get blocks around the player to calculate collision to make it ‘efficient’. But then again you need to define which sides of the blocks are going to be renderer, to not just give your CPU cycles away, and then maybe think about using Display List’s/VBO for rendering.(You use OpenGL right ? :P)

If you use other meshes(from rectangular boxes to more complex ones): You can still easily create an editor, even make it fixed along a grid, but you’ll have much less objects to worry about. Let’s say you Model one box for the parts of the floor, one for the log, one for everything, you can test collision on every objects and it still won’t matter (In this little example). But then you need to eventually do near and precise collision detection, or even still by ‘regions’. You won’t have to bother so much about which faces not to draw, since there (probably) arent so many. BUT, i guess, texturing the levels will be harder depending on how you do things, since you have to uv-map the meshes by hand or program.

I could go on and on, but i think you’ve got it after the second paragraph :slight_smile:

Do you use LWJGL/OpenGL and to plan to make this ‘by hands’?

Be careful using a 3d array and make sure you dont cache thrash (awesome nerdy band name) . I think the best way to do this is to build a loader class and to store each tile as an identity with a coordinate . This means that you can store all the data in a single 1d array into a file , much more easy to read and much more efficient to store especially with much larger files , the loader class saves each tile by scanning the map and saving it into this file , to read it you simply have your map array (ingame) read through the file and add the the ingame map accordingly.

Many thanks to you :]

I got a basic idea on how to store the maps and the meshes of the tiles.
So basically I’ll store every map in an array of Tiles with the information of X,Y,Z Coordinates.
This should be more efficient than an 3 Dimensional Array.

As for the Meshes of the Tiles, I’m thinking of a AutoTile-Class with different Meshes for different Positions (E.g. the Corner,the inner Corner or the Center)

Neato!
Glad it worked!