Out of Control

This weekend was the GMTK 2020 Game Jam, a 48 hour competition to make a computer game to a common theme with a focus on game design rather than aesthetic. It was organised by Mark Brown, creator of the Game Maker’s Toolkit youtube channel and was the third such jam organised. It was also the largest game jam ever recorded by the game hosting website itch.io.

I’d previously sworn off of computer game jams. This was mostly due to my experiences with one of the other big, popular game jams Ludum Dare (officially pronounced luh-dum dah-re) where the theme is voted on before the jam from user submitted entries. This seems to be a great way to produce bad themes, and I’d gotten increasingly frustrated with the ones chosen. It also didn’t help that there’s a definite slant towards what Ludum Dare judges like towards faux-8-bit aesthetics and 2D games and that’s just not what I want to make.

Mark runs a discord server for the patreons of his channel, and it’s one of the nicest places on the internet. It’s a weird mix of game developers, designers and lay people that just works (the $1/month barrier to entry also almost certainly helps). I missed last year’s jam, but set myself the target of joining this year’s jam because having watched last year’s go past and the generally wholesome nature of the community (and importantly there wasn’t the same slant towards the faux-8-bit aesthetic that I disliked so much about Ludum Dare) made me rethink my ban on jams.

~

At a little after 20:02 BST, the theme was announced for the 2020 GMTK Game Jam via the medium of a youtube video premier. “Out of Control” was the theme, chosen by Mark some time before and kept secret. Some small areas of the GMTK discord had been opened to the public so that anyone could join the various game jam channels and those channels had very quickly become almost entirely unusable. There was a small patreon-only voice channel but otherwise I felt quite disconnected from the jam community.

One advantage of the Ludum Dare theme voting system is that by the time the jam starts you know all of the possible options for the theme, and traditionally I sat down on the Wednesday before and thrashed out at least two ideas for each theme so that once the jam started I wasn’t just staring at an empty IDE. I had been concerned that I’d have this issue with the single curated theme but I needn’t have worried.

Very quickly I settled on two ideas:

  1. An RTS set in the pike and shotte era where you can only control units near your commander, probably from a 3rd person perspective from the commander itself.

  2. An FPS on board a space station where a person printer has gone haywire and keeps printing new clones, some of which repeat your previous actions.

The first idea felt more achievable, but it also felt like almost everyone had had the same idea and Mark had made it very clear that innovation was meant to be a big factor of the judging criteria. The second idea had the initial problem that I wasn’t entirely sure how the game would actually work but I settled on an initial concept that you’d have to work your way through an environment to fix the spaceship in a adventure game puzzle style whilst your clones mess stuff up.

A giant technical challenge lurked behind the innocent concerns about the core game loop. After quickly abandoning doing my own “physics” for the player character and just using the Unity physics engine I build a simple input replay mechanism to produce the clones. I recorded the start and end times of every player input and replayed it with the same code for both player and clone in the hopes that the same inputs in the same order would produce the same results.

Nope.

<div class="sqs-video-wrapper" data-provider-name="YouTube" data-html="<iframe src="//www.youtube.com/embed/5ug3I51NULY?wmode=opaque&enablejsapi=1" height="480" width="854" scrolling="no" frameborder="0" allowfullscreen="">
</iframe>”>

The first problem was that I could only check input on each frame and there’s no guarantee that each frame is the same length. This meant that when I replayed the inputs, there was a slight but ultimately fundamental variation in the timing of the inputs that meant that any precise movements like walking through a doorway or jumping up some stairs became impossible. I ended the first day dejected and considering shifting to the second idea.

Making breakfast (left over chilli counts as breakfast) on the start of Saturday the solution hit me. Much like when rotating a raster image requires interpolating pixel data from the old grid to the new grid, I had to interpolate the events to ensure that events were being actioned for the right amount of time and at least for my initial tests it seemed to work. There were some slight variations but not enough to derail these initial experiments and I chalked it up to “character”. This was a mistake, but one I wouldn’t see for another 24 hours.

~

With this in place I moved onto doing some art work. One of the things I wanted to do as part of the jam was more work on producing, rigging and animating human characters. It’s something I’ve been scared of for a long time but I’ve been doing sculpting practice for a while now and it’s all paid off. In about two hours I went from the blender default cube to this somewhat blobby gentleman (complete with snoopy hat) who was sculpted, rigged and crudely textured.

In terms of animation, there’s a GDC talk by the developer of a game called Overgrowth about an animation system that relies on interpolating between a limited number of animation keyframes to produce a large range of animations that I’ve wanted to experiment with for a long time.

The lack of shading makes him look blobbier than I intended, it’s meant to be pockets.

