Difference between revisions of "Chunk Format"

From wiki.vg
Jump to navigation Jump to search
(→‎Data: more clear about add array being present or not)
Line 54: Line 54:
 
* Block light array - half byte per block
 
* Block light array - half byte per block
 
* Sky light array - half byte per block - only if 'skylight' is true
 
* Sky light array - half byte per block - only if 'skylight' is true
* Add array  - half byte per block - uses secondary bitmask
+
* Add array  - half byte per block - only if secondary bitmask is nonzero
 
* Biome array - whole byte per XZ coordinate, 256 bytes total, only sent if 'ground up continuous' is true
 
* Biome array - whole byte per XZ coordinate, 256 bytes total, only sent if 'ground up continuous' is true
 
    
 
    

Revision as of 14:30, 6 January 2013

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

Packets

Two packets use this format:

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 bunch 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. In the case of 0x38, you'll need to loop over the metadata area. Specifically:

  • Chunk X
  • Chunk Z
  • Primary Bitmask
  • Add Bitmask
  • Ground-up contiguous (only in 0x33 - assumed true in 0x38)
  • Skylight (only in 0x38 - assumed true in 0x33)

Data

The data is compressed using the deflate() function in zlib. In 0x33, it describes of a single chunk column in the format below. In 0x38, the format below is repeated for each chunk column.

The format is thus:

  • Block type array - whole byte per block
  • Block metadata array - half byte per block
  • Block light array - half byte per block
  • Sky light array - half byte per block - only if 'skylight' is true
  • Add array - half byte per block - only if secondary bitmask is nonzero
  • Biome array - whole byte per XZ coordinate, 256 bytes total, only sent if 'ground up continuous' is true

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, or the add bitmask for 'add' data, which is Mojang's means of provided Block IDs past 256. In vanilla minecraft, you can expect this to always be zero.

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.

Implementations