Schlagwetter
A Minecraft Server

Please visit the source code repository on GitHub.

Download: zip ball, tar.gz ball.

Check out: git clone git://github.com/louisdx/schlagwetter (see below)

Schlagwetter is an open-source project to create a server for Minecraft. While there are several other similar projects, both free and commercial, I decided to start my own with specific design goals in mind.

A cave.

News and current status

May 16, 2011: Using the new client 1.6.3 seems to work without changes on the server, but the client behaves very poorly; we are investigating whether this is due to the server, and perhaps we should wait for the 1.6 version to stabilize.

Meanwhile, progress is made towards the persistent inventory system. We welcome any contributions or suggestions! A nice terrain generator would be a great addition at this point.

May 17, 2011: [returned from holiday] Basic multiplayer should be possible, players see each other’s avatars.

April 19, 2011: Updated for compatibility with client 1.5. Several block and item handlers have been added, torches, stairs and doors are now available. Basic inventory handling is available (mined blocks will drop spawns that can be picked up), though the inventory is not yet persistent.

April 10, 2011: Basic networking framework is set up. The Minecraft protocol has been implemented as stubs, but not yet written out very much (digging and block placement work). Basic persistent storage is available: You can load a world from an arbitrarily named file, save to a (currently fixed) file, and import NBT region files to Schlagwetter’s format (just plain zipped raw chunk data, essentially) with the "nbtimporter" tool.

Design goals

*) A possible exception will be memory mapping for the persistent storage. I do not know any platform-independent framework for that (but we will write one if we need to). Update: Having used Boost.iostreams for the serialization code, I am optimistic that Boost will even allow for a platform-independent approach to memory mapping.

†) I would have said “without un-freed memory”, too, but GNU Readline does not seem to clean up and throws this off. Assistance welcome!

Libraries

I follow the motto “reuse, don't reinvent” and try to use good libraries where possible rather than rolling my own solutions. Thankfully, many useful concepts are provided by the new C++ standard library (hash containers, threads, smart pointers), and networking primitives are entirely taken care of by Boost.Asio. A few more libraries are required and used with gratitude to their creators:

Obtaining

GitHub manages the repository, you can either download a compressed archive (see above), or use git directly:

git clone git://github.com/louisdx/schlagwetter.git

You will also need to obtain the cNBT submodule:

cd schlagwetter
git submodule update --init

Build requirements

Example

Let's suppose you are on a Linux machine and you have git and cmake.

mkdir /tmp/workspace cd /tmp/workspace git clone git://github.com/louisdx/schlagwetter.git cd schlagwetter git submodule update --init mkdir ../buildplace cd ../buildplace cmake ../schlagwetter make ./src/bin/schlagwetter --help ./src/bin/schlagwetter

Any suggestions for improving the build environment are most welcome!

World file format

I decided to keep things simple. The entire world is kept in two files, basename.idx and basename.dat (the basename is freely choosable). Both files are compressed and read and written with Boost.iostream's zlib-filtered stream. Ignoring the transparent compression, the underlying file structure is very simple: The data file consists simply of consecutive blocks of 48KiB bytes of data, each being the block type (32KiB) and block metadata (16KiB) of one chunk. The index file runs in parallel and consists of flat, 12-byte entires (all values machine-endian):

int32_t chunk_X; int32_t chunk_Z; int32_t counter;

You can either read both files in parallel to obtain all chunks, or jump directly to a desired chunk at offset counter * 49152 in the data file.

To do: Perhaps it would be better to replace the counter variable with the true offset in the compressed file. The entire model assumes that you can hold all chunks in memory; though I suppose an arbitrary number of index/data pairs could be freely mixed if splitting up is desired.

Known Issues

License

I have not yet worked out the details; it will be something with “attribution” that is compatible with the other libraries and source code that I use. Any advice would be much appreciated.

Credits

Many thanks to the developers of mineserver for the inspiration for this project, lots of practical help and source code. If possible, I would like to keep the high-level constructs similar to theirs and make changes visible upstream. I am also grateful to the developers of craftd and Bravo for two very promising projects.

If you like to help out, just send me a message on GitHub, email me patches or suggestions, or send pull requests.

louisdx