2 years ago I started the development (and the development log) of a game, Moonman. It’s been a long time in development and so I think now is a good time to take a look back at some of the key features I’ve implemented. I hope to follow this up soon with a post about the future of the game.
Moonman is a survival sandbox game with a rich but hostile world waiting to be explored. The game is set on an alien planet that has no star — instead it is given life by the many exotic moons which orbit it. The moons affect the world in different ways and many of the creatures are aligned to one moon or another. The red goblin-like creatures, for example, are aligned to the fire moon, Agre. They chant to Agre, and when Agre rises they become enraged. Moonman procedurally generates a massive world to explore, full of interesting characters, ancient machines, forests, seas, and structures. It is heavily inspired by rogue-likes and sandbox games, such as Dwarf Fortress, Nethack, Terraria, and Minecraft.
Games such as Minecraft, Terraria, and Dwarf Fortress, demonstrate how powerful a modifiable block-based world can be. In this model the world is arranged into blocks of equal size, and the player is given the ability to ‘mine’ these blocks, optionally convert the type (e.g., wood -> planks), and then build structures by placing the blocks back into the world. With some intelligent world creating algorithms at play, the player is plummeted into a rich world full of undulating hills, cliffs, trees, ores, lakes, and more, which they can explore and modify at their will. I based Moonman’s world on this model, as I believe that it has a lot of promise beyond what we’ve seen already.
The engine in Moonman supports a block-based, or grid-aligned, world, using the fundamental unit of “grid cell”. The world supports two planes of blocks: the foreground plane, which contains the blocks that the characters can stand on; and the background plane, which contains “wall” blocks. (The wall blocks provide background walls for caverns or buildings, and have a minimal effect on the world.) The rendering engine exploits the mostly-static block-based nature of the world in order to cache and efficiently render the world. Only when a block is mined or placed does the renderer have to do a render pass, and even then it only updates a local 16×16 section of the world. This ‘render-on-demand’ is a necessary optimisation, as the world has the potential to be far greater than the available cpu or graphics memory. Grid cells are also used when modelling the fog of war system, the fluid system and the fire system.
Moonman is a 2D platform game — jumping, shooting arrows, and climbing ladders are part of the game — and so physics is an integral part. The physics engine in a game like this must support typical platformer physics and a world whose geometry changes as blocks are mined and placed. During my PhD I got experience with building physics engines and so my initial attempt was to build the engine for Moonman from scratch. This was not entirely unjustified as platform physics doesn’t behave like “real” physics (see for example this, this, and this).
Needless to say it was mostly wasted time, and as the number of edge-cases got out of control I decided to instead use Box2D – a popular 2D physics engine. In my devlog post you can see my first work for that transition. It took me over a full month’s work to pull out the old physics code and replace it with Box2D, primarily because I had to tweak Box2D in order to get satisfying platformer physics. Neighbouring world blocks are grouped into larger box2d boxes in order to speed up the simulation.
Water and Fire
Moonman supports water and fire — water flows and forms waterfalls and lakes, and fire burns blocks and spreads from a source. These two dynamic elements complement the static geometry of the world, and interact both with each other and with the world. They are also dangerous, as the player can catch alight or lose his breath underwater.
Developing this game has, at times, involved a lot of experimentation. The best example of this has been the water simulation code, which was written 3 different times. The first iteration was a particle-cell hybrid method, the second was a pure cell method that conserved fluid (like Terraria), and the third and current version is now a non-conservative cell method (it acts like Minecraft water). The current method is less “realistic” but it supports nice waterfalls and is a lot more fun. The fire system, on the other hand, was very simple to build.
From the beginning I wanted Moonman to be visually minimal. The great rogue-likes (Nethack, Dwarf Fortress, Brogue, etc.) all demonstrate how powerful a game using simple symbolic representations can be. Following the tradition of rogue-likes, I gave my character the smiley face found in the IBM PC character set. The mockup below shows my first design.
A few months later the game began to increase in visual complexity. The sprite and in-engine tests below show the style beginning to take shape. The emphasis shifted away from using pure ascii symbols to having simple shapes with blocks of colour; however, Moonman’s smiling face has persisted and now defines that specific character. The image below these shows the current style of the game.
Sprites and Animation
The sprite system in Moonman supports hierarchically constructed sprites. The moonman sprite shown above, for example, consists of at least 6 separate parts, the ‘head’, the ‘torso’, the ‘legs’, the ‘right arm’, the ‘left arm’, and the sword. Each of these parts has a set of animations that are played at specific times. For example, walking along the ground plays the ‘walk’ animation of the ‘legs’ part. The sprites are created and joined together in a custom sprite editor I built from scratch. This devlog post describes the editor, an early version of which is shown below (note the two parts “sword” and “body”, and the “man” sprite which joins them.) The sprite editor took about two full weeks to code, but has been a vital asset since, allowing me to rapidly create and modify sprites. This system supports attaching items to hands, attaching helmets to heads, placing shoes on feet, and swapping head sprites for creating variety in enemies, for example.
Light and Dark
I imagined from the beginning that darkness would play a key role in Moonman: exploring caves would only be practical if you had a torch; decorating your house with lanterns would provide mood; and, as the moon set you would rush inside, to avoid being prey for “inter-moon” predators. Implementing a nice lighting system, however, has posed a few problems. During development, I examined in detail the lighting system in an existing game and docmented my own experiments in my devlog, but could never settle on a final style. I have been through a few iterations and want to get it right, but currently I have disabled complex lighting (the torches just provide a little circle of light). Below you can see some of my experiments in modelling the flow of light in a scene.
And so much more…
Other features that have been explored and implemented include: climbing, buoyancy, water resistance, projectiles, items attached to blocks, an inventory and crafting system, different visual effects and shaders for different moons, a resource-loading system, a gui system, a profiler for testing the performance of the various sub-systems, a player-following smooth camera system, a component-based system used to model all the in-game entities, initial hooks for Lua scripting, and an efficient packed array system for storing and processing entities. In addition, I’ve been working with the talented musician Gio Lobato, who has been composing music for Moonman for over a year now. The music has been evolving steadily and we now have a set of tracks that paint an eerie alien ambience over the game.
Although the game is fun and has many elements, there is still a lot more work to do. The moons need to be developed further and many more creatures and items need to be designed. I have created a lot of background lore for the world and so need to tie that in with the characters, creatures and moons, to give a consistent setting for the game. Also on the agenda is simple machines and contraptions, such as pumps and bridges. The readers of my devlog thread plead for sophisticated walking houses (see below); however, I’ll probably delay this to version 1.1, due to its civil-mechanical-engineering complexity factor. There is a lot of work to do, and it’s been an adventure so far. But I look forward to releasing the beta of the game soon, so keep an ear out.