« plasticbottle.png | Main | fence1.png »

A world of images

Early on we decided that having a procedural world would provide us the best framework for crafting something on an MMO-scale within a year with only three people. Of course, being procedural brings upon many other problems, especially in a network game. Can you trust clients to generate the world for you? If no, then you server has a lot more work on its hands as it not only has to serve new landscape chunks to clients but generate new ones as players expand beyond the boundaries of the pre-generated world. Beyond the generation of the terrain comes the transport layer, or how the information will be passed on to the clients. Simply saving the terrain in a 3D file format, like an .obj, would be fairly expensive due to their relatively large size of such file formats. Even if compressed to "only" 400kb sending those files to a large number of clients would become a bottle neck real quick, requiring the server to have a lot of bandwidth.

Our solution to all these challenges? Images!

We decided on passing images for a couple of reasons. First, we were already using a heightmap as a lookup table for basic physics and allowing the player to walk on top of the terrain. Secondly, image manipulation is fairly easy to do with all the great libraries that are out there and the increasing performance power of GPUs.
Our first step, as seen in other posts, was to allow the client to generate the terrain based on the heightmap. The x,y positions on the image itself are used to correspond to an z,x position in world space. Then the red and green channels of the heightmap are used to determine the height. We use both channels because it gives us 65,536 steps of height as opposed to just using one channel which would bring us down to 256 steps. An important thing to note is since we're working in binary adding the extra 8 bits of the second channel brings us to 2^16 instead of just 2^8, which is what gives us such a fine control. One of the benefits of this system is that since the landscape is just a series of images it now becomes quite easy to update the game world. The image can be manipulated using the tile generation tool we created and new images can be pushed out to the clients as a patch while clients are playing, practically eliminating the wait time.

Once the terrain generation was working we decided that images could be a good way of sending other information too, like texturing detail and object placement. For texturing we use a simple shader which interpolates between four textures based upon the four channels of the texture map. For object placement we use the x,y position on the image as the z,x position in the world. The red and green channels are used to determine the id of the object. The other two are used for object rotation. The first three bits of the blue and alpha channels are used for y-rotation. The other five bits of each channel are used for x and z-rotation respectively. This provides us with a good amount of control in regards to placing objects while not needing another texture for other bit definitions.

One thing you might notice from the image above is that as of now we still have two unused channels in the heightmap. They are labeled as reserved because we have plans for these channels though we haven't determined whether or not we will have other needs for those bits. The future is full of color for Broken World. :)