Minecraft Save File Format in Beta 1.3

This post is intended to give tool-makers a heads-up about the modified file format in the next version of Minecraft. If you are not a tool-maker you can relax and see this post as a blog filler :)

The purpose of changing format is to improve performance and to decrease the number of files a world needs. The old format stores each world “chunk” in its own file. A chunk is 16x16x128 blocks, and big worlds can use hundred of thousands of files in the old format. This is okay for Linux-based systems, but is quite slow on Windows. We tried several different implementations of file formats, but settled on the McRegion format created by Ryan Hitchman (aka Scaevolus), with minor modifications. McRegion stores 32x32 chunks in the same file, so it requires about 500 to 1000 times fewer files.

To save you the effort to reverse engineer the file format, here are the two most important source files you need to update your Minecraft tool: RegionFile.java and RegionFileCache.java.

Minecraft Beta 1.3 will automatically convert worlds to the new format, but if you want to make your own tool these are the steps you will need to make:

First, convert all chunks and write them to region files. For each chunk,

byte[] buffer = new byte[4096];
RegionFile region = RegionFileCache.getRegionFile(baseFolder, x, z);
try {
    DataInputStream istream = new DataInputStream(new GZIPInputStream(new FileInputStream(chunkFile)));

    DataOutputStream out = region.getChunkDataOutputStream(x & 31, z & 31);

    int length = 0;
    while ((length = istream.read(buffer)) != -1) {
        out.write(buffer, 0, length);
    }

    out.close();
    istream.close();
} catch (IOException e) {
    e.printStackTrace();
}

If you have really large worlds I suggest you try to sort the chunk files so that you don’t have to switch regions too often. Also, you can check if a chunk already has been converted, to allow people to interrupt the conversion process and continue later.

Second, when all regions have been converted, update the level data (level.dat) with a new tag called “version” (all lower-case) with the integer value “19132”, and a tag called “LevelName” with any string value you want. If you are making map tools I assume you already know how to put new tags in the data.

EDIT: Scaevolus told me this is relevant to tool-makers (how to read a chunk in C): https://mod.ifies.com/f/110216/region.c