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.
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.
-W -Wall -pedantic
.
*) 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!
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:
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
src/*.cpp
files and link them together (excluding tester*.cpp
and nbtimporter.cpp
);
if you set all your include paths right to pick up the requisite libraries, this ought to work.Let's suppose you are on a Linux machine and you have git and cmake.
Any suggestions for improving the build environment are most welcome!
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):
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.
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.
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