As promised in my previous post, here’s a bunch of stuff about the game I made for Ludum Dare 33. Minor, relatively vague spoilers ahead – play the game first if you’re going to at all, it’s pretty short.
Ludum Dare, for the uninitiated, is a weekend-long game development event. The idea is to make a game from scratch – design, code, graphics, audio, etc – in a weekend. To facilitate this, each event has a theme that is only decided on right before the event starts.
Ludum Dare is technically split into two separate but related events: the “Compo” is a 48 hour event which requires you to work on your game solo and has very strict rules about what resources you can use, and the “Jam” is a 72 hour event which you can enter as a team under far more relaxed constraints. The Compo requires submission of source code, and the Jam does not. I didn’t actively think about which one I was going to participate in before starting – I just happened to have a decent enough game by the Compo deadline and reasoned that having an extra day to work would be of no use when that day was a Monday.
I have one rule about entering these sorts of time-limited events: use a tool you know. Preferably one you can spin up a game in without consulting Google (for me, that’s GameMaker Studio). I broke that rule for this jam, and in so doing, proved it.
After the theme “You are the Monster” was announced, I spent a good few hours just thinking up an idea for the kind of game that would fit it. There are a set of very obvious ideas that come to mind: godzilla simulator, some weird reversal of a retro game like Space Invaders or Pacman where you play the invaders/ghosts or something in the vein of Execution (one game that needs no imitators). There’s also a Spec Ops: The Line angle to the idea, but in a weekend jam you barely have enough time to make a functioning game, let alone make one that functions well and uses that to subvert itself a few levels in.
So I decided pretty early on that I would be writing a text game, as a way of keeping the scope of the project manageable and also because I find rubbing glass shards in my eyes more enjoyable than drawing sprites. I wasn’t able to spend every waking minute on my game over the weekend, and it probably would have been a more complete game if I had, but everyone’s got things they need to do.
With my medium and tool decided on, I came up with this idea about the game being from the perspective of a haughty volcano god who demands sacrifices from the humans living next to his volcano and then went and wrote that. I had a few pangs of guilt about breaking my “no unfamiliar tools in gamejams” rule, but I figured that Twine wasn’t that unfamiliar and seemed really quite simple besides. What could possibly go wrong? It wasn’t as if I was using LD33 to start learning how to develop games from first principles in C++.
Well, things went well enough that I ended up with a game at the end of the weekend, but there were quite a few bumps along the road, owing both to Twine 2’s being fairly new and in parts incomplete and to my inexperience with the tool (though mostly the latter).
Ideas about the game’s structure evolved and changed during the making of it. I started with a vague concept, wrote some introductory passages to pin down the tone and voice, and then fiddled with passage connections and added variables as seemed appropriate. I’ve been a programmer for about half my life, so it wasn’t long until many variables and datamaps (hashmaps/dictionaries/key-value stores/whatever) seemed appropriate.
Twine’s main interface is a game map of square nodes (passages) and lines connecting them (hyperlinks), styled like a blueprint. So most Twine games look like complicated flowcharts. As an example, here’s the map from this randomly selected retweet by @twinethreads:
Contrast that with the map of I Hunger, which looked like this:
While the one above is a nice, connected web, this is just a bunch of nodes in a claustrophobic cluster (I didn’t want anything going off-screen). The game starts with a conventional web on the far left side, but that degenerates as you go further right, until you’ve got a lot of nodes that either connect to the same one or have no connections at all.
A traditional Twine game is like a Choose Your Own Adventure book. “To feed the troll, turn to page 37. To run away, turn to page 54,” that sort of thing. There may be a few variables here and there which change some text depending on whatever for more versimillitude, but the basic structure is still a web of nodes with definite, constant connections between them.
I Hunger, on the other hand, uses dynamic variables to decide which nodes the user can visit from which other nodes and when, and what the user sees is almost always an amalgamation of a bunch of different passages rather than one at a time.3 It’s not quite in line with Twine’s intended use-case, and that’s where my troubles began.
Twine’s Harlowe scripting language4 held up to the challenge for the most part, but was missing a number of features that would have certain parts a lot less of a headache to implement. The journey of programming, I’ve personally found, seems to be a progression from using lots of
switch statements to using as few as possible. As you learn, you speed up your work by mapping data, writing generic functions and performing pattern recognition instead of cumbersomely catering for every eventuality with a different explicit instruction. Some of Harlowe’s limitations sent me back to those dark days of long
if-elseif-else chains, with all the debugging and careful searching for typos that that entails.
But I don’t want to diss the language too much. Leon Arnott has done a fantastic job overhauling and extending on the classic syntax from Twine 1.x for Harlowe’s scripting, and there are some absolutely fantastic and easy-to-use text substitution methods. But the language remains very much a work in progress: recent feature acquisitions include being able to use a variable instead of a literal as an array index (I have a hard time imagining how arrays were good for anything before). Another issue is that the (acknowledged to be rough) documentation is somewhat incomplete, and you need go through the latest changelogs to make sure you don’t miss out on any useful recent features. You can’t not love a language which includes the
<present tag| as a syntax element, but its immaturity leads to a lot of niggling little problems.
For example: When printing an array, Twine would print a list of the array’s contents separated by a comma rather than a comma and a space, so you’d end up with something like
<span> spamming, but it won’t be a small amount of code. So all it’s much of a muchness, at least in the Harlowe format.
I struggled through nonetheless, though I had to cut a number of features and a good deal of content that would have made the game a much richer experience. As it stands, I Hunger gives you only a few choices at each point, and only really responds to the bluntest, least interesting choices you can make. That’s not wonderful, and fairly contrary to what I was trying to go for.
Additionally, the “Observe Man” sections are far shorter than I wanted them to be. I wrote about sixteen variation passages with a couple of sub-variations in each depending on various values, but what I really wanted for those sections was whole mini-stories where you can make choices on a more granular level and have those choices very subtly impact what happens later.
Going forward with this game, as I am planning to, I have a few options about what to base it on:
At the moment I’m leaning towards the middle option because it seems like it’ll be the least work in the long run, but it’s dependent on a number of decisions I still have to make about design features and changes to the structure of the current version of the game.
In any case, look out for the next version of I Hunger. I promise it’ll suck less. And remember: always use a familiar tool when entering a game jam, or pay the price.
Well, I rewrote the whole game in a new engine and made some additions, but they didn’t add very much to the experience, and most of my additions were pretty uninspired. It took me three years of mostly not doing any work on the new version to realise that the new version would never truly come to fruition.
So the other day I decided to call it quits and released the old version of I Hunger on itch.io. I probably won’t be doing any more work on this. If I do return to the rewrite’s codebase, it’ll be for a sequel or something, but that is also unlikely.
On the upside, I learnt Bruno Dias’s Raconteur wrapper for Undum in the process, and so I hope to make something new with that in the future.
Something else I’d like to write a game in at some point, but probably not for a weekend jam. ↩︎
To quote myself: “Tumblr, actually, is very nice from a blogging platform point of view. It’s really the perfect blend of ease-of-use and customisability, given that any non-technical person can have a functioning tumblog in four clicks and any technical person can have the same and then go and edit their blog’s HTML in whatever way they see fit.” ↩︎
Twine 2 takes the novel approach of implementing a different scripting syntax for each of its various so-called “story formats”, which all run on top of a single engine. The default one is called Harlowe, and I used it mainly because it was pretty and I didn’t know any better. ↩︎
I made the mistake of looking at the features of the unreleased 2.0 version of Harlowe just before implementing something which would have been a million times easier and better with array slicing, one of the big additions. ↩︎