Week of Awesome 5 – Post-Mortem

Well the 5th Week of Awesome Gamedev competition is over! It’s incredible to think that this thing has been running for half a decade.

So the way this competition worked this year is that there are four themes announced at the beginning of the week, which were: Chain Reaction | Alien Invasion | Assassination | Castles.  And each contestant needs to pick two of those and make a game around them, with a week to do so.

My game was “Invasion of The Liquid Snatchers!”.

The Idea

Straight away Chain Reaction and Alien Invasion spoke to me as strong themes that would go well together. I had vague ideas for the other themes too so I spent my 1st day conceptualising ideas for different mixes of themes and trying come up with a viable concept.

In the end I settled on an idea where the game is staged from the perspective of an alien species who are invading Earth to harvest its resources. You play by helping a handful of blue-collar (manual labour) alien minions to undertake the “behind the scenes” activities of an on-going invasion. Activities such as processing Earth’s resources or refuelling a wave of saucerships.

All of this would be driven by the use of the Earth-bound liquid resources that they had been collecting. Water, Magma, Oil and Nuclear Waste were the 4 resources that I settled on. From there I really, really wanted to try and manifest these using a real-time fluid simulation, because that just seemed like a novel and somewhat challenging thing to do – which is exactly the whole point of the gamejam for me: To push myself and do something different.

Each kind of fluid would serve a different function in the game: Water activates hydraulics (raises platforms or opens doors), Oil activates machinery, Nuclear Waste powers saucerships and Magma is supposed to be used by the aliens to forge saucerships.

The chain reaction theme would feature by way of the environment changing in response to these liquids (hydraulic platforms activating or mechanised gears rotating, etc). Most of those changes would be good and allow progression through the level but others would trigger “hazards in the workplace” such as having a row of missiles lined up to fall like dominos that end up crushing your minions!

What Went Well?

Let’s see…

  • Time – I had the week off work. Never done that for previous years where I’ve always worked during the week. So this year I had a lot more free-time in comparison. I didn’t spend it all programming mind you, but it was just nice to not have to hold down the day-job and then spend my evenings coding as well!
  • Existing code-base – From the previous two times I have competed I have built up a thin framework over the top of LibGDX which really helps me hit the ground running. Mostly it’s just resource caches for textures/sounds/etc and some ‘fix your timestep’ gameloop stuff. Nothing too fancy.
  • Shaders – My fluid simulation is rendered using a custom shader. I’m no shader expert having written a merely a handful of simple shaders in my time.Shaders cause(d) other people a lot of agro where their games don’t work on other GPUs, etc. For that alone I tend to avoid them generally. But this year I couldn’t, not for the fluid anyway. Fortunately I had very few issues with the shader authoring. I’ll write a bit more about how the fluid sim works in a follow up technical post.
  • Audio – I was able to find online several soundbite recordings of water sloshing around (each 0-2 seconds long). I picked several that sounded good and classified them into two sets: One for water being emitted and one for water being collected. Then to create the seamless sound of running liquid I select a sound snippet at random every 1 or 2 seconds and play it with sufficient falloff and overlap with the previous snippet while also making sure to never play the same sound twice in a row because humans are too good at noticing repeating patterns. It sounded pretty bad at first but after a but of tuning I’m quite pleased with the end result.
  • Art(?!) – As I say every year: I don’t attribute myself with much of any digital graphics design skills and I’m colour-blind which is a huge pain in the ass for this sort of thing. So I try to mask my artistic failings with code. But I surprised myself with the art work this year, it kind of works I think?! For the first time this is ALL my own art work, I didn’t take anything from the interwebs, I just used Paint.Net and a lot of it is drawn free-hand with the mouse.

What Went ‘Not So’ Well?

  • Liquid CPU performance – To begin with I simply assumed that performance wasn’t going be an issue in my little old game. I was wrong. It took some ingenuity to prevent the sim from becoming a bottleneck. Fortunately I have a copy of JProfiler which is my favourite profiler for finding performance hotspots. I’ll write more about that in the follow up post about the fluid rendering.
  • Level creation – In previous years I would implement an ASCII-based level format that gives a reasonable-ish approximation of how the level will look on-screen. The idea works ok for purely grid-based worlds but it doesn’t scale very well with multiple layers or when things are not grid-aligned. So this year I spent some time mid-way through the week to write a crappy in-game interactive level editor. Even with that I found it very hard to create engaging levels. And since my game is heavily physics-oriented I had to account for all sorts of “physics bullshit” in order to get each level to a point where it is deterministically solvable by the player and not just a big mess of physics stuff that may or may-not play out.
  • Box2D Determinism – It is my belief that Box2D is supposed to be deterministic (as long as the input is the same and the timestep is fixed – which it is). Yet I am definitely seeing slight variation from run-to-run. So I can’t explain that yet. I need to investigate what the ‘f’ is going on there. For this time around I just decoded to design around the problem.

Reception So Far…

So far I have had very positive reviews. First and foremost I’m very pleased to hear that people enjoyed the game.

