In early 2011 I (johno) finally played Minecraft Classic, and as a result became so provoked by the technology that I was compelled to write something similar of my own.
Since then I have (of course) bought and played TONS of hours of Minecraft, really more than I care to recall, and had lots of fun. My development of "something similar" continues and is documented here...
- Lighting is in a good state now, with edge cases working.
- Started working on water flow and shader.
I've been away from Sandblox for a long time now, mostly due to the job that pays the rent i.e. being a part time high-school teacher. This semester that job is down to 40%, so hopefully there will be much more nornware stuff going on in the coming months. I also got frustrated early this year with the performance issues of constructing Chunks; it just wasn't real time anymore, and that stumped me for a long time.
After a while I stumbled across the concept that Minecraft has of "sub-chunks", and for a long time that was priority one on my list of things to try out. I finally got around to it just this week; I don't have sub-chunks per-se, but now Chunks are 16 x 16 x 16 instead of 16 x 128 x 16. This is obviously 1/8th of the work previously required to build an individual Chunk, but the tradeoff is more objects in memory and above all more draw calls, as each visible Chunk is built and rendered as a separate mesh. I am however confident that better culling (my implementation is very arbitrary right now) will allow me to manage this.
Interestingly enough this has me back to my original Chunk size, which I had in version 1 of this codebase (the current version is 2). The big difference is that the current lighting is a whole different paradigm, and things in general are more optimized. Also this change has made the whole implementation generalized in all axes, so the world could (granted we can draw enough visible Chunks, which of course depends on view distances) theoretically extend in all directions, even up or down. I am however limiting "valid Chunks" to only be from 0-7 in y, but this is just arbitrary.
Switching to several Chunks in the y-axis did however break the way that the sky/sun light worked and made the problem itself more complex, so that is the next major hurdle. After that I also still need to figure out a way to have light bleed across Chunk edges. After that I will finally have a relevantly stable base to start working on world functions and gameplay elements, and thereafter getting some kind of build out there for people to play with.
- BloxWorldFunction4: Ruins.
- BloxWorldFunction3: Light falloff is implemented, as well as colored lighting.
- BloxWorldFunction1: Another example of colored lighting.
- Lots and lots of good optimizations of Chunk and mesh construction today, with more to come.
- The light falloff worked out better than expected in the end, even though there is no compensation for the bad edge cases; lights cannot currently spread across Chunk edges, and these artifacts are sometimes visible.
- At this point I feel like I've achieved a reasonable lighting model that looks good enough for my tastes and purposes; ambient occlusion is in there, and the way the light spreads looks reasonably like a bounced / global illumination solution.
- BloxWorldFunction2: I added a building construction site generator.
- BloxWorldFunction3: A desert which I like a lot, using simplex noise to offset a simple gradient density function that places the "ground" in the middle of the world, the effect of which is scaled using another global simplex noise function that is pow()ed a bit to achieve the super flat deserts.
- BloxWorldFunction1: An above ground shot of the "epic cave" function.
- Here I've created a basic heightfield world and subtracted some simplex noise to create epic cave systems.
- I'm really digging Ken Perlin's simplex noise; not the same as classic Perlin noise, but quite fast and useful in this context. He even has a 2d version which really helps save cycles when you only need 2d noise.
- All kinds of optimizations at this points in order to get both the logical and visual Chunk generation to run as fast as possible.
- I'm actually currently running on std::map, something that I historically have never done.
- The ambient occlusion lighting is back, this time a more efficient version than the legacy one; I've written tons of lighting models for Sandblox, and have learned a hell of a lot of nifty cheats.
- I have isolated the concept of a "blox world function" in order to try out different approaches to procedural "stuff" generation, i.e. not necessarily just noise based terrain and the like.
- Here the Chunks can be seen, as each "lot" is a single 16 x 128 x 16 (xyz) Chunk.
- I'm using a noise function as a "building selector", and from there delegating to a different object to create a building, a construction site, or a park..
- I have implemented a "blox" version of the infinite world.
- The lighting here is very temporary.
- Started running into some serious performance issues related to both logical Chunk creation and mesh building.
- A very major refactoring of my entire codebase happened here as a result of the way I'm doing the local coordinate systems for the Chunks; basically I removed the implicit conversion of floating point vectors to integer vectors. This set me back by about a full week of getting things to compile, making case by case decisions of tons of float to int conversions...
- Back on this... :)
- Working on generalization of the "infinite world" code for the purpose of implementing several different kinds of worlds
- I'm betting that I will feel very different about the whole thing once the worlds aren't limited in size, as exploration is a big deal for me.
- Here is a completely procedural world based on fractal noise and marching tetrahedrons.
Here's a summary of my current thoughts about this project.
Work has been done since the last screenshots on alternative (mainly faster) lighting models that can handle ambient occlusion, a sunlight from above, as well as point lights in some form. This has proved to be one of the main stumbling blocks, as the requirement of pseudo-realtime Chunk mesh generation is central to all of this.
Sandblox as a level editor
I think in general that the granularity of using blocks in this way to build levels is very productive and a good trade off. Indeed Minecraft itself is really a glorified level editor. The techniques used are also similar to Quake-style games, in that texture mapping is automatically associated with Materials, as well as lighting.
Several more Mesh types (per Material) could be implemented to further embellish the look and types of geometry in the world.
Where to go from here?
The project has been SEVERELY hampered by a lack of vision. The technology has arrived at the point where further work needs to reflect the needs of a specific game idea, and such an idea does not exist.
I also firmly believe that my tendency to want to make the world look "cooler" and / or "more high tech" has led to a lot of technical issues that in themselves are sufficiently complex to upset the development of the technology into any specific game. This is a trend that I have observed in very many of my projects.
- Colored Material lighting.
- Also various experiments with how to combine the specular / environment pass with the new lighting.
- Procedural foliage placement in the infinite heightfield world.
- At this point I also abstracted collision detection in the system, so that avatars could run around on the heighfield.
- I was and am very interested in the completely procedural aspects of this kind of stuff; to be able to wholly or in part avoid having to manually design levels / place stuff in a world is very compelling.
- Back on track here, working on point lights emitted from Materials.
- Various different mixes of point lights and ambient occlusion.
- Another major tangent; an infinite heightfield world based on fractal Perlin noise.
- Textures are projected based on normals and blended together in various ways.
- Normals are generated using D3DX on a per Chunk basis, so there are visible issues at Chunk borders.
- Here Materials were expanded to be able to handle images that were wider than a single block.
- This enabled more complex looking surfaces, as well as hiding the blocky tesselation a bit.
- A new Mesh type (Diagonal) is also evident here, also intended to allow for further types of geometry in the levels.
- Yet another tangent; integration of BlendMeshes to test and some gameplay ideas.
- Various new tools implemented at this point, including projectile tools (for shooting-style editing) and projectile weapons.
- Some enemies as well.
- Another tangent here; a generic terrain generation scheme using Marching Tetrahedrons.
- This was a completely different dataset (distance field) and thus incompatible with the rest of the game (avatars couldn't intersect it).
- Here a bit of a sidetrack; a new Mesh type called Smooth which uses the regular grid dataset but attempts to tesselate it using Marching Tetrahedrons.
- Mesh generation was further complicated (and performance degenerated) by this, and the limitations of using vertex lighting also became more apparent in this context.
- No ambient occlusion on Smooth Meshes at this time.
- Example of indoor lighting.
- Even more complex lighting, including shadows from an above "sunlight".
- The ambient / shadow term is constant, which means that any kind of indoor stuff is quite flat apart from the ambient occlusion.
- Integration of more textures / Material styles.
- The fractal terrain after a collaborative editing session.
- Basic ambient occlusion has been implemented her as well, which introduced some problems with the performance of Chunk mesh generation.
- At this point all multiplayer testing sessions halted as a direct result of the problems with mesh generation performance / lighting.
- Terrain generation based on fractal Perlin noise.
- Another early multiplayer session, where we tested collaborative editing.
- One of the very first multiplayer sessions.
- The basic networking architecture is very Quake 3, i.e. state streaming. The challenge was to get the Chunk data compressed down to a MTU of about 1500 bytes, which was achieved using ZLIB.
- An underwater view, where you can see the addition of a kind of specular / environment mask on the Materials.
- By this time Mats Persson had gotten his hands on the graphics and done some nice updates to the basic Materials.
- I probably had the basic avatar / physics implemented by this point, as well as a water Material (1).
- The decision to move to 24 x 24 texel blocks was made due to the fact that Bloom / SABK / Saerfus use this format, and thereby there was a bunch of nice blocks that could be reused.
- I had also added several types of Mesh types for Materials, as you can see in the simple crossed quads used for flowers and similar.
- A more elaborate skybox here as well, with the addition of an ocean plane.
- I initially called the project superCUBES.
- The world size was fixed at 256 x 64 x 256 (x, y, and z respectively), and each block stores a byte of information. This byte directly corresponds to a "material", thus 256 Materials total (including 0 which is air / empty).
- Basic terrain generation was based on particle deposition.
- The world is rendered in Chunks of 16 x 16 x 16 blocks.
- Basic editing was at this point implemented in a similar style to Minecraft, but there was no avatar and you just flew around editing stuff.
- Texels per block were initially 16 x 16.
- The skybox is borrowed from Counter-Strike.