Chunk Format

Revision as of 01:00, 31 December 2015 by Richardll (talk | contribs) (→‎Data)
Jump to navigation Jump to search

This page gives an overview of the SMP map format used in the protocol.


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.



  • 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


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


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)


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.
    • 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.

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.

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 data per block 8 for both arrays, 4 for just block light, 16 for all with biome
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 0 - 15 light level
Array of skylight data (optional depending) Each element is 1/2 byte, corresponds to block type and data position 0 - 15 light level from sun
Biome ID array, each element a byte (Sent with packet 0x26) Corresponds to each z,x value, 256 elements Biome ID

The 'biome' array is always 256 bytes when sent.