Difference between revisions of "Chunk Format"

From wiki.vg
Jump to navigation Jump to search
(→‎Data: removed pre-release info in favor of a link to Pre-release protocol)
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.
 +
-->
  
Each section (except for biome) contains packed chunk data for zero or more 16x16x16 chunks. You need to refer to the primary bitmask for the chunk column to see which chunks are sent.
 
 
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''.
 
  
 
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.

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.

Implementations