Chunk format

Chunks store the terrain and entities within a 16x16x256 area. They also store precomputed lighting, heightmap data for Minecraft's performance, and other meta information.

Chunks were first introduced in Minecraft Infdev. Before the addition of the MCRegion format in Beta 1.3, chunks were stored as individual chunk files ".dat" where the file names contained the chunk's position encoded in Base36. MCRegion changed this by storing groups of 32x32 chunks in individual ".mcr" files with the coordinates in Base10, with the goal being to reduce disk usage by cutting down on the number of file handles Minecraft had open at once. MCRegion's successor is the current format, Anvil, which only made changes to the chunk format. The region file technique is still used, but the region file extensions are ".mca" instead.

The major change from MCRegion to Anvil was the division of Chunks into Sections; each chunk has up to 16 individual 16x16x16 block Sections so that completely empty sections will not be saved at all. Preparation has also made to support blocks with IDs in the range 0 to 4096, as compared to the previous 0 to 255 limitation. However, Minecraft is not fully prepared for such blocks to exist as items; many item IDs are already taken in the range 256 to 4095.

The Blocks, Data, BlockLight, and SkyLight arrays are now housed in individual chunk Sections. The Data, SkyLight, and BlockLight are arrays of 4-bit values, and the BlockLight and SkyLight arrays no longer house part of the block ID. The Blocks array is 8 bits per block, and the 4096-blocks support exists in the form of an optional Add byte array of 4-bit per block for additional block ID information. With the Anvil format, the NBT Format was changed from Notch's original specification to include an integer array tag similar to the existing byte array tag. It is currently only used for height map information in chunks.

NBT Structure
See also: information from the Anvil format page
 * TAG_Compound("Level"): Chunk data.
 * TAG_Int("xPos"): X position of the chunk.
 * TAG_Int("zPos"): Z position of the chunk.
 * TAG_Long("LastUpdate"): Tick when the chunk was last saved.
 * TAG_Byte("TerrainPopulated"): 1 or not present (true/false) indicate whether the terrain in this chunk was populated with special things. (Ores, special blocks, trees, dungeons, flowers, waterfalls, etc.) If set to zero then minecraft will regenerate these features in the blocks that already exist.
 * TAG_Byte_Array("Biomes"): May not exist. 256 bytes of biome data, one byte for each vertical column in the chunk. See Data Values for biome IDs. If this tag does not exist it will be created and filled by Minecraft when the chunk is loaded and saved. If any values in this array are -1, Minecraft will also set them to the correct biome.
 * TAG_Int_Array("HeightMap"): 1024 bytes(256 TAG_Int) of heightmap data. 16 x 16. Each byte records the lowest level in each column where the light from the sky is at full strength. Speeds computing of the SkyLight. Note: This array's indexes are ordered ZX whereas the other array indexes are ordered XZ or YZX.
 * TAG_List("Sections"): List of Compound tags, each tag is a sub-chunk of sorts.
 * TAG_Byte("Y"): The Y index (not coordinate) of this section. Range 0 to 15 (bottom to top), with no duplicates but some sections may be missing if empty.
 * TAG_Byte_Array("Blocks"): 4096 bytes of block IDs defining the terrain. 8 bits per block, plus the bits from the below Add tag. 3D order YZX.
 * TAG_Byte_Array("Add"): May not exist. 2048 bytes of additional block ID data. The value to add to (combine with) the above block ID to form the true block ID in the range 0 to 4095. 4 bits per block. 3D order YZX. Combining is done by shifting this value to the left 8 bits and then adding it to the block ID from above.
 * TAG_Byte_Array("Data"): 2048 bytes of block data additionally defining parts of the terrain. 4 bits per block. 3D order YZX.
 * TAG_Byte_Array("BlockLight"): 2048 bytes recording the amount of block-emitted light in each block. Makes load times faster compared to recomputing at load time. 4 bits per block. 3D order YZX.
 * TAG_Byte_Array("SkyLight"): 2048 bytes recording the amount of sun or moonlight hitting each block. Makes day/night transitions smoother compared to recomputing per level change. 4 bits per block. 3D order YZX.
 * TAG_List("Entities"): Each TAG_Compound in this list defines an entity in the chunk. See Entity Format below.
 * TAG_List("TileEntities"): Each TAG_Compound in this list defines a tile entity in the chunk. See Tile Entity Format below.
 * TAG_List("TileTicks"): May not exist. Each TAG_Compound in this list is an "active" block in this chunk waiting to be updated. These are used to save the state of redstone machines, falling sand or water, and other activity. See Tile Tick Format below. This tag may not exist.

