This blog has started a short way into development of King under the Mountain so I’ll use this post to bring you up to speed on where we’re at.
For those interested in the technologies being used, King under the Mountain is written in Java using the LibGDX framework. LibGDX allows you to cross-compile your game for deployment on many different target platforms, so a port to mobile/tablet is a possibility in the future but for now the project is aiming at PC only. LibGDX is also a wrapper aroung LWJGL, which is a lower-level library and the one used to most notably create Minecraft.
The very first “working” version of the game was to get the concepts of the 2D world and “walls” working correctly. As I’m drawing inspiration from Prison Architect and a lot of older tile-based games, of course the game world in King under the Mountain is tile-based. The very first problem to tackle was the fact that as the game involves digging into the side of a mountain, I do not want walls next to each other to look like this:
However *not* rendering the walls as above means there are many more different “layouts” of walls possible. I realised that for any given tile, its 8 neighbours may or may not be a wall tile, each of which might affect what the layout looked like. Something like:
Which means the presence of a wall (or not) in a tile’s 8 neighbours is binary information across 8 cells – otherwise known as a byte! Okay, so there’s 256 possible “different” layouts of a wall in a specific tile? Not quite, for a start any neighbouring walls in the corners that themselves are not next to another wall in the grid (for example, if there was a wall at 2 but not at 1 or 4) do not affect the layout of the main tile at T. Furthermore, I’ve drawn the walls in such a way that they can be flipped horizontally, so a bunch of layouts could be discarded by flipping their “reversed” counterparts. This meant instead of 256, I had 30 different layouts to draw:
The numbers in the filenames correspond to which of the original 256 different layouts these map to. Armed with these images (and being able to flip them horizontally), I could write the engine to draw any possible layout of wall tiles.
Note that the video is also showing frustrum culling (trimming tiles outside of view, modified to be within the edges of the video for demonstration purposes). Much more recently, I made the breakthrough realisation that if I conceptually split up the wall sprites into 4 quadrants, any of the possible wall layouts can be rendered from a much smaller set of sprites. A bit of wizardry later and I managed to reduce the 30 layouts above to a much more manageable 5, which will be a massive boon in reducing the art workload! Even better, this means that no confusing horizontal flipping is necessary, which was the real driver for this change to allow me to tackle bump mapping (detailed in a later blog post) without requiring a crazy amount of resources.
After this I decided to tackle the “floor” sprites. Often in tile-based games, where different floor tiles meet they have a special sprite to show the transition from one type of floor to another. For example, in this excellent tileset from Lost Garden, most of the tiles are actually dedicated to where different tiles overlap on each edge and corner.
I decided I’d like to do something a bit more dynamic using alpha-blending, primarily to cut down on the amount of artwork required, but also to allow for effectively any kind of flooring to overlap another, if required. After drawing some rough transparency masks, and getting to grips with shaders, I managed a quite performant renderer for blending any set of floor tiles together as shown in the next video:
A little more work to ensure everything was data-driven for easy modding and I felt I was done with this stage and ready to tackle something a bit bigger – lighting and shadows! What kind of game about exploring exploring underground would be complete without an evocative lighting engine? A lot of research later and a few personal brainwaves and I’m currently in the middle of implementing it as the next system – hopefully to be detailed soon in the next dev blog!