My first post-engine stop was to start expanding the terrain generation. Different parts of the world exhibit different climates and these influence the creation of the geometry itself. For example, deserts appear in hot, dry areas. Rainforests, volcanos, mountains, tundra, caves, forests and grassy plains also make an appearance in their appropriate climates.
Towns, temples and corrupted areas will also appear in the world, but I will be covering those at a later stage as they integrate more deeply into the core gameplay.
For many months I’ve been working solely on the game engine, getting it to a point where it will meet my visual, audio, performance and networking needs for the game. As of the previous game update/patch in Feburary, I feel I have accomplished this and thus it was now time to start working on the core game experience. While I loved every moment of developing the engine - and that work will never be truely finished - I recognised that these were not changes that anyone outside of those working on the source code (little old me) would find interesting.
As I’ve reached the gameplay and content generation part of this project, I hope to be posting more frequent and interesting updates. Anyway, this is too much text and not enough content, as is starting to feel a little like I’m at school crying “the cat at my homework” (we never had a dog), so I’ll shut up and go snap some screenshots.
Occasionally I am asked if Kleaveland is a voxel engine. It is not. To be honest, I’m not even sure what it is! A kleaveland world is effectively infinite in size, and the horizontal space is divided into discrete 64x64 unit regions. Each of these regions contains a list of blocks in order from top to bottom, sorted by their top heights. Each block is defined by a top height, a bottom height, a list of vectors forming its shape and some extra metadata for properties such as the material type. The data for each block is highly compact and fits into a few bytes. This is in contrast to a voxel system which stores world data in a fixed size array, with each element representing a fixed sized cube of geometry.
The kleaveland system has some advantages over a voxel system. Primarily, individual blocks may take on any size or shape. They are not limited to just cubes. Secondly, the storage requirement is vastly reduced. A wall 10 blocks long and 4 blocks high can be stored by a single block, whereas a voxel engine would require 40 voxels to store the same area. As a bonus side effect, kleaveland can support tall worlds (4096 units) without any extra impact. The kleaveland engine is only storing what it requires and thus maintains a very low memory footprint.
By choosing not to use a voxel engine, Kleaveland is missing out on one of its primary benefits - lookup speed. It is very fast to check the contents of a voxel. In a voxel engine, the entire world at its most basic level is a giant 3D array. Lookup times in arrays are very fast, and Kleaveland does not have this luxury. To counter this, each region of the world indexes its blocks in a few ways - forward, reverse and ranged indexing. Forward and reverse indexing allows the engine to quickly find blocks which have a certain top or bottom height. Ranged indexing is used to find which blocks overlap a specific vertical space. In practise this has worked well.
When generating the visual representation for a region of the world, the engine scans the region from top to bottom and determines which block faces are visible. Lighting is also propogated during this process, and thus it can be an expensive operation. For very complex geometry, this operation can take well over 100ms. Although this occurs on a separate thread and thus doesn’t cause a noticable pause, experiencing any form of delay after placing or digging up a block is unacceptable in a game with a heavy focus on these operations. Thus a workaround was needed. The original solution to this problem worked as such:
When placing a block, a seperate temporary representation was rendered until the world had time to update.
When beginning to dig a block, the results of the dig would be calculated in advance. When completing the dig, the current visual data would be swapped out for the pre-generated results.
The system was ugly but it worked. Howver it fell apart when player the digging time was reduced, as there wasn’t enough time to pre-generate the finished results in advance. It also struggled to hold up in a multiplayer environment where multiple players are influencing the world at the same time.
Recently this system was ripped out and replaced with a more robust client prediction system. Now, the client stores some extra information for the world directly around them. This extra information includes detailed lighting data and offsets to the existing render data. When a block near the player is modified, the engine only needs to regenerate a small visual area and then stitches it back together with the existing data. Lighting does not need to be propogated (except for within vary small areas like a dug out block) and the whole process is very fast. This extra stored information is rather costly, so it only exists for the areas immediately around the player. Areas beyond this range will not be updated instantaneously, but as the player is not directly interfacing with these areas such a delay should go unnoticed. Finally, this new system is much more multiplayer friendly. A list of modifications can be stored and executed on the client while working in harmony with any updates that are received from the server. This should vastly improve the multiplayer experience.
Up until now, all lighting has been static. It is recalculated when the nearby world state is changed and then the lighting color is baked into the geometry itself. I use the alpha channel of the lighting attribute to store the sunlight separately from the raw red/green/blue values which represent the static lighting from other sources. This was done so that the transition from day to night is can look smooth and so that it can occur without having to recalculate any light data.
This video demonstrates the latest change to the lighting system. I am now generating shadow maps based on the sun’s current angle. The sunlight angle in the clip is being adjusted manually, but in the next patch this will be tied to the angle of the sun. This angle will change smoothly throughout the day/night cycle. As I am storing sunlight separately from other light sources, I can apply these shadows with respect to the light from the sun only.
Shadows from static lights pose another problem. As it will be too expensive to have dynamic lights for every player placed light, I will likely add a single fixed static shadow map below entities with respect to the static lights.
Shadow mapping will be an optional feature as it one of the more GPU intensive features of the game engine.
The game engine is now stable enough to open up some limited public testing. If you would like access to Kleaveland to play and test both singleplayer and multiplayer features, please visit http://bensgames.net/alpha/register.php and register an account. You must verify your account via email to enter the queue. At present I am only accepting a limited number of testing accounts. Please allow some time for the accounts to be activated.
Some time has passed since I last posted a video, so here is one of the updated block system in action. It demonstrates what I feel will be a nice balance between immersion and flexibility going forward. The original building/digging system allowed you to specify a 3D volume of space which could either be filled with a certain material, or removed from the world. This felt more like a world editor program and less like a game. I then transitioned to a simpler block placing interface, in which building and digging operations felt more “hands on”, but some of the flexibility was sacrificed.
In the above video, I combined these two systems. Blocks are placed and dug up/collected using the latter of the described systems, but there is now the option to define restricted building/digging areas or if you prefer, clipping zones. These zones are drawn by the player in the 3D space, and while active, all block placing and digging actions will be contained in this space.
The textures and style of the game as seen in the video is a placeholder. I will be taking this is a very different direction soon.
Another engine aspect I have been working on is a concept of ‘dynamic meshes’. These are 3D models than can have randomly defined attributes, and these attributes will modify the shape, sizes, colour, texture, etc of the model. Models can also be pieced together randomly from several sub components. The mushrooms in the above video are an early, simple test of this system - although different sizes and shapes, they are formed from the same model resource. This will be used to generate the various items and monsters which will populate the world. This is my current focus and will be demonstrated in future videos.
Testing infrastructure is in place and I will be opening this up to everyone for free shortly!
I’m currently working on the inventory system for insert-game-name-here, hopefully there will be another video next week. In addition to the paper doll slots for armor/rings/sneakers/dentures(?), each numbered keyboard slot (0-9) has a left hand and right hand slot which you can assign items to independently. Swords, shields, spells and items only require a single slot, and thus you can dual wield. Left click uses the left hand item, right click uses the right hand item.
The same item can be assigned to multiple slots, so for example you could have the same sword in the left hand for both slot 1 and 2, a shield in the right hand for slot 1 and a torch in the right hand for slot 2. You could switch between throwing down torches and blocking with your shield, all the while attacking with your sword.
Raw building materials, digging tools and two-handed weapons will fill both hands. In these cases, the right mouse button will perform context based actions, such as selecting the shape to form when placing materials.
The items will be randomly generated (including the mesh to an extent) and will vary greatly in stats. Items can have passive boosts to your stats, as well as varied damage/armor values. Digging tools (your bare hands, pickaxes, chisels) will have their own properties such a digging speed and the materials they are capable of destroying. Items will be found in dungeons, which will be the primary focus of this game. Expect multi-level sprawling dungeons with puzzles, boss fights, secrets and loot.
I’ve made the decision to leave out any form of leveling and player attribute system. All attributes will be determined by the gear you have equipped. A magic user will wear rings and armor which adds to their magic stats, a warrior may opt for high armor and speed values in their gear. There will always be better gear than what you currently have equipped. This decision was made due to the nature of the world and the multiplayer experience. If you invite a friend to play in your world to help you tackle the next dungeon, you don’t want them to be levels behind and unable to assist. Instead, you would kit them out with a spare set of gear you’ve stashed at your base.
Here’s a video of a little wooden shack I’ve built. I’ve re-worked the sunlight to a point that I’m happy with it. Sunlight is capable of bouncing around interiors as is evident in the video - some natural light makes it down to the basement. Point lights (such as the torch I placed) rely on line of sight at present, so shadows form when geometry blocks the light. This needs some work.
The pine tree I trim at the start is made from the same block system as the rest of the world, with some leaf entities attached. These entities can exist on any floor, ceiling or wall surface and will be used to represent any static details in the world as well as player placed decorations.
The interface I use to dig holes in the world will be changing. I plan to release a free engine test in the not too distant future, so thanks for watching and please stay tuned!
The texture pack is the excellent PureBDCraft by Sphax, used with permission. It can be downloaded for Minecraft here: http://bdcraft.net/
Let there be light! I was getting a bit sick of the eternal day time in the world, so what better way is there to test the point lighting system than to destroy the sun itself! Eventually a day/night cycle will be implemented, and the ambient light from the sun/moon can be tinted a colour. In this shot, the moon is lighting the land with a low intensity blue light.
To test different coloured point-based lights, I added coloured mushrooms to the world generator and gave them some light emitting properties. The torch on the pole was player placed, as were the stone walls.
Light from the sun/moon bounces its way around corners and can light a house quite well through a few windows, where as point-based lights use line of sight only and will create more varied lighting.
Shaders have been implemented, so dynamic lighting will be possible. I’m really focusing on performance (currently getting a solid 60fps on my old macbook pro, and thats with the framerate cap on), so dynamic lights will only be used a few situations where it would not make sense bake the lighting data into the world geometry itself. Examples would be a light source carried in your hand, or temporary lighting from a spell or explosion.
Another video will be coming in the near future. Honest. Until then just convince yourself that the above screenshot is a video of infinitesimally short length.