Difference between revisions of "Chunk Format"
(→Data: removed pre-release info in favor of a link to Pre-release protocol) |
(→Data) |
||
Line 45: | Line 45: | ||
In 0x21 the data describes of a single chunk column in the format below. In 0x26, the format below is repeated for each chunk column. | In 0x21 the data describes of a single chunk column in the format below. In 0x26, the format below is repeated for each chunk column. | ||
+ | |||
+ | In half-byte arrays, two values are packed into each byte. Even-indexed items are packed into the ''high bits'', odd-indexed into the ''low bits''. | ||
+ | |||
+ | Chunks are sent bottom-to-top, i.e. the first chunk, if sent, extends from Y=0 to Y=15. Blocks are ordered Y, Z, X, i.e. the 'X' coordinate changes fastest. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Section | ||
+ | ! Misc | ||
+ | ! Contains | ||
+ | |- | ||
+ | |rowspan="2"|Array of Blocktypes and metadata | ||
+ | |Encoded with block[y][z][x] = block_id << 4, <nowiki>|</nowiki> meta_data & 15 | ||
+ | |rowspan="2"|Block ID and metadata | ||
+ | |- | ||
+ | |Decoded with blockid = block[y][z][x] >> 4; metadata = block[y][z][x] & 15 | ||
+ | |- | ||
+ | |Varint of bits of light data per block | ||
+ | |(8 for both arrays, 4 for just block light, see below) | ||
+ | |- | ||
+ | |Varint of both array's total elements | ||
+ | |Blocks represented (16*16*16) * number of light arrays (1 or 2) | ||
+ | |- | ||
+ | |Array of block light data | ||
+ | |Each element is 1/2 byte , corresponds to block type and data position | ||
+ | | 1 - 15 light level | ||
+ | |- | ||
+ | |Array of skylight data (optional depending) | ||
+ | |Each element is 1/2 byte, corresponds to block type and data position | ||
+ | | 1 - 15 light level from sun | ||
+ | |- | ||
+ | | rowspan="2"| Biome ID array, each element a byte (Sent with packet 0x26) | ||
+ | | rowspan="2"| Corresponds to each z,x value, 256 elements. (Which column data is this sent in? After all of them?) | ||
+ | | rowspan="2"| Biome ID | ||
+ | |} | ||
+ | |||
+ | |||
+ | |||
+ | <!-- Incase I messed something up, this is what it said before | ||
+ | |||
+ | |||
* Repeat for each chunk specified in the section bitmask: | * Repeat for each chunk specified in the section bitmask: | ||
Line 52: | Line 92: | ||
** If skylight: Sky light array, half byte per block | ** If skylight: Sky light array, half byte per block | ||
* If continuous: biome array, byte per XZ coordinate, 256 bytes total. | * If continuous: biome array, byte per XZ coordinate, 256 bytes total. | ||
+ | --> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
The 'biome' array is always 256 bytes when sent. Values above 22 will cause the client to crash. | The 'biome' array is always 256 bytes when sent. Values above 22 will cause the client to crash. |
Revision as of 02:10, 6 December 2015
This page gives an overview of the SMP map format used in the protocol.
Contents
Packets
Two packets use this format:
- 0x21 chunk data - single column - used when player movement requires new chunks to be loaded. Also used to unload chunks.
- 0x26 map chunk bulk - multiple columns - used when first spawning into a world and when player is teleported.
Concepts
Storage
- Chunk Data: an array, either 2048 or 4096 bytes
- Chunk: a 16x16x16 area, logically made up of multiple Chunk Data arrays, storing things like block ids and skylight
- Chunk Column: 16 chunks aligned vertically (totalling 16x256x16). Chunks can be uninitialised (e.g. set to
null
) - World: a collection of chunk columns
Bitmasks
You will sometimes get a blob of data and a bitmask. Each bit in the 16-bit short represents a chunk. The least significant bit represents the chunk from Y=0 to Y=15, and so forth. If it's 0
, the chunk is entirely air and there's no data to read.
You need a loop like this:
chunks = array[16]; for (i=0; i<16; i++) { if (bitmask & (1 << i)) { // read a chunk data array } }
Format
Chunk Column Metadata
The packet contains important metadata which you'll need to pull out. For bulk packets, you'll need to loop over the metadata area. Specifically:
- Chunk X
- Chunk Z
- Section Bitmask
- Continuous? (only in 0x21 - assumed true in 0x26)
- Skylight? (only in 0x26 - only if overworld in 0x21)
Data
- See also: Pre-release protocol#Chunk Section for the new format in 1.9
In 0x21 the data describes of a single chunk column in the format below. In 0x26, the format below is repeated for each chunk column.
In half-byte arrays, two values are packed into each byte. Even-indexed items are packed into the high bits, odd-indexed into the low bits.
Chunks are sent bottom-to-top, i.e. the first chunk, if sent, extends from Y=0 to Y=15. Blocks are ordered Y, Z, X, i.e. the 'X' coordinate changes fastest.
Section | Misc | Contains |
---|---|---|
Array of Blocktypes and metadata | Encoded with block[y][z][x] = block_id << 4, | meta_data & 15 | Block ID and metadata |
Decoded with blockid = block[y][z][x] >> 4; metadata = block[y][z][x] & 15 | ||
Varint of bits of light data per block | (8 for both arrays, 4 for just block light, see below) | |
Varint of both array's total elements | Blocks represented (16*16*16) * number of light arrays (1 or 2) | |
Array of block light data | Each element is 1/2 byte , corresponds to block type and data position | 1 - 15 light level |
Array of skylight data (optional depending) | Each element is 1/2 byte, corresponds to block type and data position | 1 - 15 light level from sun |
Biome ID array, each element a byte (Sent with packet 0x26) | Corresponds to each z,x value, 256 elements. (Which column data is this sent in? After all of them?) | Biome ID |
The 'biome' array is always 256 bytes when sent. Values above 22 will cause the client to crash.