Kulkis on Itch.io
To make the long story short Kulkis is now available on Itch.io as name-your-price. You can play the game directly in your browser (provided it supports Flash) or download the Windows build. It’s a small but fun game so give it a go!
Kulkis was one of the earlier Flash games I wrote and I think it might be the first one which used Retrocamel framework, a Flixel-inspired set of libraries that I developed in order to speed up development of my games.
Since the game’s first release the framework had at least two major internal releases, so the code that is currently hosted on GitHub is far from what it was originally. Heck, I am fairly sure that code is now lost forever.
The reason I even bother writing this is the nostalgic feeling you get when you open your old code. The delight you experience when you realize that despite it being so many years, the code is still not bad! I’ve been planning to release as optional-donationware my old projects on itch.io for a while but I never could be bothered to investigate what I have to do legally to make sure I don’t break some Polish tax law or something. But now I’ve finally managed to carve enough free time to investigate and that’s how Kulkis made its way to this site.
Anyhow, this is a devlog post and, like I said previously, I want to talk a little bit about the nostalgic feeling of seeing your old code. Or, more specifically, what does it feel to suddenly find yourself deep in old code when implementing new features.
New music manager
Retrocamel framework has a class for managing and playing audio, but it is flawed. When playing music there is no clean way to detect when the track ends, so the way the music in the game worked was that each time you started or restarted a level the music would start from the beginning which, most of the time, meant you’d be hearing the same first 20 seconds over and over again.
I wanted to polish it the tiniest bit by making it so that the music continues where it stopped last and when one track ends the next one starts automatically. But I decided not to modify the existing music manager. Partly because there was a lot of boilerplate functionality that I had no use for, partly because I felt this respects towards that code. I’d rather cut out old functionality than perform sacrilege by hacking a quick and dirty solution in something that I was proud of in one way or another.
So I hacked a solution in the game’s code directory. This introduced a few dumb bugs because of how losing window focus works but those are such edge cases that I decided to just leave them in.
Integrating the new music manager was pretty amusing. The game featured quite a few volume fade-ins and outs and that was accomplished using a very clumsy effect system. See how the effects are built. And sure, you can hardly do better in AS3 due to not having generics, but after my experience in C#, I know how things like that can be done better.
Consolidating hard mode into the main game
Originally the game was released in two version – regular and hard mode, where each level was filled to the brim with spikes. Those were separate SWF files and were usually treated as separate games. But for the itch.io release, I wanted to finally clean it up and have everything in a single executable. So that’s what I tackled next.
Integrating this was a bit of a pain, since I had to add a new button and touch layouting code which looks like this:
_startRegular.y = 271; _continueRegular.y = 271; _startHard.y = _startRegular.y + BUTTONS_Y_DISTANCE; _continueHard.y = _startRegular.y + BUTTONS_Y_DISTANCE; _credits.y = _startHard.y + BUTTONS_Y_DISTANCE; _options.y = _startHard.y + BUTTONS_Y_DISTANCE; _quit.y = _options.y + BUTTONS_Y_DISTANCE; _startRegular.x = (S().gameWidth - _startRegular.width) / 2 | 0; _startHard.x = (S().gameWidth - _startHard.width) / 2 | 0; _quit.x = (S().gameWidth - _quit.width) / 2 | 0; _continueRegular.x = _startRegular.right + 10; _continueHard.x = _startHard.right + 10; _options.x = (S().gameWidth - _options.width - _credits.width - 10) / 2 | 0; _credits.x = _options.x + _options.width + 10;
It’s inexcusably bad. Very inflexible, repetitive, easy to make a mistake. I am not proud of that code.
Not to mention for every function that starts/restarts/loads level I had to make sure the function know its context, whether it’s regular or hard mode. Of the many possible ways to do it I chose a hybrid of passing an argument and storing things in some local variable somewhere. And it works. Since the code is unlikely to ever again be modified (much) I can allow myself to chose suboptimal solutions.
There is another dumb aspect of this, appearing/disappearing. When the state is created all of the UI elements have their alpha set to 0 (yes, alpha to 0, not visible to false) and when the logo animation finishes it’s flipped to 1. Accidentally I introduced a bug here which made it so that the continue button for hard mode never appears. I thought it was a problem with saving/loading state, but after 20 minutes of debugging in the wrong place, I noticed the alpha on the button was never changed.
That’s how a bad code can bite you in the butt.
Beyond those two changes there were a few subtler ones:
- In Kaizo (hard) mode player moves horizontally the tiniest bit faster and the death animation is shorter. It’s a very important design change inspired by games like Meatboy and Celeste where the assumption was to fail fast. It makes this game mode a bit more bearable but, if I am to be frank, I’d be surprised if anyone ever bothered to complete the whole thing, I just don’t think it’s worth it. The reason it’s even there is to stay true to the original game where it makes sense and, arguable, it makes sense here.
- Removing lives. Let’s be honest here, there isn’t much space anymore for games with lives systems. And as a blast-to-the-past, the only thing it accomplished was to annoy players and waste their time which are two things you generally want to avoid. And also…
- I removed score. With unlimited lives, the lower score would actually signify a better result since that would imply you didn’t get points for repetition. If the game was bigger it could possibly stay but it’s too late for that now.
- Added new intro and outro texts for Kaizo mode. Nothing fancy, but the player at least deserves something different.
And that would be it, folks. It was a lot of fun just opening an old project and doing a couple of small changes. It was also a learning opportunity to see just how worse a programmer your past-self was and how you would do certain things better.