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.

index.dat Format
index.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, index.dat_old, a backup of index.dat.

NBT Structure
The structure of the file is as follows:


 * TAG_Compound("Data"): Holds the map information.
 * TAG_Long("Time"):: Stores the current "time of day" within the map. 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.
 * TAG_List("Pos"): 3 TAG_Doubles describing the current X,Y,Z position of the player entity.
 * TAG_Short("AttackTime"): Unknown
 * TAG_List("Motion"): Current velocity of the player entity at the time of the save, stored as 3 TAG_Doubles (X,Y,Z). (Note: Falling into the void appears to set this to ridiculously high speeds. 0,0,0 is no motion.)
 * TAG_Short("HurtTime"): Unknown
 * TAG_Short("Fire"): Has something to do with fire and how much health is taken each second. -20 appears to be the baseline, but can dip as low as -1000 and as high as 1000.
 * TAG_Short("Health"): Amount of health the player currently possesses. 0 is dead, 20 is full health.
 * TAG_Float("FallDistance"): Likely used to calculate damage done upon impact with a solid surface based on amount of distance the player has fallen. 0 appears to mean no fall distance. No apparent maximum.
 * TAG_Short("Air"): How much oxygen the player has while underwater. 200 is the unmodified maximum, 0 indicates the player is out of breath.
 * TAG_List("Inventory"): Up to 36 (9 columns, 4 rows including "on-hand" items) TAG_Compounds containing 4 items. 0-8 are on-hand slots (slots shown on-screen during normal gameplay), the rest are backpack slots, accessible through the inventory menu. Order of these items may be important.
 * TAG_Compound: 4 entries
 * TAG_Short("id"): Item or Block ID (see Blocks, items and 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"): Number of range 0-35 indicating the slot number. 0-8 are on-hand items, 9-35 are backpack items.
 * TAG_List("Rotation"): 2 TAG_Floats depicting the player rotation at time of game save. Axes and type (degrees/radians) are unknown at this time.
 * TAG_Int("Score"): Current score of the player, doesn't appear to be implemented yet. Baseline is 0.
 * TAG_Short("DeathTime"): Unknown
 * 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"): Size of the entire saves, possibly in bytes.
 * TAG_Long("RandomSeed"): Random number providing the Random Seed for infdev's level generator.

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.

NBT Structure

 * TAG_Compound("Level"): Stores data about the chunk.
 * TAG_Byte_Array("Data"): 16384 bytes of data pertaining to blocks. Format unclear.
 * TAG_List("Entities"): List of entities (mobs, falling sand/gravel/TNT(?)) in the area. Format similar to that of the player.
 * TAG_Long("LastUpdate"): Timestamp.
 * 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_List("TileEntities"): Appears to store tile entities (chests, Mob spawners), but the format is unclear.
 * TAG_Compound: A tile entity (following is minimum Tile Entity info:)
 * TAG_String("id"): Tile entity ID (MobSpawner, Chest)
 * TAG_Int("x")/TAG_Int("y")/TAG_Int("z"): Local coordinates of the TileEntity.
 * 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)
 * 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_Byte_Array("Blocks"): 32768 blocks in byte form. See Block Format below for details

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