Post

My First Successful Game Jam - GMTK 2024

I have always wanted to release my own game, but unfortunately when it comes to actually working on a game, I would rather do a gainer off my roof.

Luckily, that’s what game jams are for.

What is a game jam?

A game jam is a “competition” where people try to finish a fully functional game demo that follows a theme in a limited amount of time, usually only a few days. I say “competition” lightly, because while there is a rating system, it’s more about motivating people to make cool game ideas and finish them, rather than “winning”.

I’ve signed up for 2 jams in the past, but ended up quitting within the first few hours because:

  1. I took them way too seriously to the point of not commiting to any idea deamed “not good enough” (spoiler alert: that’s all of them)
  2. I wasn’t comfortable enough with my art skills to know where to go when designing games. Game jams are an excellent learning tool, but having some basic skills in an art medium can go a long way here

This year I wanted things to go differently, so before the jam I decided to try and learn pixel art… and also an entirely new game engine.

Back in June I spent 30 days making pixel art every single day, and while I still really suck at it, I’m now at least somewhat comfortable with the basics of Aseprite and can make some basic art and animations. I also started learning Godot a few weeks ago and found it a lot quicker to get prototypes up and working. It has a few concerning downsides if I ever wanted to publish a game with it (I really hate dynamic typing), but considering I’ve never even gotten close to that stage, it’s not something I’m really concerned with.

After I finished a few practice projects to be prepared, I was really excited about this year’s jam!

Day 0 - Suffering

The jam technically started for me at 11am on a Friday, so I still was working when the theme got announced as Built To Scale. I immediately started brainstorming ideas that I could start on once I got off work. I came up with:

  • A simple puzzle where you change sizes
  • An alien zookeeper game where you have to balance different sized creatures that would eat each other
  • Some kind of weird blacksmith game where you could forge massive weapons and throw them to “scale” the walls

I bounced around a bunch of ideas, even making little prototype graphics in Aseprite, and holy shit it’s already been 4 hours.

I had gone back and forth with so many different ideas that I started to feel like nothing sounded remotely good. By the end of the day I was so desperate to do SOMETHING that I started on a brick breaker clone, but that didn’t last very long either. By the time I went to bed and still hadn’t commited to a single idea, I was pretty convinced this would be another year of not submitting anything…

Day 1

After completely failing to start anything the day before, I came to a great realization:

I am very dumb

The goal I was telling myself was to “just finish a game I could submit”, but in actuality I was trying waaayy too hard to create an “original” game idea that would rank super well and be amazing and prove just how awesome and cool I was. Instead, I just needed to pick an idea, finish it, and take what I can from that.

With that genius realization, I went back to one of my first “basic” ideas of a top down game where you control a character who can grow and shrink things. I eventually decided on a puzzle game where you need to get your player and his lil buddies to a ladder to escape a collapsed mine.

Next I made a super basic tileset and configured an autotiler for it. I had some issues getting it to work perfectly, but with limited time I decided to just move on. The art for the rooms was mostly placeholder but I ended up liking how clean it looked and just kept that style. I also spent some time configuring collision shapes for each tile, since I’d need those for the player and also the navmesh for the other characters. After some playing around, I finally had a basic level layout to test with.

Interactables

After making some basic movement controls, I wanted to figure out the other mechanics as soon as possible. I started by adding a detection region collider to the player that would check for any overlapping objects when I pressed the interact key. I then created an “abstract” Interactable node with an interact() function, and tested this by making a FollowInteractable node so the other fellas would follow you/stop following after interacting with them.

To get this follow functionality to work, I used a navigation region node and nav agent node, which was actually really simple to setup with the tilemap in Godot. I’ve written about how to do this here, but basically once you define the colliders of your tilemap and make it a child of a navigation region node, the baked navmesh will automatically avoid obstacles.

Scaling

Once I got that working, it was time to tackle the size changing mechanic. I used a similar approach to how the player presses an interact key, and assigned Q and E as the grow and shrink buttons. This would use the same detection hitbox to check for any objects in front of the player, but this time it would look for a node I created called Scalable. This node was pretty basic and would simply scale the parent object up or down using three different sizes. If the player didn’t have anything in front of them, it would instead scale the player up or down, but I decided to change that later for balancing reasons.

Level Completion

The final piece to this basic prototype was creating an interaction for the ladder object, which was the main goal for the player to get to with all of the other characters. To do this, I created a new Interactable node that stored the next level (as a PackedScene) and the number of fellas required to move on. When the player interacted with the ladder, it used another collision shape to count how many little fellas were there, and if everyone had made it to the ladder, it would load the next level. This was a big relief to see how simple level loading was, because I hadn’t really done that before.

And with that, I had the world’s most boring game.

I did some smaller polish tasks like adding a custom font with in game tips to guide the player. Since I figured most people wouldn’t want to read the description for controls, I decided to try and treat most of the game like a big tutorial. That really helped me pace out how I could introduce new mechanics, create a puzzle with it, and move on.

Adding Items

At this point, I still had no clue where to go to make this “fun”, but it seemed way too powerful to freely change sizes, so I started working on the creatively named Growberry and Shrinkroom.

I started by making some basic sprites, and then created a new Interactable node that would allow me to carry items. This ended up really coupled to the player controller, but when you’re prototyping like this clean code doesn’t matter.

Side Note - The Beauty of Prototyping

