William Roe’s blog

A variety of geekery

Ludum Dare 31 Postmortem

On the weekend of 6th December 2014, I participated in Ludum Dare 31. The theme was “Entire Game on One Screen”. I didn’t finish my game and didn’t hand anything in. This is the 3rd(?) time I’ve started but not finished a Ludum Dare game in recent years. The first time I participated in Ludum Dare, I completed a game and handed it in for the competition (48 hours), so I’m curious as to what has been holding me back since then.

Lack of planning

It was only after Ludum Dare was completed and I filled in a Trello board with the tasks necessary to complete my game that I realised the immensity of the project. I was reading Amy Hoy’s new book Just Fucking Ship and it emphasises working backwards from a goal to a set of tasks that need to be done. Hoy also advocates Mise en place style of working, which I’ve never identified as a thing before but it’s obvious in hindsight. Ludum Dare advice usually contains something about starting on paper, getting all the high-level details worked out before diving into code and that’s absolutely right. The other massive advantage of having a todo list (e.g. in Trello) is that it’s super easy to order the list of things in terms of what needs to be done and what is optional. Does it matter that the resolution is fixed at 800x600? Nope. But I’ve totally sunk hours/days into coding around the idea I need to have a scalable interface on the web for my games (and it’s always really painful).

Case in point - this Ludum Dare, I decided to use Elm, which was entirely new to me. The conventional wisdom has it that one should never learn tools while participating in Ludum Dare, just use whatever you have at hand (i.e. programming languages/IDEs/libraries etc. that you have used extensively before). I only make games during Ludum Dare though and I’ve never reached a level of proficiency with gamedev that I feel leaves me with a default technology choice, so I used a new thing. However, this time round, using Elm, the web game ends up getting drawn using the 2D canvas and image elements positioned on top of it basically. You can’t control a lot of how Elm does any of this and there was a minor wrinkle - there’s no way to use CSS’s image-rendering option to optimise for pixel art (crisp-edges is what you want - which is essentially nearest-neighbour scaling up/down). The result is you get blurry pixel art in your games and this sucks. It’s not at all a blocking problem for Ludum Dare games though and I feel silly for spending any more than 5 minutes on it.

Overly ambitious game design

I’m not a regular gamedev, this is something I do very occasionally. I’m a software engineer and therefore I completely and wildly underestimate the complexity and difficulty of programming tasks. Not to mention my total lack of ability to gauge time requirements. In the world of work, many of us software engineers avoid the near-impossible task of time estimation by using Agile-based practice and estimating complexity instead. It’s entirely based on teamwork and iteration of process and makes no sense for an individual working towards a goal on a deadline.

Aside: within the confines of Agile processes and teams, individuals can and do use more “traditional” time estimation and tracking tools to live up to their own expectations of themselves, so we do think “this will probably take half a day” but the discipline of working in an Agile team is never externalising that because it becomes an expectation and a commitment.

All my weaknesses as a software engineer aside, I made the fundamental error of dreaming up a cool game that was not within my reach of a 48 hour deadline. This is a completely avoidable self-imposed problem. The solution seems to be, sketch out the game in its entirety - all the objects in the game, all the components and all the behaviour. Make sure you have all the artwork at least approximated (I did this in Paper on the iPad because I could doddle on that while watching TV and it didn’t even feel like work). At this point you can identify elements that can be left out - think “what could I postpone if I was forced to launch this in an hour?” - or some other mind trick to force yourself to be ruthless with the scope of your game. One advantage of sketching everything on paper or in Paper on an iPad is that if time gets really tight and you don’t have super great pixel artwork ready - just chop up/scan in/photograph the sketches and use them as your assets. There will be people playing your game who think the hand-drawn nature of the artwork was a stylistic choice you made from the beginning and you know you ran out of time.

Onwards

So now I have a Trello board that makes it embarrassingly clear how unrealistic my game was for a 48 hour competition - where do I go from here? I think the best answer to that is to carry on with it, attack each task in the list and then realise the game is done (that sounds obvious but it’s impossible to realise when you’re ready to ship something unless you define up-front what you actually want to ship).

In Agile circles, we talk a bit about what it means to be Done. The “definition of done”, which can sound rather alien to somebody who’s not familiar with specifying that concretely. It’s essential to working progress otherwise you end up with tasks that linger on for days and weeks because they are quite simply never finished. Those aren’t tasks, they’re a waking nightmare. Sometimes there is no definition of done. This blog post doesn’t have a definition of done because I made an agreement with myself that I would write until I felt hungry then I would order some food. In Agile that’s usually called time-boxing and it usually isn’t hunger-based but might as well be. “Let’s time-box this for an hour” is a common phrase in Agile teams. It’s how you manage investigation tasks (otherwise they go on forever). We all need more, clearer definitions of done.

