It’s been three years since The Skeleton War was released.
Why a new dev blog now, you ask? Well, I’ve had a whole bunch of images and notes from the development process sitting on my computer since the game’s release, and it’s long been my intention to compile them into a proper narrative around the game’s development. With the game’s third anniversary behind us, and with the team long since moved on to other endeavours, completing this dev blog offers a nostalgic trip down memory lane for me and hopefully an interesting tale for everyone else.
Another reason to post this now is because I want to release the game’s soundtrack in an accessible form for the first time (192kbps MP3s), so the link for that will be at the bottom.
I mentioned in the last dev blog that I’d be focusing on UMG (Unreal Motion Graphics) next. I won’t do that, because Unreal Engine is now up to version 4.20 and The Skeleton War was built in version 4.8. Mathematically, 4.20 might be less than 4.8, but in terms of software patches, that’s 12 major releases since I worked on the game – meaning anything I write about UMG will likely be outdated and you could find better articles on it elsewhere. So instead I’ll be talking about the game itself and its journey from an idea to a published product.
Still with me? Alright then, let’s get started.
The Skeleton War was created by a team of six people. We would figure out our precise roles as time went on, but in general terms the team was comprised as follows: Zanda (artist/modeller), Taygen (artist/level designer), Pav (producer/project leader), Chris (programmer), Jake (programmer), and myself (Julian, programmer).
From the outset we knew we wanted to make a game about skeletons. And skeletons, in their supernaturally necromantic nature, are highly modular. I mean, what game have you played with skeletons where they haven’t had limbs flying everywhere after a hit or two? Knocking apart grinning skeletons was always one of my favourite moments of Oblivion’s and Skyrim’s gameplay.
So if these supernaturally-animated skeletons are so easily blasted apart, why not allow them to be put back together as well? This was the core idea that founded our game: the idea that, as a skeleton, players could lose and reattach limbs as much as they like all in the course of a single skirmish. We also knew we were aiming for an October release, so the proximity to Halloween would bolster our marketing efforts.
The implementation of this core idea varied vastly between the beginning and end of production. Our earliest prototypes for the player skeleton and the abbey/graveyard environment looked like this:
As you can see, the first skeleton model had a blocky, chunky design. Human skeletons in real life are actually quite spindly things and wouldn’t do at all for our purposes, so we got creative. The skeletons needed to feel weighty as you ran around, like you could withstand a few hits and keep moving.
Meanwhile, the level design was inspired by gothic architecture, cathedrals, and graveyards, which ultimately led to an abbey being chosen as the location. Mock-ups were made, sketches were drawn, and buttresses were erected for our very first abbey prototype. I personally liked the aesthetic of this initial prototype, however the artists ultimately decided to cut it down to a more compact structure that we could feasibly texture, collision map, and decorate in the time we had.
We also wanted the map to be suitably spooky, which of course meant it would take place at night. The following sketches were early attempts to capture the tone of the level:
Alpha (not the apex predator)
By the time we entered the alpha stage of development, we had a map like this:
And the other side:
And just for fun, one more shot taken after a particularly hectic testing session:
There are a few obvious differences between this iteration and the final map: no paths, no lanterns, no modelled grass, no fog, and an early iteration of the player scoreboard and nameplate, to name a few things. The stone columns and platforms providing an external entry point to the second floor were later removed because our movement model didn’t really have the fidelity for precise platforming, so no one used them in the midst of a battle anyway. And the fallen columns forming a staircase were later replaced with a hollow log (more on this later).
But the general layout is there; the abbey structure itself is there, the trees and fences are there, the spawning tombs are there, and for the first time we could actually run around testing out the gameplay.
Speaking of which, at this point in development you had infinite bombs, so a viable strategy was simply to sit on top of a tree and throw bombs down at everyone. Fun for that one person, but not terribly fair for everyone else.
Holy HUDs, Batman!
Now, showing the level’s evolution over the course of development is all very well and good, but for me, most of the time, development involved looking at a wall of code or blueprint graphs. At their best, blueprints are a joy to work with, and they allow all the game logic to visually make sense (like the Throw Bomb function shown in the previous blog). At their worst, they can look more like this:
This was the logic behind the old HUD system (the purple text and web you see in the prior screenshots). In a nutshell, all those little green nodes are values (like screen width, spider Y position, score font size, etc.) and all the larger rectangular nodes with blue headers are draw commands – the functions that actually make things appear on the screen.
Here was the end result:
Notice that this early HUD was almost entirely text-based, because working with images was painful in blueprints. Hence not only was this approach messy, repetitive, and a pain to modify, it wasn’t as pretty as a HUD which incorporates more graphics into its design.
Consequently, I ended up redoing the entire HUD using Unreal Motion Graphics (UMG), which includes a handy visual designer a bit like using WinForms or JavaFX. This was the end result:
Wooden panels hanging on chains now display the players’ names and scores. Much prettier. (The orange backdrop was our rudimentary photo booth for creating some of the menu graphics.)
This is the game’s options menu here, just to show you what UMG looks like behind-the-scenes. The HUD is split up over numerous widgets and hence less interesting to look at.
UMG has a bunch of pre-defined controls (like labels, text boxes, buttons, etc.) that you can drag in, manipulate, and animate. One of the major drawbacks with it though was its very primitive support for controller input.
Playing with a controller was a big requirement for us – it’s a party game, and the controller’s rumble when you take a hit or knock off another player’s limb plays a big part in making those interactions feel weighty and satisfying. And if we wanted to support controllers in-game, we obviously had to support them in the menus too. This led to countless hours of frustration for me (as the resident UI developer) getting things to work as players might expect. Cycling through buttons in the correct order, applying a different style to highlighted buttons, auto-selecting the first button when jumping to a new screen, supporting message box pop-ups, all that stuff we take for granted in game menus. Unfortunately, none of that came out-of-the-box with this early version of UMG. And when you’re on a tight schedule, the last thing you want to do is drop an indefinite amount of hours on something that players won’t even notice. But you would notice if it didn’t work, so I persisted.
As the menus slowly shaped up, the map underwent numerous iterations large and small. Grass, fog, and lanterns were added. Another two bomb spawns were added. Area sounds were added (mostly owls hooting). The inaccessible outer border of the map was extended and a giant moon was dropped into the distant sky.
Our skybox didn’t have a moon, so instead of re-texturing and re-animating the whole skybox, or figuring out how to sync another layer to the existing one, we decided it would be quickest just to place a giant sphere outside the map. Plus, I think it made for a cool effect, seeing the moon so close.
Speaking of the skybox, I also made it my mission to make it slowly transition to day as the round neared its time limit, making the sky lighter and eventually casting rays of sunlight across the battlefield. Being creatures of the night, this signals an abrupt end to the skeletons’ shenanigans and gives a nifty in-world warning that the round is about to end, along with a change in music.
As mentioned earlier, the fallen columns acting as a stairway into one side of the abbey were also replaced with a hollow log. This was so that places without legs (e.g. from being caught in a bomb explosion), who move slower than legged players, could escape a pursuing player without having them follow.
To prevent those leggy players from simply jumping on top of the log instead, we added a bit of level design trickery: invisible walls that players only collide with from the sides and not the top.
Two further changes were instrumental in creating the final level’s atmosphere: grass and fog. Neither involved a lot of work to implement, yet their effect was profound. Adding complex, swaying grass around the abbey elevated the environment from a rough, blocky, 90s-style arena to something that actually leverages a small part of UE4’s potential. And the fog, well, the fog made the art’s shortcomings less obvious. Take for example this comparison:
Not only does the fog hide some of the immersion-breaking implementation details, it makes the whole area more spooky and skeleton-friendly.
There were a number of small tweaks like this to lighting and post-processing that made a world of difference to the level’s atmosphere, which just goes to show that the biggest aesthetic improvements are sometimes the easiest to implement, and there’s always time for some final tweaking.
Yup, even our tiny little skeleton game has at least one Easter egg. Or many, if you can all the punny default player names, but I’m just going to mention two here.
The first: random epitaphs are visible on the back of each of the four crypts. These are partly inspired by random jokes found online (most of them originally penned by Spike Milligan), and partly written by yours truly. These are also randomised each round, so you probably won’t see the same one twice.
Alright, so this Easter egg regrettably did not make it into the final build, I think it’s worth sharing nonetheless. The idea was that every round there would be a tiny chance of a giant pumpkin spawning in the middle of the abbey. This could then be detonated by a bomb to specular effect.
Who says game developers don’t goof around?
Easily the greatest challenge we faced with the game was that of the multiplayer implementation. Or the netcode, as it’s more colloquially known. UE4 has great support for player replication out of the box... for ordinary player models. Our skeletons presented a problem because of their detachable limbs.
As the programmer in charge of network replication (that is, making everything look the same on every player’s screen), it fell to me to make sure arms and legs fell at the same time in the same place on the server and all the client machines.
The problem is that there’s not just “one right way” to code multiplayer. There’s a bunch of different approaches you could take, all with their advantages and drawbacks. Generally, you want all hit detection to take place on the client, eliminating annoying “but I hit you!” errors introduced by a high latency. The hit event is then sent to the server, which tells all connected clients to detach the appropriate limb and drop it to the ground. But the skeletons will all be in slightly different positions by the time they receive this instruction – not by much, but enough to make the limb roll to a different location. Then you could potentially encounter an issue where a player picks up a limb on their screen that’s several metres away from them on another player’s screen. So we decided to replicate the detached limb positions too, but this demands a lot more bandwidth since there are potentially a lot of limbs moving and rotating around at any one time, and UE4’s handy pawn replication logic is not optimised to replicate all these other bits and bobs.
Eventually, we settled for the limbs’ positions being replicated, but not their rotation. This is why if you play the game as a client (rather than the host), dropped limbs sometimes seem to be sticking in the ground at weird angles – but at least you can see them and interact with them.
Really, this represents game development in a nutshell: there’s not just one way of making something work, but many, and it’s about striking compromises between functionality, bugs, performance, and the development time need to make it all work.
We would have faced this same challenge again if we’d had time to optimise the game’s performance. I’m aware it runs fine on some machines but terribly on others with comparable hardware specs, and this is something which would have required many hours of testing and tweaking to solve. As it stands, I’m happy with the variety of graphical options I threw in to give players some flexibility in that area, but this could have been taken further with options like fog, grass, and shadow detail levels.
The level looks oddly pretty without textures. The performance gain is negligible, though, so I don’t think “Textures: off” would feature as a graphics option.
Best and Worst: A Retrospective
Playing the game now, there are a few things that stand out to me as things I’m proud of and things I wish we did better. I’m happy to say the former list is much longer.
Things I’m particularly proud of, replaying the game now:
- The way the camera moves smoothly back to the sky when respawning
- The blur and muffling effect of losing your head
- Bombs dropping at your feet when you have no arms
- Held bombs being physically shown on your belt
- The rising-from-the-grave spawn animation
- The little “tink” sound bombs make when they bounce off stone or metal (I recorded those!)
- The whole menu system – the sound, graphics, and responsiveness
- The variety of graphical options available – and the way it auto-detects your resolution (even 21:9, I just discovered! Many modern games don’t even support that ratio)
Things that make me cringe a little:
- For a game centred on melee combat, the melee combat just isn’t as satisfying as it could be. Skirmishes more frequently involve random wailing on the other player than purposeful swings
- Being multiplayer-only, its audience is somewhat limited – I wish we’d had time to implement some kind of single-player mode against basic bots
- The slightly-floaty running animation
- Our data collection server going bankrupt about a year after the game’s release, taking all our data with it – stuff like rounds played, favourite game mode, total player deaths, etc. – it would have been nice to see what sort of mileage the game got after the first month of release
By default, the game collects and sends off anonymous gameplay data which we can then view and turn into meaningful statistics. Unfortunately, the service provider we chose for this task shut down some time ago, so all we have is the data we collected in the first 10 days of release. Here it is.
Wacky Patch Notes
Most games have their share of odd-sounding patch notes that are all the more amusing when taken out of context. Given the unusual premise of our game, we certainly had a few...
- “Fixed legs removing head even when not attached”
- “Movement speed changed depending on number of limbs”
- “Made the owls slightly louder”
- “Fixed bombs not working without arms”
- “Limbs replicating properly again”
- “Tweaked bone sounds”
- “Legs can now also be attached to arm sockets though only if you already have two legs (someone else isn't going to like you very much)”
- “Fixed an issue where a player's head could remain attached momentarily after being blown apart”
- “Removed headbutt” (yep, you could headbutt at one point, but the animation never worked right
- “Don't play footstep sound for legs in arm sockets”
You didn’t think I’d forget, did you? Without further ado, I present The Skeleton War OST, finally available for your listening pleasure. It includes all five tracks from the game plus two bonus ones for good measure. I hope you like jazz.
Direct download: Indiedb.com
Once More into the Long Night
So that’s all, folks! I hope you enjoyed this retrospective write-up which was three years in the making. There are many more stories I could tell, but it’s all ancient history now and at some point you just need to let things rest in peace. (That point is three years later, apparently.)
My only hope now, as I imagine it is for all game developers, is that our game will occasionally be revived at the odd LAN party for years to come. I know it will at any that I organise.