Many/most of the criticisms I’ve received are about things which I completely agree with too, so no surprises there. I would definitely have fixed them where this not a week-long development. There’s just not time to do everything unfortunately.

It’s not known yet how all the judges feel as that still remains to be seen.

Riuthamus (one of the judges) live-streamed his play-through of my game on Twitch. It was hilarious! He actually found some pretty decent ‘alternative’ ways of solving one or two of the levels that looks to me every bit as good as my intended solution. So that’s fine by me! It was great fun to watch and valuable feedback too.

So How Does That Fluid Simulation Work Anyway?

One of the biggest compliments I’ve had is when people think the fluid simulation is a soft-body physics or a true fluid simulation. It’s really not 😛

I’ve decided to write up a technical article about the fluid simulation and rendering process which you can find over here.

That’s A Wrap!

I had good fun over the week and just want to extend a big thanks to the competition organiser (slicer4ever), to the other judges and to the prize-pool contributors.  They have all done a fantastic job at making this competition happen! Every year I see the competition evolve in very positive ways!

And good luck to all the contestants!

Week of Awesome IV – Gamut of Blob – Postmortem

Embarrassingly I haven’t used this blog in 2 years and that was for my WoA2 postmortem!

Well WoA4 is over and I am super pleased with my entry. It is somehow more complete and polished than I had anticipated to achieve considering I had a full week of work and a couple of weekend commitments that would see me Macbook-bound for the majority of the weekend.

This year announced 4 themes and contestants were expected to select and incorporate 2 of these for their game: Shadows, Evolution, Ruins, Undead.

A restriction was that Shadows and Evolution had to manifest as gameplay mechanics, whilst Ruins and Undead would need to manifest as graphical theming. Since I am no artist, it takes me a long time to produce art and I have no experience producing art of any kind on a Mac, I decided to opt for the 2 gameplay themes: Shadows & Evolution.

Scope is always an issue in any project. So I took the entire Monday just to let the themes sink in and try to come up with an idea that was appropriate in scope for the free-time I had. I was open to extremely simple games like Flappy Bird but I simply could not marry that up with the requisite themes (evolution, shadows, ruins, undead) in a way that enthused me. Also under consideration was a farming game where veggies are bred and transmuted to achieve a desired phenotype with a supply & demand mechanic driving that, as well as some kind of underwater game like flOw. Both interesting ideas but were too ambitious.

The idea I went with was top-down maze-puzzler with minimalist graphical look featuring cute little blob creatures. Gameplay-wise I was partially inspired by games like Chronotron or the Clank levels from Ratchet & Clank: A Crack in Time. In these games there is a way to generate multiple versions of yourself which must collaborate together to finish the level, things like standing on buttons to open gates. While I did not include their time-travelling mechanic I do have lots of cute little blob creatures running around standing on switches to banish shadows and allow fellow blobs to progress. Blobs can replicate themselves by finding DNA/gene fragments in the level; picking these up will spawn an evolved blob friend, each blob colour has a unique skill which allows it to access parts of the map that your regular unevolved green blob is unable to reach.

day6 (3pm)

The great thing about this idea is that it scales up/down depending on how productive I am: If things go well I can always develop new types of blob which enables new gameplay elements. If things go slowly then I can scale back on my ambitions for lots of different kinds of blob and focus up on just getting *something* done. My original plan included 5 types of blob:

  • Green – The standard unevolved blob
  • Blue – Able to swim and pass through water.
  • Red – Tolerant to extreme temperatures and can walk over lava.
  • Purple – Resistant to the genetic stresses of teleportation and can use teleport pads.
  • Yellow – Speedy, takes long straight paths very quickly and does not stop until it hits a wall.

I probably could have implemented all of these if I had sacrificed some polish but I didn’t want to do that.  In the end I managed all but the Yellow blob, not bad at all! And I don’t feel that the game has suffered at all.

One of the hard-learned lessons from previous years was that starting from a position of no code (just an empty main() method) is tough going. I end up spending a good 2-3 days just knocking out basic infrastructure (resource management, game-states, sprite-rendering, audio, physics, etc). So this year I prepped a very light-weight game-agnostic framework based on LibGDX to handle all that. This was a massive productivity boon and this ‘engine’ wasn’t at all constraining either having received only a minimal amount of frantic hack’n’slash near the end, which I will probably refactor and generalise for the future!

Something that didn’t work out as well I had hoped was the level file format. I used a similar format to my WoA2 game which worked very well for that game. However this time around I had lots of layers to the map and keeping them in-sync was an error-prone head-ache. Some kind of level-editor would have gone a long way to ameliorating this but there wasn’t time for that kind of development. Perhaps for next time I can generalise the concept of a tile-based level editor? Or learn to use an existing one and write an importer for its file format.

Overall, as usual, it was a lot of fun. Very tiring. But a lot of fun.

I have whizzed through playing the other contestants’ games (need to go back and play some of them for longer) and I have to say that I really do not have a good sense for where my game will place amongst them once the judging is over. As usual I am blown away by what people are able to achieve in a week!

Congratulations to everybody who managed to submit an entry. I am looking forward to next year’s competition already! 😉