So Ludum Dare is over. I’m done with this blog post. I have plenty to practice and improve before next Ludum Dare and with any luck I’ll ship a game next time.

JSON for Humans

JSON is a fairly easy to read format but sometimes you need to deal with an unreadable dump of the stuff and it’d be useful to quickly reformat or prettify it. There are a number of ways to do this.

Javascript (Chrome, Firefox etc.)

Javascript has the JSON.stringify function, which can pretty-print JSON according to the number of spaces you pass as the 3rd parameter. For example:

1
2
var example = {user: {name: "Ada Lovelace", email: "ada@example.com"}, group: "programmers"}
JSON.stringify(example, undefined, 4);

If you try the above in a console in a web browser (or a Node.js console), you should see this:

1
2
3
4
5
6
7
{
    "user": {
        "name": "Ada Lovelace",
        "email": "ada@example.com"
    },
    "group": "programmers"
}

json_reformat

That’s all well and good, but relying on a javascript console is not the most efficient way to do things, so an easier and more scritable tool is the json_reformat command (part of the Yajl). To get this tool installed, do the following:

  • brew install yajl - OS X
  • apt-get install yajl-tools - Debian/Ubuntu Linux

Now you can just pipe JSON text to json_reformat and it will pretty-print it to standard output. This makes it very useful for use in other tools, such as vim. Here is some vim config for using json_reformat:

1
2
au BufRead,BufNewFile *.json set filetype=json
au FileType json setlocal equalprg=json_reformat

Now let’s edit a file that was generated by Berkshelf and has been spat out on the filesystem in ~/.berkshelf/config.json. Initially it looks like this:

1
{"chef":{"chef_server_url":"https://api.opscode.com/organizations/acmecorp","validation_client_name":"acmecorp-validator","validation_key_path":"/Users/ada/Work/.chef/acmecorp-validator.pem","client_key":"/Users/ada/Work/.chef/ada.pem","node_name":"ada"},"cookbook":{"copyright":"Ada Lovelace","email":"ada@example.com","license":"MIT"},"allowed_licenses":[],"raise_license_exception":false,"vagrant":{"vm":{"box":"Berkshelf-CentOS-6.3-x86_64-minimal","box_url":"https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box","forward_port":{},"network":{"bridged":false,"hostonly":"33.33.33.10"},"provision":"chef_solo"}},"ssl":{"verify":false}}

This passive-aggressive attempt by the machines to subjugate us humans just will not stand and thankfully we have the tools to take back control of our JSON configs. Position the cursor anywhere on the single line of JSON and press ‘==’, vim will pipe the buffer to json_reformat and replace it with the output of that command resulting in this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
    "chef": {
        "chef_server_url": "https://api.opscode.com/organizations/acmecorp",
        "validation_client_name": "acmecorp-validator",
        "validation_key_path": "/Users/ada/Work/.chef/acmecorp-validator.pem",
        "client_key": "/Users/ada/Work/.chef/ada.pem",
        "node_name": "ada"
    },
    "cookbook": {
        "copyright": "Ada Lovelace",
        "email": "ada@example.com",
        "license": "MIT"
    },
    "allowed_licenses": [

    ],
    "raise_license_exception": false,
    "vagrant": {
        "vm": {
            "box": "Berkshelf-CentOS-6.3-x86_64-minimal",
            "box_url": "https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box",
            "forward_port": {

            },
            "network": {
                "bridged": false,
                "hostonly": "33.33.33.10"
            },
            "provision": "chef_solo"
        }
    },
    "ssl": {
        "verify": false
    }
}

This trick with vim and json_reformat is one of the many answers to a StackOverflow question about pretty-printing JSON, there are so many more.

Tmux & Autoenv Tip

On OS X, if I use tmux (or more usually, wemux for pairing) then I end up with oddly named windows like this:

This is because I’ve followed the awesome instructions from Dr Bunsen’s Text Triumvirate and in order to have the tmux and system (OS X) clipboards interacting, it requires a hack called reattach-to-user-namespace which proxies the running of zsh in tmux.

One quick way to get around this and save time renaming my tmux windows, was to use autoenv and add a file named .env to projects with content similar to:

tmux rename-window "project-name"

This is piling hacks on top of hacks, but at least it saves a bit of time for frequently visited directories.

Tweet