JS13K 2021: Galaxy Raid

Can’t believe it’s been already a full year! My last post was about JS13K, and a year later, the story repeats itself; not only I participated again this year, but I built a shmup game… again!

While I was quite proud of what I created last year, there were quite many things that I couldn’t include; 13Kb is a very small size, but even more important than that, I couldn’t invest as much time and energy as I would have liked to. During the judging phase of the competition, I was really impressed with many of the entries. At the same time, it dawned on me that real life doesn’t give me the necessary bandwidth to build something similar. So, instead of trying to build everything in a month, I decided to build an “engine”, and then use the competition time to work on the actual game.

Phase 1: Improving the original entry

After the competition was over, I started reworking the 2020 entry, improving every aspect; sound effects, pixel perfect collision detection, gamepad and keyboard support… of Webpack… at the same time, I kept the game mechanics and ship generation almost untouched (with the exception of the new collision system). The end result already felt a lot more polished, but don’t take my word for it; play the original and compare it to the updated oned. Not only that, but it ended up being noticeably smaller, almost 2Kb under the 13Kb limit.

Phase 2: Incompatible changes

After that I went back to the procedural ship generator library I created. The biggest problem updating it is that any ordering change on the pseudo-random number generator causes completely new ships being created, so it was time to work on “version 2”. This included changes like an updated PRNG library, and a number of optimizations that weren’t backwards compatible.

Now that the game was better and smaller, it was time to think about adding new things on top, and I started with the new HUD/menu system. In the original version, everything was painted on a HTML5 Canvas object, but that doesn’t upscale well in larger screens, so after some experimentation I went with a hybrid Canvas/HTML approach. The game now has two layers: a Canvas object, and a HTML panel on top, which use exactly the same scaling factor, but now the text will look perfect even at very high resolutions.

The great thing about working outside of the competition’s time frame is that I could spend as much time as necessary polishing the small details, like choosing the font, playing with different styles (I settled for a skewed, condensed look using CSS transformations), and building a user interface that could be used with a mouse, keyboard and even gamepad.

Phase 3: The actual jam

For the actual game content, I waited until the theme was revealed, as I really wanted to integrate it properly… and it happened to be “Space”! I was secretly hoping to make some sort of weird “fusion” with whatever was announced, but at the same time, being able to keep the space elements of the game gave me more time to focus on the rest.

At this point, most of the “engine” work was done, so I could fully concentrate on the game itself. I decided to name each stage after a star, and decided to build 4 regular stages, a final stage, and a survival mode. I’m definitely not a game designer, but I’m quite happy with the final result; there’s a good variety of enemies, and the difficulty progression is well correlated with the upgrades available. Also, I could add a couple of surprises that I’m not going to spoil!

So, with one week to go, I had a finished game that just fit the size limit. But that wasn’t the end of the story…

Bonus phase: Roadroller

Just before the competition started, I read a tweet that mentioned a new compression tool with very promising results, developed specifically for JS13K games. Until this point I developed the game without it, and running it actually gave me an extra 1.5Kb!! So now I had to decide what to do with it; my first thought was to add some music, but given the game has multiple stages, I’d have had to use the same tune for all of them, and that’s the sort of compromise that will make players aware of the limitations of the competition, which is something I really didn’t want.

After giving it some thought, I decided to add a story in the form of “cutscenes”. 1.5Kb is not a lot, so I implemented the simplest possible system I could think off: a dialog between the different actors in the story. However, the uncompressed dialog text alone is already 3.7Kb! Even so, I tried to make it as interesting as I possibly could, so hopefully that will give an incentive to players to finish the game. After some dialog tweaking and additional optimizations, it went under the size limit, and sent it the night before the competition ended.

Closing thoughts

While it’s highly unlikely I’ll end up working as a game developer (as that needs actual talent), it was really interesting to wear that hat for a little bit, and see things from a different perspective than what I’m used to.

I’m really looking forward to read the comments of the judges and the other developers, as I really think that getting feedback was best part of last year’s competition. And if I get a shirt this year, I’ll be very happy!

Play it here, and the source is on GitHub.