Birth of a shoot’em up



I don't remember whether I played They Started It before or after coming up with the concept for Laser Sky. I had been toying with the Pyglet game library, pondering what sort of game it might be suitable for, and a shoot'em up was the most obvious choice. Not that the world needs yet another game about blowing stuff up. But making a sequel to Attack Vector and getting it right for a change is an old dream of mine, and any excuse to learn a promising new technology is a good one. The big problem was choosing a theme. And like the first time around, nothing I came up with seemed to have legs. Even a briefly considered idea for a cute'em up fizzled out (though that's definitely worth revisiting). Moreover, it began to dawn on me that coding a sprite-scaling engine on top of a 2D library backed by OpenGL was kind of ridiculous. The new game had to be a good old-fashioned scroller... but then it couldn't be a sequel to Attack Vector.

In the end, the concept for Laser Sky came to me almost fully-formed during a walk in the park. Trouble is, it involved vector graphics, and that precluded the use of an engine optimized for sprites. So, back to HTML5 it was. The first order of business was dusting off the game microframework I developed two years ago for the original [[RogueBot?]]. (Which of course revealed a bug, duly fixed.) Making a ship move around the screen, and some basic enemies come at it, was easy enough. Then it was time for them to interact.

First good signs: the game looks just as well on screen as in my imagination, and the primary mechanic works great -- your bullets lose power as they go, so you can't just stay at the back of the screen sniping away. And since closing in for the kill comes with a risk of collision, there's some actual gameplay right off the bat. But just one type of enemy coming at you without pause gets old fast. (No, really. I've seen shmups released at that stage. Ugh.) So the next order of business was adding multiple enemy types, with different behaviors, and divided into waves. That was a whole new source code module.

Around the same time I added a rudimentary title screen, which also meant getting myself a nice open source font -- a relatively new practice for me. Another new practice was relying on hardware scaling for once, which eliminates most manual calculations and speeds up the code. Not that it's such a big problem this time; one unexpected benefit of 2D is having a surprisingly small number of primitives to draw each frame: around fifty most of the time, not counting the HUD.

Now I could add a life bar and getting blown up. But it wasn't easy to get blown up, because I could just sweep the screen shooting continually. I made the enemies more resilient, which led to very satisfying visuals once explosions were a thing, but it wasn't enough. So I also made the gun overheat... which it kept doing way too fast no matter how much I increased the limit. In the end, the solution was to make enemies less hardy again. Talk about getting balance right in the first place, then breaking it.

It was a toss-up what to add next, but the five waves I'd gotten out of the first two enemy types just came and went too fast, so putting in another three enemies and using them to double the length became the next priority. A few more tweaks, and it all became just difficult enough to make the first ten waves -- including a mid-level boss -- almost unbeatable without power-ups (that don't yet exist). Perfect! And with three of the five enemies shooting back, now there's an actual reason to blow them up, rather than simply dodging.

Incidentally, adding enemy missiles caused me to waste over an hour staring at the entirely wrong things in the debugger because of the way scope works in Javascript. That, and "use strict" isn't nearly strict enough, so stupid little mistakes can easily get overlooked. Look, you don't need static typing to figure out that the programmer trying to access an object property they never created in the first place is probably an error.

The last thing I added yesterday was the scrolling background, which again worked just as intended right away. It is kind of fast and distracting, but trying to slow it down made it worse. Oh well. Also gamepad support, which makes the game a lot more playable, in addition to protecting the keyboard from wear.

And that was all for the first eight days of development, because real life got in the way something fierce. Next: more enemies, more waves, audio, and then I'll be able to show off the game before adding extra levels.

Thanks for reading, and stay tuned.