Pocket Minecraft Map Format
This article describes the Chunk format used in the Full Chunk Data (0xbf, clientbound).
Contents
Concepts
- Chunk: a 16×128×16 area, sometimes also called chunk section
Format
A chunk consists of the following fields (fixed size of 83200 bytes):
Field Name | Field Type | Notes |
---|---|---|
Blocks | Array of bytes | Always a size of 32,768 bytes |
Regular Data | Array of bytes | Always a size of 16,384 bytes |
Sky Light | Array of bytes | Always a size of 16,384 bytes, half byte per block |
Block Light | Array of bytes | Always a size of 16,384 bytes, half byte per block |
Height Map | Array of ints | Always a size of 256 bytes |
Biome Colors | Array of ints | Always a size of 1024 bytes |
Blocks
The following definitions are provided to clarify the mapping between the location of a block within a LevelDB entry containing a chunk of 32,768 blocks and the corresponding location of the block within the entire world:
- Let
X
andZ
be the values contained within the LevelDB key. - Let
C[]
be a three dimensional array of the chunk of 32,768 blocks contained within the LevelDB entry. The first two indices i and j range from 0 to 15, and the third index y ranges from 0 to 127. - Let
W[]
be a three dimensional array of the blocks contained within the entire world.
For infinite worlds, the first two indices x
and z
both range over the values of a four byte integer and may be negative as well as positive.
The third index y
ranges from 0 to 127 for both old style and infinite worlds.
Assuming the definitions above, the location of a block with a LevelDB entry with key values X
and Z
maps to the corresponding location of the block within the entire world as follows:
let x = 16 * X + i let z = 16 * Z + j C[i, j, y] <-> W[x, z, y]
Skylight/Blocklight/Metadata
Block light and skylight are very similar to the 1.8 implementation used in the Minecraft: PC edition of the game. All chunks always have the same value and have a fixed size of 83200, you can index the skylight/blocklight/metadata by block by using (x * 2048) + (z * 128) + y
where x, y, z are the coordinates of the block you are trying to retrieve the skylight/blocklight/metadata for.
Heightmap
The heightmap is the mapping between the height of each block in a chunk for retrieveing by x and z you can simply (z << 4) + x
to get the value or set it.
Biome colors
Each block in a single column has a biome id and (unlike the PC version of the game) an r, g, b value associated with it that is used for the client to render the color (more like hue) of the block. For finding/setting the biome id for a column of blocks the key for each column is (z << 4) + x
and the integer that you pack inside the value is (current & 0xFFFFFF) | (biomeId << 24)
where current = biomes[(z << 4) + x]
and biomeId = the id of the biome
for getting the id, it is the same but you just reverse it (current & 0xFF000000) >> 24
where current = biomes[(z << 4) + x]
. For setting the r, g, b color of each chunk you can do a similar key [(z << 4) | x]
and unpack the r, g, b by color >> 16, (color >> 8) & 0xFF, color & 0xFF
and pack it again by getting the correct color (biome[(z << 4) + x] & 0xFF000000) | ((R & 0xFF) << 16) | ((G & 0xFF) << 8) | (B & 0XFF)
.
LevelDB
In the Minecraft: PE application, all chunks are stored in Mojang’s fork of LevelDB (a ZLib compressed LevelDB database) each key follows the same format unless you are using a special key, or a nether key
For an overworld key, it is quite trivial (always 9 bytes long):
Field Name | Field Type |
---|---|
X Coordinate | Little-endian int |
Z Coordinate | Little-endian int |
Type | A byte containing the type of data, see bytes below |
For a nether key it is similar, but with an extra byte after Z Coordinate (always 13 bytes long):
Field Name | Field Type |
---|---|
X Coordinate | Little-endian int |
Z Coordinate | Little-endian int |
Nether specifier | Little-endian int, always a value of 1 |
Type | A byte containing the type of data, see bytes below |
The corresponding byte specifier for the type of chunk are:
Field Name | Field Value |
---|---|
Terrain Data | 0x30 (48 in decimal, ‘0’ ASCII) |
Tile Entity Data | 0x31 (49 in decimal, ‘1’ ASCII) |
Entity Data | 0x32 (50 in decimal, ‘2’ ASCII) |
1-byte Data | 0x76 (118 in decimal, ‘v’ ASCII) |
Tile Entity Data and Entity Data are encoded as NBT, the format of Terrain Data is specified above.
Implementations
- Mojang’s LevelDB: https://github.com/Mojang/leveldb-mcpe