Minecraft infdev introduced a new data storage challenge while under development: Terrain generated in infdev has the potential to be almost 235 petabytes, which is 240,640 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 folder may also contain level.dat_old, a backup of level.dat. There is also a session.lock file to make sure only one Minecraft opens the world at once.
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:
- program opens session.lock
- program writes timestamp to session.lock
- program monitors session.lock for changes
- 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 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"): Stores the Unix time stamp (in milliseconds) when the player saved the game.
- TAG_Compound("Player"): Player entity information. See Entity Format and Mob 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.
- TAG_Short("Damage"): The amount of wear each item has suffered. 0 means undamaged. When the Damage exceeds the item's durability, it breaks and disappears. Only tools and armor accumulate damage normally.
- TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is 1-255. Values above 127 are not displayed in-game.
- TAG_Byte("Slot"): Indicates which inventory slot this item is in.
- TAG_Compound: Inventory item data
- TAG_Int("Score"): Current score, doesn't appear to be implemented yet. Always 0.
- TAG_List("Inventory"): Each TAG_Compound in this list defines an item the player is carrying, holding, or wearing as armor.
- 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_Byte("SnowCovered"): 1 enables, 0 disables, see Winter Mode
- 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 BlockLight 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("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("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. Note: This array's indexes are ordered Z,X whereas the other array indexes are ordered X,Z,Y.
- 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) indicate whether the terrain in this chunk was populated with special things. (Ores, special blocks, trees, dungeons, flowers, waterfalls, etc.)
Block Format
Blocks are laid out in sets of vertical columns, with the rows going east-west through chunk, and columns going north-south. Blocks in each chunk are accessed via the following method:
unsigned char BlockID = Blocks[ y + ( z * ChunkSizeY(=128) + ( x * ChunkSizeY(=128) * ChunkSizeZ(=16) ) ) ];
The coordinate system is as follows:
- X increases South, decreases North
- Y increases upwards, decreases downwards
- Z increases West, decreases East
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.
All entities share this base:
- TAG_Compound: Entity data
- TAG_String("id"): Entity ID
- 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.
- 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 up to 20 seconds submerged. Decreases while underwater. If 0 while underwater, the entity loses 1 health per second.
- TAG_Byte("OnGround"): 1 if the entity is touching the ground.
- TAG_Compound: Entity data
Mobs
Known Mob Entity ids: Mob, Monster, Creeper, Skeleton, Spider, Giant, Zombie, Slime, Pig, Sheep, Cow, Chicken
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"): Unknown
"Pig" has one additional field:
- TAG_Byte("Saddle"): 1 or 0 (true/false) - true if there is a saddle on the pig.
"Sheep" has one additional field:
- TAG_Byte("Sheared"): 1 or 0 (true/false) - true if the sheep has been sheared.
"Slime" has one additional field, and it can't be used as the Entity ID of a MobSpawner:
- TAG_Int("Size"): The size of the slime
Items
Known Item Entity ids: Item, Arrow, Snowball, Painting
Additional fields for "Item":
- TAG_Short("Health"): Unknown
- TAG_Short("Age"): Unknown
- TAG_Compound("Item"): Item data
- TAG_Short("id"): Item or Block ID.
- TAG_Short("Damage"): The amount of wear each item has suffered. 0 means undamaged. When the Damage exceeds the item's durability, it breaks and disappears. Only tools and armor accumulate damage normally.
- TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is 1-255. Values above 127 are not displayed in-game.
Additional fields for "Arrow" and "Snowball":
- 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"): Unknown
- TAG_Byte("shake"): Unknown
- TAG_Byte("inGround"): 1 or 0 (true/false) - Unknown
Additional fields for "Painting":
Possible values for Motive are not yet catalogued.
- 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_Short("TileX"): X coordinate of the block the painting is hanging on.
- TAG_Short("TileY"): Y coordinate of the block the painting is hanging on.
- TAG_Short("TileZ"): Z coordinate of the block the painting is hanging on.
Vehicles
Known Vehicle Entity ids: Minecart, Boat
Additional fields for "Minecart":
- TAG_Byte("Type"): The type of the cart: 0 - empty, 1 - with a chest, 2 - with a furnace.
For a minecart with furnace there are three additional fields:
- TAG_Double("PushX"): Unknown
- TAG_Double("PushZ"): Unknown
- TAG_Short("Fuel"): Unknown
For a minecart with a chest there is one additional field:
- TAG_List("Items"): List of items in the slots, same as for a chest.
Dynamic Tiles
Known Dynamic Tile Entity ids: PrimedTnt, FallingSand
Additional fields for "PrimedTnt":
- TAG_Byte("Fuse"): Ticks until explosion.
Additional fields for "FallingSand":
- TAG_Byte("Tile"): Block ID.
Tile Entity Format
Known TileEntity ids: Furnace, Sign, MobSpawner, Chest
All tile entities share this base:
- 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.
- TAG_Compound: Tile entity data
A tile entity has additional fields depending on its id:
Furnace
- TAG_Short("BurnTime"): Fuel time
- TAG_Short("CookTime"): Cooking time
- TAG_List("Items"): List of items in the slots
Sign
- 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
MobSpawner
- TAG_String("EntityId"): The id of the mob .
- TAG_Short("Delay"): Ticks until next spawn.
Chest
- TAG_List("Items"): List of items in the chest. Each item is a TAG_Compound identical to the ones in the Inventory list. Chest slots are numbered 0-26 with 0 in the top left corner.
See Also
- Map Format (NBT)
- Infdev