From time to time, I see a game that is inspiring enough for me to either try to re-code them my way or create a new game that is very similar. It recently happened with
Minecraft, the fabulous game by Mojang AB (or you could say just Notch).
The concept is simple : you begin the game in a wild cubic world, with a few animals around, mountains, trees and the see. The only tool you have is your bare hands, with which you can destroy most cubes in the world to collect them, and eventually place them wherever you want.
What is the point of the game ? Well, soon enough, the night starts to fall, and monsters appear... At first you can't fight them (unless you're willing to die after earing a *pshhhhh...*), so your only option is to build yourself a house and wait for the sun to return. Then, all monsters will catch on fire and die in a matter of seconds, leaving you alone again in this wide world (~4 times the surface of Earth !).
Very early in the game, you can build some tools using your inventory, torches for example, or a crafting table, which allows you to create many new things (pickaxes, swords, ...). These will help you to discover some new areas of the game, by allowing you to dig fast in the stone, of traveling the seas with a boat.
On top of that, you can play this game on a multi-player server, to build and discover with your friends.
I really like the simplicity of the game, and the vast opportunities it offers.
So I wanted to give it a shot : could I program such a game myself ?
My first priority was performances : currently, I only have a very crappy laptop at my disposal, on which Minecraft runs smoothly only with the lowest graphics options. But it is written in Java, and some even say it is
badly written in Java. So that leaves some room for improvements.
On top of that, you can run into memory problems if you're not careful : improving performances implies most of the time to cache calculations to avoid running them on every frame. If you cache too much, you end up using enormous amounts of memory... To give you an idea, Minecraft can display the world up to a distance of 256 blocks, that means roughly 70 000 000 blocks... Assuming 5 bytes per block (which is quite a low number), it sums up to at least 300MB of memory.
As for CPU/GPU performances, I have at least 30 frames per second with a view distance of 250 blocks and smooth lighting enabled (per vertex lighting and ambient occlusion), while Minecraft runs terribly slow with the same parameters (about twice slower).
But again, I'm missing many features of Minecraft, so maybe I've done some optimizations that I won't be able to keep in the future.
I've used SFML for input handling, window and opengl context creation, and 2D drawing for the GUI. I also plan to use it for networking and sound/music later.
zlib is used to compress and decompress the world files to decrease disk usage and bandwidth.
The rest is done using OpenGL directly (not a big deal actually).
Anyway, enough talking, here are the pretty screenshots :
(don't mind the 8FPS, I had to Alt+Tab to take a screen shot without the mouse on Ubuntu...)
Smooth lighting and normal lighting comparison (I erased the mouse with Gimp here... damn thing). Normal lighting is the raw result of light propagation per block. Lighting is done per cube face. With smooth lighting, each vertex takes the average light amount of the surrounding blocs and lighting is done per vertex instead. There is also an ambient occlusion effect, which is very simply implemented (~ number of occupied blocks around the vertex).
Basic procedural terrain generation.
All pictures were taken on my laptop with an integrated Intel chip, except the last one which was taken on my gaming rig that is ~2-3 years old (with GUI caching on).
What is done :
- Basic procedural terrain generation
- Multithreaded updating, loading, generating, saving of block chunks
- Placing/removing blocs
- Fully implemented lighting system with sun light (saved in the world file) and point lights
- Ambient occlusion effect
- Collision detection and response
- 8 inventory quick slots
- Inventory (no GUI yet)
- Basic items from minecraft (all tools in all qualities)
- Block solidity
Known issues :
- Severe visibility bug since svn0032 (bad chunk update).
- Imperfect collision detection code (it is possible to fall through the ground).
Current controls :
- Escape : exit the game
- W, S, A, D : move front/back left/right (editable in game)
- Space : jump (editable in game)
- Mouse left : dig
- Mouse right : place selected block
- Mouse wheel : change selected block
- Shift : toggle mouse cursor
- L : add a light
- Shift+L : remove a light
- F2 : toggle smooth lighting (enabled by default)
- F3 : toggle shaders (enabled by default if supported)
- F4 : toggle VBO rendering (enabled by default if supported)
- F6 : toggle wireframe view
- F7 : toggle day/night cycle (enabled by default)
You can download the sources and binaries (win32 and linux32) from the project's sourceforge page :
[download], or using the following links (I may forget to update this post for every release, so don't hesitate to visite the sourceforge page). It is released under the GNU General Public License (GPL).
Although I'm much less used to distributing linux programs, it should work out of the box provided that you have the following packages installed :
- libfreetype6 (libfreetype.so.6)
- zlib1g (libz.so.1)
- libgl1-mesa-glx (libGL.so.1)
- libglu1-mesa (libGLU.so.1)
- libglew1.5 (libGLEW.so.1.5)
Please tell me if the program requires a shared object that is not covered by this list. All other dependencies are linked as static libraries, except some very common ones like libc, libX11, ...
If you decide to compile the program yourself, I warn you : it may be a little difficult... I use several libraries written by myself for other projects, which depends among others on lua5.1 (to which I've made some modifications) and freetype2. I've also modified SFML a little ;). Latest Win32 builds also require boost::thread (until MinGW supports std::thread).
The project (and the utility libraries) needs to be compiled with GCC 4.4 at least (using C++0x). Project files for Code::Blocks are provided in each package.
You can download most dependencies from here :
[download] (source only, not always updated to the last svn version), and the modified versions of Lua5.1 and SFML2.0 here :
[zip],
[7z] (again, source only).