What I learned from a night of no sleep (MonkeyJam Postmortem)


Steering behaviours, GameMaker, game crashes and ‘fake 3D’.

Monkey Jam 2024 just finished, and after some much needed sleep, here’s what I learned from it all.


I always like to try and use a game jam to attempt something I’ve not done before. As such, despite usually being an artist, I enjoy tackling the programming side of things, regardless of the problems I may inflict on myself! This jam had a whole lot of those, as well as the usual dearth of cut content and failed ideas that are common in any jam (at least in my experience 😭)

The Idea

The theme was ‘Cycling’ so immediately I thought

“everyone’s gonna do a 2d side-view ‘mini-clip’-esque bike game or a ‘runner’, so let’s not do that!”

Instead I wanted to make a game that really made you feel like a monkey riding a bicycle as we’ve all so longed to be. Essentially, the idea was to create a simple racing game filled with lots of mini-games designed to distract you from the goal, making the player (Monke) fall behind in his chase to catch the reluctant villain (Chris).

Ultimately, due to the constraints of being a person trapped by linear time, most of these mini-game ideas were dropped and the project turned into more of a ‘runner’ style game than planned, which a lot of other people also seemed to make as well! If you can’t beat ’em, I guess.

Over-Ambition

Take a look at my initial ideas for the jam.

Hmmm, yes "bike customisation". A totally reasonable thing to attempt in a jam

Originally, the pedal mechanics would have been quite simple: Slowly and rhythmically alternating two buttons to mimic pedalling, the bike would accelerate. Easy. The difficulty would come from all the other crazy crap happening on screen that you would have to deal with at the same time!

Not only would you be dealing with vehicular close calls, and banana-based hazards, other random events would have included:

  • Roadside konbini stops to refuel energy (at the cost of time, and your quarry getting further ahead)
  • Weather conditions such as rain (slippy when wet!)
  • Random roadside Obaa-san that would ask questions in Japanese, pulling your concentration from the road
  • Stream-snipers
  • Bike gangs (I dunno, just spitballing)
  • Various obstacles to avoid: Roadworks, traffic lights and crossroads, banana spills, speeding vehicles (those last two made it in at least!)
  • Random ‘humorous’ Breaking News updates scrolling across the screen detailing random events going on in the world
  • Different road elevations, changing the pedalling difficulty up-hill vs down-hill, as well as a gear system allowing you to change up and down to increase/decrease pedalling toughness
  • Player energy (Cycle harder = more speed -> lower energy, energy too low -> slower speed)
  • Bike Health: Call in the van gang to fix your bike when it breaks after a crash
  • Bike Customisation: Use limited funds to soup up your bike to gain an edge in the race

Failing tasks would result in either Damage to your bike, or a loss of Energy for the player, making it harder to continue cycling unless you repaired and refuelled at one of the proposed Konbini Stops along the way. Succeeding would do the opposite, and grant more Energy for the continued push.

In essence, I wanted the screen to look like a mess:

There's even a JPY-GBP graph there to keep an eye on the currency while you cycle! Brilliant and necessary!

Pictured: A mess

The screen would have been cluttered with a UI element for everything imaginable. Gear and knobs and buttons and dials and gauges, all needing to be attended to, distracting the player from the main goal. The point of the game then becomes not “Can you press two buttons to win a cycling race?” but “Can you press two buttons to win a cycling race whilst also dealing with a million other distractions before you inevitably crash into oncoming traffic?”

(In the past I’d written a simple Twitch IRC integration for GameMaker, so I was even considering an Engagement graph, that would have meant you had to pull out your phone every so often to up the Engagement, lest your Energy drop too low.)

Phew… As you can see that’s a lot. Too much for a three day game jam. But in a way, that’s kind of the fun of a game jam. Coming up with a load of ideas at the beginning, filtering them through a sieve, and seeing what you have in your pan at the end.

The Jam

- Doing it the hard way