Block Format
The information in this section may be incorrect; valid information is in the works.

In the Anvil format, block positions are ordered YZX for compression purposes.

The coordinate system is as follows:
 * X increases East, decreases West
 * Y increases upwards, decreases downwards
 * Z increases South, decreases North

Each section in a chunk is a 16x16x16-block area, with up to 16 sections in a chunk. Section 0 is the bottom section of the chunk, and section 15 is the top section of the chunk. To save space, completely empty sections are not saved. Within each section is a byte tag "Y" for the Y index of the section, 0 to 15, and then byte arrays for the blocks. The "Block" byte array has 4096 partial block IDs at 8 bits per block. Another byte array "Add" is used for block with IDs over 255, and is 2048 bytes of the other part of the 4096 block IDs at 4 bits per block. When both the "Block" and "Add" byte arrays exist, the partial ID from the "Add" array is shifted left 8 bits and added to the partial ID from the "Blocks" array to form the true Block ID. The "Data" byte array is also 2048 bytes for 4096 block data values at 4 bits per block. The "BlockLight" and "SkyLight" byte arrays are the same as the "Data" byte array but they are used for block light levels and sky light levels respectively. The "SkyLight" values represent how much sunlight/moonlight is reaching the block - these values do not change when the light level from the sky changes; these values act as a sort of percentage.

The pseudo-code below shows how to access individual block information from a single section. Hover over text to see additional information or comments.

byte Nibble4( byte [] arr, int index) { return index%2 == 0 ? arr[index/2]&0x0F : (arr[index/2]>>4)&0x0F ; } int  BlockPos  = y *16 * 16 + z*16 + x; byte BlockID_a = Blocks [BlockPos]; byte BlockID_b = Nibble4(Add, BlockPos); short BlockID = BlockID_a + (BlockID_b << 8) ; byte BlockData = Nibble4(Data, BlockPos); byte Blocklight = Nibble4(BlockLight, BlockPos); byte Skylight = Nibble4(SkyLight, BlockPos);

Entity Format
Every entity is an unnamed TAG_Compound contained in the Entities list of a chunk file. The sole exception is the Player entity, stored in level.dat, or in .dat files on servers.

All entities share this base:
 * TAG_Compound: Entity data
 * TAG_String("id"): Entity ID. This tag does not exist for the Player entity.
 * TAG_List("Pos"): 3 TAG_Doubles describing the current X,Y,Z position of the entity.
 * TAG_List("Motion"): 3 TAG_Doubles describing the current dX,dY,dZ velocity of the entity in meters per tick.
 * TAG_List("Rotation"): Two TAG_Floats representing rotation in degrees.
 * TAG_Float[0]: The entity's rotation clockwise around the Y axis (called yaw). Due west is 0. Can have large values because it accumulates all of the entity's lateral rotation throughout the game.
 * TAG_Float[1]: The entity's declination from the horizon (called pitch). Horizontal is 0. Positive values look downward. Does not exceed positive or negative 90 degrees.
 * TAG_Float("FallDistance"): Distance the entity has fallen. Larger values cause more damage when the entity lands.
 * TAG_Short("Fire"): Number of ticks until the fire is put out. Negative values reflect how long the entity can stand in fire before burning.
 * TAG_Short("Air"): How much air the entity has, in ticks. Fills to a maximum of 200 in air, giving 10 seconds submerged before the entity starts to drown, and a total of up to 20 seconds before the entity dies. Decreases while underwater. If 0 while underwater, the entity loses 1 health per second.
 * TAG_Byte("OnGround"): 1 or 0 (true/false) - true if the entity is touching the ground.