The lack of shading makes him look blobbier than I intended, it’s meant to be pockets.

<div class="sqs-video-wrapper" data-provider-name="YouTube" data-html="<iframe src="//www.youtube.com/embed/LNidsMesxSE?wmode=opaque&enablejsapi=1" height="480" width="854" scrolling="no" frameborder="0" allowfullscreen="">
</iframe>”>

Unity did not want to play ball and it took me almost as long as the entire player model to get the animation working. Did you know that Unity has at least two distinct and incompatible animation systems and NEITHER OF THEM JUST WORKS. I didn’t get it working 100% but a little bit of jank is something to be expected in a game jam entry. Despite having made a total of four keyframes I now had walking, running and jumping animations! I got started on building the environment for the game and went to bed feeling pretty good about things.

Sunday morning rolled around, I got up in good time, made myself an actual breakfast and got to work working on the environment. Plugging the initial sketch from blender into unity showed a pretty glaring issue. Unity’s physics is nondeterministic. There’s no guarantee that if you provide the same set of inputs that you’ll get the same output and whilst averaged over time I was providing the same inputs, on a physics tick by physics tick basis I was providing entirely different inputs and thus getting what can only be described as “vaguely related” outputs. And the worst part was, the longer the simulation went on the more it varied.

<div class="sqs-video-wrapper" data-provider-name="YouTube" data-html="<iframe src="//www.youtube.com/embed/eq6QHLa_VbM?wmode=opaque&enablejsapi=1" height="480" width="854" scrolling="no" frameborder="0" allowfullscreen="">
</iframe>”>

My initial experiments worked because I hadn’t moved too far from the initial spawn, but my plans for a map had revolved around having a relatively large map with a big central spiral ramp so that you’d see your clones going about doing stuff. That wasn’t going to work.

Old, expansive design meant to feel like part of a larger structure

Old, expansive design meant to feel like part of a larger structure

Newer smaller design meant to be easy for the AI

Newer smaller design meant to be easy for the AI

There wasn’t enough time to start on plan #2 so I quickly threw together a second, smaller map that still incorporated a central area that all the clones would have to cross. This didn’t work, as the issue wasn’t so much with distance as time. Whilst a clone could reliably walk out of the spawn and into one room, there was maybe a 50/50 chance they’d make it back into the central area and basically zero chance they’d walk into a second room correctly.

gmtkmap.png

Implementing the animation system had also broken the ability to look up and down, whilst Unity can read .blend files without having to go through something like FBX Blender and Unity disagreed somewhat significantly on the relative power of lighting which meant that I had to redo all the lighting I’d set up in Blender and….

It got to about midday and I was completely demoralised. I had a game that didn’t work, no plan for how to fix it and not nearly enough time to pivot to another idea.

I took a break for lunch and decided to work on other stuff for a bit to see if what I needed was a distraction.

~

I won’t rehash what I said in yesterday’s blog post about my creative process, but the imminent deadlines and the sheer breadth of work required to make a game don’t gel too well with how I work. I had considered forming a team to do the jam but trying to find a random stranger to work with wasn’t going so well and I don’t know anyone else who likes game jams, has a different skill set to me and would want to collaborate on something like this. There’s also an element that I’m a technical team lead in my professional life and I don’t really want to do that in my spare time as well.

Long story short I abandoned my entry. A friend came for a (socially distanced) visit in the afternoon as he was passing through the area and I did some work on some other projects. I didn’t feel too stressed about it, but there was still a tinge of sadness to the whole affair.

For what it’s worth an option for fixing the problem hit me about an hour before the deadline. It would have been a significant compromise from the initial vision but it almost certainly would have worked with minimal rework required.

~

Despite abandoning the entry, I still got a lot out of it. More practice sculpting and rigging humanoid characters is never a bad thing and I learned quite a bit about rigging as a result. A chance to experiment with the animation system described in the GDC talk was fun and I fully expect to continue noodling around with that in the future.

I did enjoy the experience, and feeling of detachment aside taking part in the patreon only voice chat was fun. It’s interesting putting voices to names I’ve known for some time.

I am, however, not going to be continuing work on my jam entry. There’s not really enough of a game there to warrant it. The actual game loop was something tacked on to justify the jam and especially removed from the constraints of the jam itself it would just expand to fill the available space. And I’ve got enough projects to be working on right now (he says, having started this morning drafting yet another lasercut project).

I might noodle on the other idea, the pike and shotte RTS, as I’m already working on the assets for that for other projects. This is, however, the last game jam I enter as a solo participant though. This was the final nail in the coffin of the idea that they work for me. All the more power to people who enjoy them, and can get a game finished within the constraints, but it’s just not for me.

If only I was friends with any musicians…