I’d written engines from scratch before, but they were generally for smaller, less ambitious games. However, my thinking was it’s a top-down scrolling 2d tile-based engine, how hard can it be? I envisioned gameplay similar to one of my SNES favorites, Super Smash TV. Rather than Smash TV’s chain of mostly-identical square rooms, though, I wanted a series of maps, and enemies with real pathing AI. Not just open arenas, but alleys and corridors; maps that would’ve been at home in 2.5d games like Wolfenstein or Doom but in a top-down two-stick universe. It would’ve been a linear, story-driven thing. Science fiction film noir – a space-faring bounty hunter that gets drawn into a web of murder, police corruption, and mad science. Shades of Blade Runner and Shadowrun but with blocky pixel graphics reminiscent of the 16-bit era. A whole alternate history reality grew out around it – a universe where the cold war went hot in the mid-80s. The name “Fistful of Kremlinks” is an obvious homage to Sergio Leone, owing to space western influences like Firefly. A “kremlink” was a blockchain currency developed in the former Soviet Union in the 2030’s by a mysterious, mostly-anonymous engineer. If you’re asking “how would you end up with a fistful of virtual currency?”, consider your character is a high-end assassin and many affluent people in this universe embed their private crypto keys on subcutaneous chips – a mental picture begins to form that gives the phrase “blood money” new depth. Each map would involve gunning your way through the baddies to uncover another piece of the story that would lead to the next location. In concept, it would’ve been my magnum opus. In reality, it was never finished.
Multiple Tile Layers, Multiple Z Levels, Parallax Scrolling
The engine was compositing several different layers of tiles in real-time. Some of this was to facilitate dynamic alternative or decorative tiles, kind of like decal layers over the main tile layer. Some of it was to cut down on Z layer calculations – for tiles that I knew would always be in front of the characters, I could place those tiles in a layer that always overlays the sprite layer and not have to calculate their Z height over and over. The most noticeable use, though, and the primary reason I did it, was for parallax-scrolling. In this clip, you can see I used it to add a layer of decaying ceiling tiles to an abandoned movie theater, placing the camera viewpoint above or inside the crumbling roof. It was a neat effect, but I think ultimately doing all that compositing in real-time in addition to the lighting effects is what really brought out the shortcomings in the way I was rendering and led to slowdown and framerate issues.
It may be a little grandiose to call it a lighting engine, but it did have a system that used masking to allow for ambient light changes on a map, and have things that glow and flash. It’s most noticeable on dark levels, like this asteroid mine. Here you can see the glowing headlamps on the miners and the muzzle flashes lighting up the cave. I also used it to give the player a little flashlight that swung around and followed the cursor. Pretty effective visually, but like I mentioned, compositing these lighting masks along with multiple tile layers really pushed the limit of what HTML5 canvas can do in real-time, tens of times a second, while the browser is also chewing on all the math to facilitate the gameplay.
Monster In-Fighting and Non-Enemy Sprites
Sprites could have different dispositions toward the player and towards other sprites. In the first example there, the prison mining colony riot, the miners hate the player, but they also hate the guard robots. The guard robots hate the miners but will ignore the player – unless the player damages them. In the second example, the zombies hate both the player and the nearby civilians equally – they’ll gladly chomp on whichever is closer. If they kill the civilians, though, the civilians join the ranks of the undead. I’ve always really appreciated how much life is brought to a game world by in-fighting and different enemy factions. The idea that characters aren’t entirely defined by their relationship to the player but also to other characters in the world makes both the characters and the world more cohesive and interesting. What I didn’t consider is that also adds a lot of edge cases and unknowns that make balancing encounters and debugging enemy AI much more difficult. In the second example there, you can see that while one nearby civilian in the lower left (correctly) runs around panicked when he sees another civilian killed, the one closest (incorrectly) just stands there. It’s probably just a minor bug, a greater-than sign somewhere I meant less-than, but the time taken to debug and fix tiny problems like that adds up, especially when you get into interactions between non-player entities. At times it requires recreating scenarios that can’t be reproduced easily without writing a lot of purpose-built code that’ll be ‘thrown out’ after debugging is done. You put in a few hours of coding, and what you have at the end is an enemy AI that’s slightly smarter, but in a way that will probably be imperceptible to the player in almost every instance. It’s a slog. It’s the perfect scenario for unit testing, but the code wasn’t structured well for that since I didn’t plan for it in the beginning.
In addition to writing the code for the engine, I also drew – pixel-by-pixel – tens of tilesets for different environments and hundreds of frames of sprite animations. It may seem macabre, but the death animations are some of my favorites. Most everything else is just a short loop – walk down, walk left – but the death animations could be a little more extravagant. The tank pictured here was a mini-boss, the lighting in the animation when it’s defeated is some of my favorite pixel work I’ve ever done. I also recorded a soundtrack – I really loved the idea of dynamic soundtracks, different musical elements that are layered in real-time to build a musical backdrop that rises and falls with the intensity of gameplay. I had over thirty tracks of music that could be combined in various ways – thumpy ambient/industrial stuff that hearkened back to the kid that wanted to be Charlie Clouser when he grew up. But by 2017, after three years of working casually on it, I’d started losing momentum. It was more and more obvious that some bad development decisions I’d made early on were hamstringing the game engine. I spent less and less time on it, and eventually washed my hands of it completely. It’d been a learning experience and a fun hobby, but it’d never be a game. I tried really hard to get comfortable with that. Sometimes I succeeded. I’d learned so much in the intervening time, though, and I really loved the little universe I’d started creating. It seemed like a shame for all the work I’d done to never be used for anything.
Once More, With Feeling
Bring on the Carnage
As of now, I’m still undecided if this blog entry is a game announcement or a postmortem. I have made peace with the idea that my browser-based space saga will likely never see the light of day. The setting may be used in future projects, and I may eventually tell the story in some other way – maybe a game, maybe not; if it is, I won’t be writing my own engine this time. But I did think it was kind of a shame I developed a game for over five years off-and-on and didn’t have anything playable to show for it. An idea stirred – I had created a map that was just a square arena, a la Smash TV. It was essentially my “is it fun?” sandbox – when I needed to tune weapons or enemy behaviors, I ran the “Arena of Carnage” map as a way to playtest. The simple map means a lot of the more intricate challenges in collision detection, line-of-sight, and enemy pathfinding could be sidestepped. This small one-room map with flat lighting also ran fairly well in the old engine, as it was, without any further optimizations. I was struck with the idea of releasing “Carnage Mode” as a standalone game – significantly less ambitious than my original vision, but nearly finished already. So I went back to the old engine, spent a couple weeks tying up the loose ends, and the result is Fistful of Kremlinks: CARNAGE MODE – available for free on itch.io.