Ludum Dare 32 is over! It’ll be three weeks before ratings are completed and I find out how well I placed, but I already feel like my experience this weekend counts as a smashing success.
My entry is Deserializer, a vaguely Frogger-like game of network packet sniffing. The objective is to steal the system password by deserializing passing packets of data, without getting caught and blocked from the system.
Play it now using the experimental Unity WebGL build. Also available is standalone executable for Windows (packaged as a 7z file, 64-bit, 32-bit, or packaged as a zip file, 64-bit, 32-bit).
So what makes me feel like this is already a big success? The main factor is that I was able to prototype the core mechanic and obtain a sense of fun early in the process, without needing to tweak and polish and expand in order to hunt for the fun. Within five hours I had the core mechanic working, and after another three hours the next day, I also had the core objective implemented. That left a lot of time for polish on top of an already solid core. So all in all, this represents exactly the type of skill I want to have for being able to rapidly prototype ideas.
Related to that is the fact that I was able to successfully use Unity to quickly churn this out and add in enough bits of juiciness to get a taste of what type of experience a polished product might generate. In the past, I’ve had trouble working with Unity, because I found myself fighting against it’s architecture rather than working with it. This time I was able to get past that, for whatever reason. Partly because I quit caring about the quality of my code. Consistency was definitely not happening. In some places I instantiated prefabs at runtime; others I placed the objects directly in the scene. In others I used static factory functions to build objects at runtime from scratch, rather than from prefabs. I suppose in a more polished project all of those methods could be applicable too, but my choice of when to use each one was more experimental in this case. But that exploration has given me a bit more of an idea of when each use is most appropriate.
Reflection on Gameplay Elements
As for the fact that it seems to have a good fun core (at least as far as my impression goes), I certainly can’t claim full credit. Some of it was luck. For example, packets with large quantity of inner bits are easier to get, because their active target area is large. But they’re also more likely to not perfectly fit the objective data. The packets with only two or three active bits are harder to hit, but will more often be exactly what you need. So it’s a tradeoff that just happened to work out well, and be fairly balanced in practice. But on top of this I did add my own tweaks. For one, I made shorter bit patterns probabilistically more frequent, because the default distribution didn’t feel quite right. Secondly, during the early levels, I added a chance that packets will be generated with exactly the data you need. That chance decreases in the later levels, but it serves as a good introduction to the game, and provides a sense of satisfaction at exactly nailing the objective.
I had to try a few different things in terms of visuals and sounds to communicate the mechanics well. It still doesn’t feel perfect admittedly, but it turned out way better than my first full prototype after eight hours. The animation effect of deserializing a packet was the first major one I did, and the way the bits fly down to the objective and match or mismatch one by one with sound effects was a big improvement toward making it clear what was happening. And the effect of fading out and scattering the non-active bits probably made it clear that they were irrelevant beyond making you explode if you hit them. Later, with the help of feedback from friends, I was able to improve the display of the objective so that it was less confusing. They also helped me figure out some of the particular ways in which I need to tweak the data visuals so that they were more clear. In particular, they needed to be wider and needed more visually distinct horizontal separation, whereas I had previously been focusing too much on their vertical differences.
And finally, credit for the idea of a killer end of file objects goes to Jeremy Breau of Antithesis Design. That added a definite nice touch, though I chose to leave it out of the early levels to keep them relatively easy. Conveniently, having a menu screen with stuff happening in the background allowed me to keep them visible so that beginner players would know they exist, even if it took them a few minutes before they experienced them directly. Hopefully the little data lane flicker warning and sound effect add a touch of polish too. The flicker in particular weakens the assassination skill of the EOF, so that it at least gives the player a chance to make a hasty but informed decision about how to get out of the way.
And as a matter of accident, my particular implementation of the EOF also happened to product some curious side effects in terms of play style. I made it so that an EOF, since it moves much faster than data packets, will only spawn on an empty data lane. But it will queue up on a lane that isn’t empty, which blocks other packets from being spawned on that lane; the EOF will then be released as soon as the lane becomes empty. A side effect is that I found myself hiding amongst data packets in order to avoid EOFs. But that gets tricky as I’m being surrounded by a bunch of packets that could destroy me. Worse still, as soon as I deserialize a packet, that might actually free up the EOF that is queued up waiting to attack, so grabbing the last packet on a lane is always a dangerous game. Again, good tradeoffs which make for interesting gameplay decisions.
Further, the EOFs spawn at a semi-random rate that is separated by so many seconds. But that is really only their queue time. So sometimes they still end up releasing within about a second of each other, which heightens the excitement. Even better, EOFs prefer to queue up on the lane that the player is currently on; they actually target the player, rather than being entirely random. This encourages the player to move around a lot, rather than sitting in one lane.
There’s probably all sorts of similar subtleties that could be discovered, or which could be generated with additional but similar mechanics. Buffs and debuffs were a mechanic that I had considered, but didn’t have time to implement. These could be standalone objects like the tabs (which were a workaround for the irritating problem of having all but one bit correct), or better yet, they could be embedded within the non-active portions of data packets. In this latter case, you end up sometimes having to decide whether to grab a packet with a good buff but the wrong data, or grab a packet with a bad debuff but exactly the data you need. Decisions, decisions! What would the buffs and debuffs be? All sorts of things, I’m sure; extra lives were the first I thought of. Slow downs and speed ups. Spawn rate alternations. Invincibility. Et cetera. It would be a fun game mechanic area to explore.
I may very well have to look into commercializing this in the future. For now I’m going to wait on the Ludum Dare rating results, and get back to work on Worldbuilder, but this could work quite well as an arcade game for consoles, or possibly a tablet game if I figure out decent controls for a touchscreen. As one of my friends said, it does have a promise of becoming a time vampire. Having progressively more difficult levels, and saving the best times and highest levels achieved probably helps with that; there’s always an objective to work towards, even if it is merely getting betters times or surviving longer.