48 hours to prototype an Ant Sim Game

gamedevludumdarejavascriptphaser

I gamejam-ed last weekend to the Ludum Dare theming "Beneath the Surface" (29th edition).

I enjoyed that time a lot. What changed from the previous Ludum Dare for me is that I'm now —and happy to be— a father, and I'm enough trained to wake up at 3am so I could be there attending the beginning!

This article is my diary of this incredible 48 hours past to develop "Anthill", a minimalist anthill simulation game. This postmortem will explain what went right and what went wrong for this compo.

The Game

I haven't played any Ant Simulation Game but I recently played a lot "Banished", an awesome city-building strategy game, and I was inspired by the "assign jobs to people" gameplay of this game.

Timelapse

Developing a complete game in 48 hours (including sleeping) is tough, especially that it is also about making the graphics and the music!

The game resulting of these 2 days is more a prototype than a finished game: the simulation remains minimalist and fastly boring, the food is the only resource you have to care about.

Here is a 300x accelerated screencast of the developement of "Anthill":

What went right

Music

Best achievement of my LD entry was –to me– making the music.

I'm not a musician, neither a pianist, but I played a lot with Audio the past year and I've managed to make a music for this game —and had a lot of fun making it. I've used my Yamaha P105 as a MIDI controller for making the game music and connecting it to SunVox, a modular tracker software.

Play the music - feedback appreciated

Most of the notes you heard have been recorded live from my hand, and I was quite proud of that, because I'm quite a noob on a piano. Doing that way, you keep some imperfection in the music (little delay on the notes, especially in the intro music) and I think that sometimes makes the music better.

I've talked a few times about SunVox, also I still want to make my own web version of a modular audio tracker that anyone (first myself!) could use and also could embed live in the game (and, for instance, having game variable impacting the audio experience).

Graphics

Also, I'm more a developer than a graphist so I would say this was a success^^

Using a library

I've entirely focused on making my game rather than making the technical stack. Usually, I tend to develop my own framework with the game. It is good to learn and discover some cool ways of programming a game but this time I really wanted to get things done...

Phaser.io

...so I've used Phaser which is a trendy and awesome framework. It is also built on top of the Pixi.js rendering library (I used in LD27) and p2.js physics engine, which are two brillant and performant JavaScript libraries.

Hopefully I started my project with a "Phaser template" I bootstraped during the previous warmup weekend. I've still lost some time playing with the Phaser API but I could have relied on Phaser features and performance so I think it worth it the second day.

Google Hangout with Ludum Dare friends

I used Google Hangout during the whole Ludum Dare, as a way to put my webcam in the timelapse, but more importantly to have other Ludum Dare friends coming in it!

This was a cool first experiment as an alternative to the "stream my dev" approach. It was quite fun and social to have @mrspeaker showing me his crazy Metal Meter game advancement.

What went wrong

Achievability

My initial plan was too ambitious. It seems to always happen with me: I get the first day a lot of ideas and motivation, and I tend to underestimate the work to be done. Then at the end of the first day, I'm frustrated to find out I won't have enough time to do all my plans. Indeed it is good to have a lot of ideas but, next Ludum Dare, I'll try to be sure to have achievable goals.

Next time, let's remove half the features I establish!

So, the second day morning, I've been replanning from scratch and reprioritize my features to basically have something finished and working as a game. Because of this decision, the result you can see is a game, but far from the one I originally wanted. This version is only about digging, collecting mushrooms and avoiding stravation.

Also I originally scheduled to work that way Day 1: developing-only, Day 2: music and graphics + new features. I'm not sure this approach can really works, especially it doesn't scale, we better work by adding complete features one after the other. That theorically works, but it is however difficult to apply in practice with the stress of the Ludum Dare countdown!

Path finding performance

Implementing my own path finding algorithm was fast but not optimal at all because of performances! I recently released a bugfixed version which just use an existing path finding library to fix my bad implementation and also to avoid an ant to request path finding each frame when looking for a task to be affected on.

Finding the good simulation parameters

I underestimated a bit the amount of work needed to find the good parameters of the simulation. Those are very important to make the game well-balanced (e.g. not impossible but also not super-easy), I don't think I found the optimal parameter in the released version.

I think I need two important things to make this parameter search easier:

  • a framework to maintain parameters presets and change them live.
  • make the simulation running at any speed to ease the development. (faster simulation)

[bug] A task is not always completed by the closest ant

There is a inconvenient proximity bug in my game that you may have noticed: when a new job is created, it may happen that, even if a ant was here nearby, a very far ant is assigned to this job.

I'm using a foreach ant in noJobAnts { findAntTask(ant,availableTasks) } loop. In this first approach, even if a ant will take the closest task in findAntTask, the first assigned ant will occupy the task even if a closer ant was after in the noJobAnts list.

Another approach to solve this issue would be to do foreach task in availableTasks { findTaskAnts(task,noJobAnts) }. In this second approach, the findTaskAnts should sort the noJobAnts list for the given task proximity.

However it is not that trivial because tasks also have different priorities for a given ant, and findAntTask solved that. In my original plan, there is some basic tasks like "clean the dirt" or "clean the corpse" which can be done by any ant. However, a specialized ant (let's say an Harvester) may have some more important tasks to be done first, so this is why we need this priority.

In other word, fixing this bug is not trivial and I need to find the optimal loop for that!

To be continued...

I really wish to continue this game because I enjoyed making it and I would enjoy playing the one I have in mind! Time will tell if I can accomplish that wish!

You can make games!

I strongly think anyone a bit motivated and inspired can participate Ludum Dare.

Whoever you are, you can make games!

  • If you are a developer, you can develop games easily! But that's not enough, you will require graphics and music!
  • If you are a graphist, you can make crazy beautiful games! There is tools to help you making the game without coding.
  • If you are a game designer or story teller, you can make awesome games too! You could also just make a cool text adventure game?
As a generative plotter artist, I use code to generate art (creative coding) and physically create it with pen plotters, which is itself a generative process – each physical plot is a unique variant. I love dualities, like digital vs analog physical, abstract vs figurative, orthogonal vs polar, photo vs noise,...