Mobs
Mobs are self-controlled entities with pathing capabilities. Some mobs can attack, others can only run. Some mobs can breed, and of these mobs few can be tamed by players. All mobs drop XP and many drop items.

Additional fields for Mobs:
 * TAG_Short("AttackTime"): Number of ticks the entity's "invincibility shield" is lasting after the entity was last struck.
 * TAG_Short("DeathTime"): Number of ticks the entity has been dead for. Controls death animations.
 * TAG_Short("Health"): Amount of health the entity has. Players and enemies normally have up to 20 health. Livestock has up to 10 health.
 * TAG_Short("HurtTime"): how long the mob turns red for after being hit
 * TAG_List("ActiveEffects"): The list of potion effects on this mob. May not exist.
 * TAG_Compound: A potion effect
 * TAG_Byte("Id"): The effect ID.
 * TAG_Byte("Amplifier"): The potion effect level. 0 is level 1.
 * TAG_Int("Duration"): The number of ticks before the effect wears off.

Additional fields for mobs that can breed:
 * TAG_Int("InLove"): Number of ticks until the mob loses its breeding hearts and stops searching for a mate.
 * TAG_Int("Age"): Represents the age of the mob in ticks; when negative, the mob is a baby. When 0 or above, the mob is an adult. When above 0, represents the number of ticks before this mob can breed again.

Additional fields for mobs that can be tamed by players:
 * TAG_String("Owner"): Name of the player that owns this mob. Empty string if no owner.
 * TAG_Byte("Sitting"): 1 or 0 (true/false) - true if the mob is sitting.

Creeper has one additional field:
 * TAG_Byte("powered"): 1 or 0 (true/false) - May not exist. True if the creeper is charged from being struck by lightning.

Enderman has two additional fields:
 * TAG_Short("carried"): Id of the block carried by the Enderman.
 * TAG_Short("carriedData"): Additional data about the block carried by the Enderman.

Ozelot has one additional field:
 * TAG_Int("CatType"): The ID of the skin the tamed ocelot has.

Pig has one additional field:
 * TAG_Byte("Saddle"): 1 or 0 (true/false) - true if there is a saddle on the pig.

PigZombie has one additional field:
 * TAG_Short("Anger"): Anger level. Determines the aggressivity of the creature towards players.

Sheep has two additional fields:
 * TAG_Byte("Sheared"): 1 or 0 (true/false) - true if the sheep has been shorn.
 * TAG_Byte("Color"): 0 to 15 - see wool data values for a mapping to colors.

Slime and LavaSlime have one additional field:
 * TAG_Int("Size"): The size of the slime.

Wolf has one additional field:
 * TAG_Byte("Angry"): 1 or 0 (true/false) - true if the wolf is angry.

Villager has 3 additional fields:
 * TAG_Int("Profession"): The ID of the texture used for this villager. This also influences trading options.
 * TAG_Int("Riches"): Unknown, but starts at 0 and increases with trading.
 * TAG_Compound("Offers"): May not actually exist (such as with Villages spawned from Spawn Eggs)
 * TAG_List("Recipes"): List of TAG_Compound of trade options.
 * TAG_Compound: A trade option.
 * TAG_Int("uses"): The number of times this trade has been used.
 * TAG_Compound("buy"): The first 'cost' item.
 * Same as an Item's structure, but without the Slot tag.
 * TAG_Compound("buyB"): The second 'cost' item, may not actually exist.
 * Same as an Item's structure, but without the Slot tag.
 * TAG_Compound("sell"): The item being sold for each set of cost items.
 * Same as an Item's structure, but without the Slot tag.

Projectiles
Projectiles are moving objects thrown/launched by players, mobs, and dispensers. Some projectiles travel in straight lines and are unaffected by gravity, others travel in arcs and are affected by gravity. Arrows and Fireballs can be punched back by players.

