(Open in full screen.)

Laser Sky is a side-scrolling shoot'em up with abstract vector art and slow-paced gameplay, suitable for older gamers. As of autumn 2016, it's limited to a single-level demo; development has been canceled in favor of a redesigned game by the same name. The original devlogs can be found below.


If connected and supported, a gamepad will partially override the keyboard; use the left analog stick and button 1 to play (Firefox only).


Development log

Coming soon, Laser Sky

Funny how much morale matters in game development. While this weekend I was in no condition to work on Laser Sky, the game was in a condition to be seen by a few early testers, and that gave me the energy to go on. Not that the feedback was so great: everyone's first reaction was to call it sluggish and unresponsive. It didn't feel that way to me, but when three people say you're drunk...

So the first thing I did on Monday morning was to make the player's ship accelerate just a little faster. Which, to my surprise, improved the game balance, and subsequent testers merely remarked the game is slow-paced. In other words, exactly as intended. Success! Most of them also praised the graphics, though one tester was put off by the same "paper airplane" enemies another loved. There's no accounting for taste. And hey, both of them recognized the inspiration despite the abstract shape. Go me.

Anyway, as predicted last time, the rest of the day was spent adding sound effects. They're from the same Creative Commons pack I used for Attack Vector, except a different selection (twice as wide, too), and with no additional sources. So the two games ended up sounding nothing the like. Couldn't locate any suitable music, but a friend offered to help with that, and from what we discussed it seems we're on the same wavelength. So this should be great.

On Tuesday, it was time to finish adding the content for level 1. Which meant creating one last enemy, then the end-level boss, adding more waves and remixing what was already there. Also some tweaking of the spawn range for two of the enemies, which at last made the second half reasonably balanced. This took all day, and left me terribly tired. It also caused me to realize I needed three weeks of work to have one complete level in the game. Laser Sky is shaping up as one of my biggest projects so far. Fortunately the gameplay is coming together very well, so working on it is a joy. If only the return on investment will be on the same level...

That said, on Wednesday I took it easy and settled for adding a mute key — also a dedicated pause key while the hood was up. The latter isn't just good form, but also frees up the Enter key for a secondary weapon, at least once I come up with the right idea. One last tweak to the final boss, and it was time to take a break. These updates don't write themselves, you know.

What next, then? Most likely, the game will go live this weekend as-is; it's time for a public appearance. After that, adding a high score system, the music (whenever it's ready), and then either levels 2 and 3 or else the menu screen I keep promising. What won't happen immediately is the planned desktop port. Not only the effort would be too much so soon after release, I want to see what people think about the game before sinking much more time into it.

Laser Sky progress report

I wasn't planning on posting updates today, since real life problems and bad weather conspired to keep me down, but in retrospect the game has progressed noticeably anyway, even if it didn't feel like that at first.

So, a week ago I announced my new game, a good old shoot'em up called Laser Sky simply because the name was available — as opposed to pretty much anything involving the word "neon". (Do you know how hard it is to come up with original titles these days? "RogueBot" for instance is used by a whole bunch of other projects, from a variety of fields. Hopefully nobody sues.)

Anyway, at the time Laser Sky was just beginning to feel like a game, but still lacked variety. So one of the first things to add was power-ups. The first one restores lost energy, or else gives points if you're topped up — power-ups should never become useless! The second gives you an extra gun (then a third in the tail, which was sorely needed), and after that it erases the heat build-up, that gets significant even though with two guns you fire more slowly. The whole thing took some balancing work, because more guns should be more powerful overall, but still come at a cost. With a bit of special-casing, and otherwise fewer changes than expected, that too worked out great. It requires a change in strategy that just makes sense, and feels satisfying. Not bad for just one addition!

It took some thinking, but the third power-up became a shield that, while active, absorbs half the damage you get. Initially it lasted until consumed, but that turned out to be a really long time whenever I happened to be on a roll and/or catch two of them in a row. So now shields also expire by themselves after a while — long enough so you don't feel cheated, but short enough that you have to plan for it. Yet another gameplay element that's helpful without breaking balance.

Another change entirely was the addition of one more enemy type, the sixth so far, and the last of those originally planned. This one also had to be special-cased, fortunately not too much. It also took a lot of tweaking, because at first it felt too weak, so I made it stronger, but since it's also great at ramming you that made it too dangerous, even if it didn't also shoot missiles, which it does. In the end I erred on the side of easy (a little, mind), because other players won't be as intimately familiar with the game as its author. At least waves 11 and 12 are survivable with skill now, rather than just dumb luck or exceptional reflexes.

Speaking of which, a non-gameplay addition is continues — a necessity for testing the game as it gets longer: changing the code all the time to start in the middle not only gets old quick, but could make me forget how my audience experiences the game without having that luxury. For now continues are infinite, and don't penalize you much; perhaps later there will be an option to limit or disable them, for gamers who want a bit of a challenge. Cheats would have been another option, but eh. They're not as easy to implement, and they feel like a childish thing these days.

In the way of programming, it's worth mentioning that sometime after adding the ability to space out enemies in a wave, the game began to stutter consistently, on two different browsers/engines. It seemed odd that a simple "if" statement could do that, but the rhythm of the stutter was telling. Either way, making sure the GameWorld object now runs in strict mode, as well as replacing all instances of == and != in the code with === and !== respectively, made the game run smoothly again, even on my elderly CPU. A hope for the future!

The next step will be to add sound effects, for which purpose I'm going to raid the same collection used in Attack Vector. Got an idea for how to get music, too. May or may not add a menu screen before release, but the first level should be complete in any event — twenty waves, or 6 minutes and change of play time. Then it will be a toss-up whether to add more levels or make a desktop edition for sale, and leave the HTML5 prototype as a demo. But first, to get some feedback. Stay tuned.

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.