A few weeks ago, Jay Cano and I took part in the week-long Godot Wild Jam 18 and submitted Plague. Here are some of my personal thoughts on how we did and maybe some lessons for the future!
📈 Results
Out of 43 submissions, we ranked 6th overall. That is the top 13th percentile. More importantly, we ranked 3th for fun or top 6th percentile. For the sake of comparison, Onederful Wizard, which we submitted to the GMTK 2019, ranked 294 out of 2617 entries (top 11th percentile).
Even though both games received positive feedback, Plague ranked high for fun. We're very happy about that!
👍 What went well
✅ Splitting tasks
During the previous jam, Jay and I rushed to implement features like crazy. Despite, Godot being very source control friendly, we ended up having to manually resolve too many merge conflicts.
This time we were much better organised and split tasks in a more consistent way.
- 👋 David: player movement, enemy behaviour, individual game systems, menus and effects.
- 👋 Jay: procedural level generation, level section design, enemy/item spawning and putting it all together.
Additionally, we both had separate "playground" scenes to test our work. We barely faced any merge conflicts!
✅ Platforming
We got pretty good feedback for tight controls. Our player movement is not too complex. For maximum control, we use a KinematicBody
rather than a RigidBody
. We did a direct implementation of the formulas explained in the Building a Better Jump GDC talk.
The proposal of the video is simple. The variables designers tweak to control character movement should not be gravity
, acceleration
, etc. They should be jump_height
, jump_distance
, time_to_jump_peak
, time_to_max_speed
, etc. It's much easier to reason about the distance a player can jump to build a level than the combination of gravity and other physics variables.
Additionally, we implemented a very simple Coyote Time. This gives players a grace period to jump even if the character has left a platform. Tiny thing, but it makes the experience a lot more responsive.
✅ Procedural level generation
The game is a procedurally-generated infinite side-scroller. However, we do not procedurally place tiles. We have 8 hand crafted chunks. Then, the InfiniteLevelManager
script is responsible for randomly selecting the next chunk as the player approaches the end of the current chunk. Finally, it populates the chunk with enemies and ammo pickups.
This gave us an infinite scroller with a very simple procedural generation algorithm and super tight control over the end result. We even managed to progressively increase difficulty by spawning more and tougher enemies.
With more time, we would have increased the variation and potentially procedurally place decoration on top of the blocks instead of having it built-in.
✅ Re-using assets
Jay and I are both engineers and not very good at art. It was a wise decision to leverage multiple asset packs. This led to good feedback on both audio and visuals.
- 🔉 The Essential Retro Video Game Sound Effects Collection by SubSpaceAudio
- 🌎 Roguenoir Cyberpunk Assetpack by Sam
- 🎵 Dark Retrowave Cyberpunk by Alex Zavesas
- 🌟 Particle pack by Kenney
- 🎮 Keyboard and controller prompts by Xelu
There are so many super high quality free assets, it's insane. If your jam allows it and you have a similar skillset to ours, go for it!
✅ Time for polish
We dedicated a big chunk of the last day for polish and juiciness, which massively increased the game's perceived quality.
- 🎥 Camera shake for damage and bullet impacts.
- 🦘 Coyote time for jumps.
- 🎮 Gamepad controls. The game detects Xbox/PS4 controller or keyboard and shows different instructions in the main menu.
- ⛈️ Weather effects. We added rain, lightning and thunder that start at random intervals.
- 🌟 Particles and SFX for everything that happens in the game.
✅ Automatic deployment
Right before the jam, I implemented a Continuous Delivery pipeline that exports the game and publishes to itch.io on every push to master
. This completely removed the panic that typically happens when something goes wrong with game export right before the deadline.
You can also go back in time and see how the game looked at any point in time during development.
👎 What went wrong
❌ Poor use of theme
Due to some issues with the organisation, the theme announcement was delayed by half a day. Knowing that we weren't going to have much time to work on the game during the week, we started right away without a theme.
Unfortunately, we failed to go back to the theme and really incorporate it into the game. In the end, you can interpret that the monsters are the "plague". Other games like Harvestor-3000 and Ceefax made a much better use of the theme.
By the way, this is not a complaint about the organisation at all. We really appreciate their efforts to keep the jam going!
❌ Lack of end goal
The infinite platformer concept made people feel a lack of purpose. We didn't save top scores, so there was obvious sense of improvement nor progression.
An alternative may have been to introduce a final boss and an end-game after a fixed number of chunks. Lack of time!
❌ Yet another platformer
The game is a simple platformer and the procedural generation was not enough to make it fresh. That is why we scored the lowest in originality, ranking 28th or 65th percentile.
In future jams, we should prioritize a differentiating feature and really go with it. Hopefully, foundational things like getting movement right will take less time going forward.
✌️ Thanks!
I had a blast participating in the jam. Thank you for reading this postmortem and thanks to everyone who played the game and gave us feedback.