Additional fields for Projectiles:
 * TAG_Short("xTile"): X coordinate of the item's position in the chunk.
 * TAG_Short("yTile"): Y coordinate of the item's position in the chunk.
 * TAG_Short("zTile"): Z coordinate of the item's position in the chunk.
 * TAG_Byte("inTile"): For arrows being stuck into blocks.
 * TAG_Byte("shake"): The "shake" when arrows hit a block.
 * TAG_Byte("inGround"): 1 or 0 (true/false) - Unknown

Additional fields for Arrow:
 * TAG_Byte("inData"): Unknown.
 * TAG_Byte("pickup"): Unknown, not a boolean value. Affects whether the arrow can be picked up (e.g. fired in survival, fired in creative, fired from infinity bow, fired from skeleton, etc...)
 * TAG_Double("damage"): Unknown how this affects actual damage inflicted by the arrow. May not be a whole number.

Items
Items are dropped by player, mobs, and blocks, collide with solid objects, and can be picked up by players or moved with water.

Additional fields for items:
 * TAG_Short("Health"): The health of the item, which starts at 5. Items take damage from fire, lava, and explosions. The item is destroyed when its health reaches 0.
 * TAG_Short("Age"): The number of ticks the item has been "untouched". After 6000 ticks (5 minutes ) the item is destroyed.

Additional fields for Item:
 * TAG_Compound("Item"): The inventory item, without the Slot tag.
 * TAG_Short("id"): Item or Block ID.
 * TAG_Short("Damage"): The data value for this item. The name "Damage" comes from when only tools used this value, now many other items use this value for other purposes.
 * TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is -128 to 127. Values below 2 are not displayed in-game.
 * TAG_Compound("tag")
 * TAG_List("ench"): Contains enchantments for this item.
 * TAG_Compound: One of these for each enchantment.
 * TAG_Short("id"): Id of the Enchantment.
 * TAG_Short("lvl"): Level of the Enchantment
 * TAG_String("title"): For Written Book, the title of the book.
 * TAG_String("author"): For Written Book, the author of the book.
 * TAG_List("pages"): For Book and Quill and Written Book, the list of pages in the book.
 * TAG_String: A single page in the book.

Additional field for XPOrb:
 * TAG_Short("Value"): The amount of experience the orb gives when picked up.

Vehicles
Vehicles can be entered and controlled by the player and can collide with solid objects. Boats have realistic collisions with entities, and Minecarts can hold mobs.

Additional fields for Minecart: For a minecart with a chest there is one additional field: For a minecart with a furnace there are three additional fields:
 * TAG_Int("Type"): The type of the cart: 0 - empty, 1 - with a chest, 2 - with a furnace.
 * TAG_List("Items"): List of items in the slots, same as for a chest.
 * TAG_Double("PushX"): Unknown
 * TAG_Double("PushZ"): Unknown
 * TAG_Short("Fuel"): The number of ticks until the minecart runs out of fuel.

Dynamic Tiles
Dynamic tiles have realistic physics with solid objects, but do not affect nor are effected by other entities.

Additional fields for PrimedTnt
 * TAG_Byte("Fuse"): Ticks until explosion.

Additional fields for FallingSand:
 * TAG_Byte("Tile"): Block ID. Not limited to only sand or gravel.

Other
Other entity types that do not fit into any of the above categories.

Additional fields for Painting:
 * TAG_Byte("Dir"): Direction the painting faces: 0 is east, 1 is north, 2 is west, and 3 is south.
 * TAG_String("Motive"): The name of this Painting's art.
 * TAG_Int("TileX"): X coordinate of the block the painting is hanging on.
 * TAG_Int("TileY"): Y coordinate of the block the painting is hanging on.
 * TAG_Int("TileZ"): Z coordinate of the block the painting is hanging on.

Tile Entity Format
Tile Entities (not related to Entities) are used by Minecraft to store information about blocks that can't be stored in the 4-bits of block data the block has.

All tile entities share this base:
 * TAG_Compound: Tile entity data
 * TAG_String("id"): Tile entity ID
 * TAG_Int("x"): X coordinate of the Tile Entity.
 * TAG_Int("y"): Y coordinate of the Tile Entity.
 * TAG_Int("z"): Z coordinate of the Tile Entity.

