Java Edition Alpha level format

Minecraft infdev introduced a new data storage challenge while under development: Terrain generated in infdev has the potential to be several terabytes in size when stored in memory, due to the sheer size of the map (several times the surface area of the Earth). Therefore, to reduce file size and memory usage, Notch decided to split the terrain into 16 x 16 x 128 chunks and store them on disk when not visible. In addition, terrain is only generated when it is within the drawing distance of the player's camera, significantly reducing save size, since most players will only be able to search a tiny fraction of the map in a reasonable time frame.

World folder structure
An infdev level is actually a single folder containing at least one file named "level.dat". The world folder may have up to 64 subfolders, each with up to 64 additional subfolders each. These folders contain the chunk files that hold the world's terrain and entities. Each chunk file is identified by its chunk position xPos and zPos. The varying parts of the chunk file's name are obtained by taking the base36 representation of the xPos and zPos. The names of the folders that the chunk file is placed in are found by taking xPos and zPos, modulo 64, and converting to base36.

As an example, to find the chunk at position (-13, 44):

* The first folder name is base36(-13 % 64). This is base36(51) which is "1f". * The second folder name is base36(44 % 64). This is base36(44) which is "18". * The chunk file's name is "c." + base36(-13) + "." + base36(44) + ".dat". This evaluates to "c.-d.18.dat" * Thus, the chunk at (-13, 44) is stored in "1f/18/c.-d.18.dat"

Each chunk remembers its position independently of the file and folder names. See Chunk File Format to find out how to read a chunk's position from the file data.

session.lock Format
session.lock contains the timestamp of when the world was last touched. The file is eight bytes long, and contains a single 64-bit signed integer in big endian format. The value of this integer is the timestamp, stored as the number of milliseconds elapsed since 1970, in UTC.

Unlike typical lock files, session.lock ensures that the LAST program to open a world is that one that owns it. The process goes something like this:


 * 1) program opens session.lock
 * 2) program writes timestamp to session.lock
 * 3) program monitors session.lock for changes
 * 4) if the contents of session.lock change, program aborts and gives up its lock on the world.

level.dat Format
level.dat is an NBT file that stores environmental data (time of day, for example) and player health, inventory, velocity, and position within the map. Most importantly, it stores the en:Random Seed that the terrain generator uses to seamlessly generate more terrain on the fly.

The world folder may also contain a second file, level.dat_old, a backup of level.dat.

NBT Structure
The structure of the file is as follows:


 * TAG_Compound("Data"): World data.
 * TAG_Long("Time"): Stores the current "time of day" in ticks. There are 20 ticks per real-life second, and 24000 ticks per Minecraft day, making the day length 20 minutes. 0 appears to be sunrise, 12000 sunset and 24000 sunrise again.
 * TAG_Long("LastPlayed"): Probably stores the Unix time stamp when the player saved the game.
 * TAG_Compound("Player"): Player entity information. See Entity Format for details. Has additional elements:
 * TAG_List("Inventory"): Each TAG_Compound in this list defines an item the player is carrying, holding, or wearing as armor.
 * TAG_Compound: Inventory item data
 * TAG_Short("id"): Item or Block ID (see Data values).
 * TAG_Short("Damage"): The amount of wear each tool has suffered. 0 is undamaged, maximum may be different for each tool. Non-tool items (blocks, for example) have 0 damage.
 * TAG_Byte("Count"): Number of items stacked in this inventory slot. Curiously, tools can be stacked as well. Range is 1-255. (Counts over a certain number make the white stack count number in the inventory menu disappear, picking up more items results in the count being reset).
 * TAG_Byte("Slot"): Indicates which inventory slot this item is in.
 * TAG_Int("Score"): Current score, doesn't appear to be implemented yet. Always 0.
 * TAG_Int("SpawnX"): X coordinate of the player's spawn position. Default is 0.
 * TAG_Int("SpawnY"): Y coordinate of the player's spawn position. Default is 64.
 * TAG_Int("SpawnZ"): Z coordinate of the player's spawn position. Default is 0.
 * TAG_Long("SizeOnDisk"): Estimated size of the entire world in bytes.
 * TAG_Long("RandomSeed"): Random number providing the Random Seed for the terrain.

Chunk File Format
Chunks files store the terrain and entities within a 16x16x128 area. They also store precomputed lighting and heightmap data for Minecraft's performance. The file names contain the Base36 of the chunk's position.

The Data, SkyLight, and HeightMap are arrays of 4-bit values. The low bits of the first byte of one of these corresponds to the first block in the Blocks array

NBT Structure

 * TAG_Compound("Level"): Chunk data.
 * TAG_Byte_Array("Blocks"): 32768 bytes of block IDs defining the terrain. 8 bits per block. See Block Format below for byte ordering.
 * TAG_Byte_Array("Data"): 16384 bytes of block data additionally defining parts of the terrain. 4 bits per block.
 * TAG_Byte_Array("SkyLight"): 16384 bytes recording the amount of sun or moonlight hitting each block. 4 bits per block. Makes day/night transitions smoother compared to recomputing per level change.
 * TAG_Byte_Array("HeightMap"): 256 bytes 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.
 * TAG_Byte_Array("BlockLight"): 16384 bytes recording the amount of block-emitted light in each block. 4 bits per block. Makes load times faster compared to recomputing at load time.
 * 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_Long("LastUpdate"): Tick when the chunk was last saved.
 * TAG_Int("xPos"): X position of the chunk. Should match the file name.
 * TAG_Int("zPos"): Z position of the chunk. Should match the file name.
 * TAG_Byte("TerrainPopulated"): 1 or 0 (true/false) value seeming to indicate whether lighting data for the full chunk has been calculated yet. If false, there may still be some lighting data that originated from other chunks. (not verified)

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.

Known Entity ids: Item, Pig, Sheep, Cow, Zombie, Skeleton, Spider, Creeper, Minecart, Boat, Painting


 * TAG_Compound: Entity data
 * TAG_String("id"): Entity ID
 * TAG_Byte("OnGround"): 1 if the entity is touching the ground.
 * TAG_Short("AttackTime"): Unknown
 * TAG_Short("DeathTime"): Number of ticks the entity has been dead for. Controls death animations.
 * TAG_Short("Air"): How much air the entity has, in ticks. Fills to a maximum of 200 in air, giving up to 20 seconds submerged. Decreases while underwater. If 0 while underwater, the entity loses 1 health per second.
 * 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("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"): Number of ticks the entity's "invincibility shield" is lasting after the entity was last struck.
 * TAG_Float("FallDistance"): Distance the entity has fallen. Larger values cause more damage when the entity lands.
 * 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. (Note: Falling into the void appears to set this to ridiculously high speeds. 0,0,0 is no motion.)
 * 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.

Tile Entity Format
Known TileEntity ids: Chest, Furnace, Sign, MobSpawner


 * TAG_Compound: Tile entity data
 * TAG_String("id"): Tile entity ID
 * TAG_Int("x"):
 * TAG_Int("y"):
 * TAG_Int("z"): Local coordinates of the TileEntity.

Block Format
Blocks in each chunk are accessed via the following method:

unsigned char BlockID = Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];

The direction of decreasing Z coordinates is East. Likewise, decreasing X is north, increasing Z is west, and increasing X is south