Everyone’s all about their Godot’s and their Unity’s(…) but I’m GameMaker for life, ride or die baby! Sometimes using GameMaker feels like an exercise in reinventing the wheel. It lacks a lot of the standard features that other programs have by default. But arguably that’s what makes it so fun to use; getting to muck about with systems and implementations and creating little do-dads and widgets and-Oh yeah I’m meant to be making a Jam game!

Sometimes you don’t need to reinvent the wheel though. As I learned after spending far too long trying to implement a path-following seeking behaviour for the traffic in the game, before realising GameMaker has a more than adequate path system that I could have used straight out of the box. It’s simple, but for a game jam it’s more than okay. There goes 6 hours! Sometimes you get so wrapped up in writing your own stuff from scratch, you forget that GameMaker does actually have features!

- Procedural generation

Procedural generation was the next thing I wanted to tackle to generate a road for the player to follow. Grand dreams of having different elevations, different road surfaces, alternate road widths and splitting routes quickly fell away. Just make one thing and call it good! With a single road type decided upon I chose to generate a path by creating a bunch of points and connecting them together. It’s not completely random, there is a bit of a procedure to the generation, but not enough to completely rule out the chance that the path loops back on itself, intersecting with an existing road piece, and consequently forming a road block that is impossible to pass.

Looking at it post-Jam, a better idea would have been to create set ‘road pieces’ e.g. rightCurve, leftCurve, rightCurveTight, slalomPath, straightPath, wavyPath, uTurn etc. Each of these pieces would have had a variable that stored how many 90 degree turns they took. As each piece was placed a simple check could have been done against the current amount of left or right turns, and if they came to more than 2, a straight path would be placed instead, or a curve in the opposite direction, so as to prevent the road overlapping.

- HTML5 Support & “Fake-3D”

HTML5 support was the next one I wanted to tackle. Mostly because I think it’s fun to just be able to click and play in-browser. Less friction means more people will play it! (And tbh I think it has a lot to do with a previous jam game doing so well.) I find code sanity drops rapidly as jams continue. What starts as a nice attempt to keep everything organised with state-machines and functional programming devolves into long if-else chains, bloated switch-cases and needlessly repeated code. This caused the HTML5 version to become sluggish and unappetizing to play.

Not pictured: The amount of times I check if instance_exists(oPlayer)

I was keen to try some spritestack, isoslice, whatever-you-wanna-call-it “Fake 3D” with this game. It’s a pretty simple technique where you take the art equivalent of an MRI scan and layer each ‘slice’ of an object on top of one another, offset with respect to the camera, creating a pseudo-3D look. It’s kinda fun to play with, but all that extra drawing is a major drain on performance (unless you use something like the awesome Fauxton 3D, which I literally just realised at the moment of typing this that it’s meant to be read ‘Photon’ and not ‘Forkston’), so at this point I said goodbye to HTML5 and focused solely on the windows export.

- Balancing Act

Balancing difficulty is a hard thing, even in a normal game environment where you generally have a bit more time on your hands. Needless to say, the difficulty of this little jam game is probably slightly too high, no thanks to the less-procedural-than-desired random generation. Errant speeding vehicles, road bananas and dodgy wall collisions at infuriatingly inconvenient times, combined with speed increase toward the finish line means less-than-perfect input can snatch defeat from the jaws of victory. This was something I hadn’t really noticed until the game was submitted for the jam. Turns out getting a lot of practice playing your own game makes you quite good at it compared to a new player!

Why Jam?

I think the thing I like most about game jams is that you can just allow yourself to get super obsessed with an idea for a few days, pour all of yourself into it for a limited time, and be proud that you made something at the end of it all. On other long term projects (that are often technically easier to achieve) I sometimes struggle to find the motivation to continue with them (even if I’m enjoying them!) despite that fact I know I’m capable of making those kinds of things. The game jams are evidence for that! But there’s something about the energy you gain from the distilled chaos of a jam, working with others, where you have to throw caution at the walls even more than the wind just to get something, anything done. And that’s kinda cool I guess.😎

Files

MonkeBrake_v1.1_MajorBugFixed.zip 8.3 MB
10 days ago

Get Monke Brake

Leave a comment

Log in with itch.io to leave a comment.