Implementing endless map in memory
boost, c++, maps
Solution
I assume you probably wouldn't need to the have entire possible area of a Minecraft world in memory time because that would be incredibly huge (1024000000 KM^2). If you are just trying to keep the area that anyone would usually end up visiting during a game in memory I think it would be completely feasible to access it using STL (Standard template library).
Minecraft worlds are always loaded in game in chunks which are 16X16X255 blocks. You could store chunks in your program in a `std::map`. There are a few advantages to this method. The first is it allows representation of locations well beyond the playable area of the map based on the wiki entry for the Far Lands. It also allows for a sparse representation of the minecraft map that will very closely resemble how actual Minecraft maps are rendered. Only the chunks that you are using for your program are loaded in the `std::map` and hopefully keep memory usage reasonable. You would be able to represent any area no matter its location in the playable area of the total possible Minecraft map area.
To implement this you will just have to first create the world datatype:
using namespace std;
struct Block
{
// Whatever information you care to store here...
};
typedef vector<block> Chunk;
typedef map<int, map<int, Chunk> > World;
Then to access a single block:
Block McMap::getBlock(int x, short y, int z)
{
const int WIDTH = 16; // You might want to store these constants elsewhere
const int HEIGHT = 255;
int chunkx = x / WIDTH;
int chunkz = z / WIDTH;
return yourWorld[chunkx][chunkz][x + z * WIDTH + y * HEIGHT * WIDTH];
}
To erase a chunk:
void McMap::eraseChunk(int x, int z)
{
if (yourWorld.find(x)) // Tests to make sure that row exists in the map.
yourWorld[x].erase(z);
}
Another benefit to using this method is that by creating a clever constructor for a chunk rather than just using a `typdedef` like I did you could automatically generate a chunk when you need to access a new chunk in the world `std::map` similar to how chunks are generated in Minecraft only when you visit them. Whenever you access an object that does not exist yet in a map it will call the default constructor for that object.
Problem
I will have to implement an endless 3D raster map in program memory. The map may or may NOT start at [0;0;0]. The map has Y coordinate limited by 255, others may be infinite. (yes, now, you may have guessed it is a Minecraft map) I need to create some class which will have simple `McMap::getBlock(int x, short y, int z)` and `McMap::setBlock(int x, short y, int z)` method. Means I need to be able to both read and write the data. I also want to be able to delete blocks and so free the memory. What should user for this purpose? I think the best solution would be some table with such structure: ``` int x|short y|int z|int block id|other values... -----+-------+-----+------------+--------------- 55| 21| 666| 1| ``` But how do I implement this with C++, without using real MySql (that would be real overkill)? Also, I don't want to keep the map when the program exits, so I want the data to be inside the programs memory. Once more, consider that the map is infinite and so the coordinates may be whatever. Also do not forget that a very distant points may be mapped. Also, a very important thing to note: I need to have an effective way to get block by X, Y and Z coordinates - I don't want to walk through all block to find one of them. I have already included boost library.