Additional fields for Furnace: The original maximum burning time for the current fuel isn't stored, thus the current time left is assumed to be the maximum when this Tile Entity is loaded into memory.
 * TAG_Short("BurnTime"): Number of ticks left before the current fuel runs out.
 * TAG_Short("CookTime"): Number of ticks the item has been smelting for. The item finishes smelting when this value reaches 200 (10 seconds). Is reset to 0 if BurnTime reaches 0.
 * TAG_List("Items"): List of items in the furnace slots. Each item is a TAG_Compound identical to the ones in the Inventory list, but without the Slot tag.
 * 0: The item(s) being smeted.
 * 1: The item(s) to use as the next fuel source.
 * 2: The item(s) in the result slot.

Additional fields for Sign: Only the first 16 characters of each line are read, the rest are discarded.
 * TAG_String("Text1"): First row of text.
 * TAG_String("Text2"): Second row of text.
 * TAG_String("Text3"): Third row of text.
 * TAG_String("Text4"): Fourth row of text.

Additional fields for MobSpawner:
 * TAG_String("EntityId"): The Entity ID of the mob. Only Mob Entity IDs will work.
 * TAG_Short("SpawnCount"): How many mobs to spawn each time.
 * TAG_Compound("SpawnData"): The tags to replace the default tags; any of the Entity or Mob tags may be used, including the Pos tag.
 * TAG_Short("Delay"): Ticks until next spawn.
 * TAG_Short("MinSpawnDelay"): The minimum random delay for the next spawn delay.
 * TAG_Short("MaxSpawnDelay"): The maximum random delay for the next spawn delay. Warning: Setting this value to 0 crashes Minecraft. Set to at least 1.

Additional fields for Chest: Double chests are simply two Chest tile entities next to each other.
 * TAG_List("Items"): List of items in the chest. Each item is a TAG_Compound identical to the ones in the Inventory list, including the Slot tag. Chest slots are numbered 0-26 with 0 in the top left corner.

Additional fields for Music:
 * TAG_Byte("note"): Pitch (number of right-clicks).

Additional fields for Trap:
 * TAG_List("Items"): List of items in the dispenser, each item includes the Slot tag. Slots are numbered 0-8.

Additional fields for RecordPlayer:
 * TAG_Int("Record"): Record currently playing. 0 is no record. Otherwise, it is the item ID of the record (e.g. 2261 for the "mall" record). Other IDs can be used to make other items or blocks pop out with a data value of 0.

Additional fields for Piston:
 * TAG_Int("blockId"): Block_IDs of the block being moved.
 * TAG_Int("blockData"): Data value of the block being moved.
 * TAG_Int("facing"): Direction in which the block will be pushed.
 * TAG_Float("progress"): How far the block has been moved.
 * TAG_Byte("extending"): 1 or 0 (true/false) - true if the block is being pushed.

Additional fields for Cauldron:
 * TAG_List("Items"): List of items in the brewing stand. Each item is a TAG_Compound identical to the ones in the Inventory list, including the Slot tag. The slots are numbered 0 to 3.
 * TAG_Int("BrewTime"): The number of ticks the potions have been brewing for.

Tile Tick Format
Tile Ticks represent block updates that need to happen because they could not happen before the chunk was saved. Examples reasons for tile ticks include redstone circuits needing to continue updating, water and lava that should continue flowing, recently placed sand or gravel that should fall, etc. Tile ticks are not used for purposes such as leaf decay, where the decay information is stored in the leaf block data values and handled by Minecraft when the chunk loads. For map makers, tile ticks can be used to update blocks after a period of time has passed with the chunk loaded into memory.


 * TAG_Compound: A Tile Tick
 * TAG_Int("i"): The ID of the block; used to activate the correct block update procedure.
 * TAG_Int("t"): The number of ticks until processing should occur. May be negative when processing is overdue.
 * TAG_Int("x"): X position
 * TAG_Int("y"): Y position
 * TAG_Int("z"): Z position