The beauty of working on a project for only a few days means the best design patterns are the ones that allow you to finish. If it works as a prototype BUT has some horrible design decisions making it impossible to maintain, that’s fine. You can rewrite it later if you need to, all that matters is finding out if the idea works or not.

This was really hard to force myself to understand, because maintainable software tends to have a “no compromises” attitude (for good reason). Prototyping a piece of software is entirely different than implementing features with well-defined user stories, and that took awhile to sink in.

Carryable Items (cont)

Next I changed it so that you could only change an item (or friends) size if you were carrying the appropriate item, which would then be consumed. I also tried to add some player feedback by making them vibrate if you weren’t holding the correct item, and spent way too long debugging weird issues from that.

The last thing I worked on for the second day was trying to find some background music.

I went down a rabbit hole on this one. Even downloaded a DAW that I had no idea how to use. I already mentioned I’m dumb in this article right?

Day 2

After thinking about the game and doing some light playtesting, I realized a few issues with the game:

  1. First it was a little overpowered for the player to be able to change size whenever they want, so I changed the player controller to require scaling items. I think this also makes the game rules more consistent

  2. Second, the grow and shrink items can take away from any puzzle because there’s only one action to try with them, so I created a new item called the ScaleFruit. This is exactly the same as the Growberry or Shrinkshroom, but allows the player to choose whether to grow or shrink with Q and E.

Those changes were pretty simple to implement, but I did get stuck on this weird error for awhile. It turns out I had named one of my functions “scale”, which Godot then interpreted all my other references to the property “scale” as referring to the Callable object instead. It can be kind of frustrating worrying about issues like that when they’re so easily avoided in languages like C#, but that’s just the price you pay to build Godot for the web :/

More Mechanics

After some more play testing, the ideas really started flowing for new mechanics so I added:

Rocks that could be moved through by little guys or crushed by large ones. I also added Rock Walls that could only be crushed.

Next were Shrink Zones that shrunk everything that entered them, or the opposite Grow Zones that grew everything.

Finally I started working on an Ant NPC that would only attack things smaller than it. This required some more complicated behavior, but I threw together the basics and moved on for now.

I also did a bunch of smaller things

  • Added restart button
  • Added sprint ability
  • Added text tips that only appear when you get close
  • Fixed bugs
  • Created more levels

Intro Scene

Now that I had a handful of levels, I wanted to spend a bit of time setting the scene. Since the goal of the game was to escape from a collapsed mine, I decided to create this intro cutscene showing the little fellas working away and somewhat setting up the premise. I used Godot’s animation player node, which felt a little janky to work with, but overall worked well enough to make the intro scene.

Day 3

Even though the jam didn’t end until the next day, this was my last real day to work on my game. My goal was to get uploaded before dinner so a few friends could playtest (just incase anything was game breaking) so I quickly got started with last minute polish.

Interactable Outline Effect

I decided to add an outline effect to show which objects are close enough to be interactable, and did this by just ripping some shader code online.

It took some time to get it working, but one of the main problems I had was fixed by checking the shader material’s “Local to Scene” property. Basically, this creates a new instance of the material each time it’s used in a scene. Otherwise when I tried to outline something, everything in the scene would get that outline as the material was shared.

Other Improvements

  • I did some more bug fixing on the ant, and made it flee away from things that are larger than it
  • The intro still wasn’t finished, so I finally completed that and added a “skip” option in case the player had to reload
  • I also added a cheat key to skip to the next level, which seemed like a good fallback in case anyone got tragically stuck. I definitely wasn’t making a good game, but I figured I could at least anticipate that things may break and provide work-arounds.

I also wanted a particle effect for when things changed size, and after watching this nice tutorial was able to do that pretty easily. I even color coded it differently for growing and shrinking.

Sound Effects

The last thing that was really missing was sound, and I spent awhile trying to find and modify some 8bit sound effects to work, and they just sounded awful. The only sounds I ended up keeping were the intro sounds and a basic copyright free song that plays in the background. That’s definitely something I want to explore in the future, but I’d rather leave them out than include sounds that make the game worse in my opinion.

After some more bug fixing, finishing the last few levels, and some playtesting, I was finally ready to upload! Surprisingly this was actually really smooth. I was worried about server issues or my build misbehaving, but I think since I was technically uploading almost a day early, everything worked well.

If you want, you can even play “Little Fellas” here!

Results

After submitting (and waiting another 20 hours since I was really early), the jam became locked and we had 6 days to rate other games.

I tried to play through a bunch of other games, and there were some really creative ideas! One of my favorites was a silly jazz piano improve game that teaches you “scales” (ha get it) to use during a live jazz performance. There’s not really a win/lose condition, but it had a very enjoyable story and had a ton of charm.

After almost a week of scoring submissions, the jam was locked for about 24 hours for scores to be verified, and I finally got my results back.

I was genuinely just excited to have actually submitted something, especially considering I thought I was screwed after the first day, but I actually did well! The jam received 7,630 submissions and 158k ratings, and my game got:

  • 22 Ratings (people who rated my game)
  • 11 Comments
  • Enjoyment: #789 (3.636 / 5)
  • Style: #1113 (3.818 / 5)
  • Creativity: #2532 (3.273 / 5)
  • Overall: #1249 (3.576 / 5)

Given that there were almost 8k other games submitted, I was really happy with this result. I completely agree with the ratings that I made a pretty basic game, but I’m just happy to have submitted something. I’m really looking forward to next year to see how I do :)

This post is licensed under CC BY 4.0 by the author.