Another quarter year, another Ludum Dare game jam. Last time I did a little phyics-based angry-birds-em-up style casual-action-puzzler-thingy called Gravity Assist. It turned out pretty well, particularly for my first jam, and also came 155th overall in the Compo category (the “official” half of the event, allowing only solo devs and with strict rules on content creation) of about 1500 entries.
So this time, I wanted to step things up. A few months ago the idea of a procedural Descent clone occurred to me. 6DOF shooters were an integral part of my formative gaming experiences, and they’re very rare nowadays. Conceptually, it seemed a perfect fit for randomly-generated levels, and my friend Phi had all the necessary skills from his roguelite dungeon crawler Tiny Keep. Along with Jey Kazi, Phi’s sound designer on Tiny Keep, we decided it was a game that had to happen.
We initially wanted to do the 7-Day Roguelike jam, but both Phi and Jey were hustling for a milestone and had no time. Then Ludum Dare came round again, and incredibly, the theme was “Beneath The Surface”. The stars had aligned, and SUBLEVEL ZERO was born.
The Dream Team
Phi got together The Dream Team. Literally, actually, since our 3D artist was Gary Lloyd of Hypersloth, the team making first person exploration game Dream. With myself, Phi, Jey, Gary and Phi’s composer Will Bedford, the team was complete.
As I’ll note later, the team worked really well. That Sublevel Zero is as good as it is, is a testament to the skill and dedication of everyone involved. It was a pleasure working with these guys, and I’d do so again in a heart beat.
Phi focused on level generation code, and I focused on gameplay code. I won’t say too much more about the dev process or the game specifics – Phi’s own earlier post-mortem here is a great intro, so please read that! However, I thought it would be nice to supply my own thoughts, and focus on the gameplay instead of procedural generation. Furthermore, we’ve since produced V2 with many tweaks and a few additions, including Oculus Rift support.
Basically, I’m hugely proud of this. It’s an astounding amount of content for a game made in 72 hours. But so many of the mechanics and features were thrown in at the last minute – so while it’s a testament to the whole team that things more often than not just worked first time, it does mean that much of it lacks polish. So, here’s the traditional rundown of good, bad, lessons learned and so forth.
What Went Well
Unity: As with last time, Unity was a godsend to allow us to do this much in this little time. I’m also a lot better at using it than before, increasing my own productivity.
Teamwork: Having more people was great, and we worked really well together. Everyone was on skype constantly, and communication was excellent. No politics, no drama, no bullshit. An unexpectedly well-oiled team from the get-go!
Basic mechanics: Simply put, the game works. Yeah, it’s got some rough edges, but the core concept is fun and works really well.
Art, sound music: These three aspects are just incredible for a game made on this timescale, and all credit goes to Gary, Jey and Will respectively. We’ve had a lot of really positive comments on all of these.
Level generation: That we got this working, and essentially on the first day, amazes me still. It’s a really nice feature, and means we have essentially infinite playability. Again, all credit to Phi.
First person cockpit: Having a true Descent-style cockpit with 3D HUD was essential to getting the feel right, and was worth the effort. Especially when playing on the Oculus Rift.
Enemies: Sublevel Zero has seven different enemies. That’s a lot. Three with lasers, two with missiles, a minelayer and a melee bot. Put together with the procedural level generation there’s a fair bit of variety. The tiny laser enemy in particular, I think, works well. It’s frustrating (it’s supposed to be) and while it does little damage, can make you hugely vulnerable in a room full of enemies as its constant harassment stops your shields from recharging.
Weapons: Oh, and five player weapons. Lasers, minigun, spreadfire, railgun and missiles. All with their own graphics, sounds and stats. Nice.
Stats: To add to the roguelike feel, the player receives stat boosts by levelling up and collecting stat pickups. Almost every aspect of the player and their weapons can be buffed this way.
Code: What I’m perhaps most surprised about is how good the code is. I mean, it’s not production quality, but it’s not the total mess that I would expect game jam code to be. As a resuilt, tweaking, bugfixing and adding features post-jam has been really painless. Not sure how we managed that one, honestly.
XBox controller support: I decided to include XBox controls from the get-go, and I’m really glad I did. It was worth the extra effort.
General polish: There are some nice touches. I’m quite proud of how enemies (and the player) drift out of control before exploding, the rotation of the pickups and things like that.
What Went Not-So-Well
Integration: It was often a struggle integrating everyone’s work in the time available. Assets weren’t too bad, but code was a bit of a nightmare. Having 2 coders made things possible, but it was difficult. Since we didn’t set up a Git or Mercurial repo, integrating my code and Phi’s was a manual effort and often went wrong, wasting entire hours. Added to that, Phi’s upload speeds meant there were further hours (literally) waiting for file transfers.
Testing input code: Unity’s input code is a bit opaque, and though I thought I’d made sure mouse input didn’t depend on framerate, I was wrong. The result was that on some systems, mouse control was super sensitive (unplayably so). We weren’t aware of this until after submission, so that probably cost us a bit. I ended up doing a fix which more ‘manually’ handled mouse input.
Balance: The downside of including so much content in the time was that it was horribly balanced. The railgun was incredibly overpowered, health and energy pickups are far too abundant and many other issues. While many people struggled with the controls (apparently more from a lack of 6DOF experience than the mouse issue), those who didn’t found it relatively easy.
Complexity: The other downside, actually, is trying to explain it all to the player. Which we didn’t. So there are a lot of features which aren’t obvious at all. What does energy do? How does the shield mechanic work? Am I actually damaging this red thing, and is it actually the reactor? What are my stats at the moment? Why do these tiny blue ships hate me so entirely? Some of this is fixed in the latest version, but it’s still a lot to take in with no tutorial. The length of this post-mortem speaks to the sheer number of elements as well.
Level generation: As above, that we have procedural generation at all is really impressive, and that it works well even more so. But we were inherently limited in this aspect, since in the timeframe we couldn’t do anything other than a basic tree-style algorithm. This means there are no loops, there’s lots of backtracking and it’s super-easy to get lost.
Enemies: The AI is super-simple. Once you’ve worked out how they react, you can easily defeat an entire room full of them.
Roguelikeness: While they’re cool features, the roguelike elements don’t end up adding a lot. They’re not clear enough and the effects aren’t always apparent. The player doesn’t end up feeling more powerful as they go along. Partly I think this is the basic design – since the gameplay is hectic, there’s no loot, just automatic buffs – so the player never gets to compare their options and really see what the differences are. But the other half is just the implementation, since the player gets minimal feedback on this process anyway. It’d be really helpful to have a stats screen where the player can see their progress.
Missing features: Despite the complexity, there were features we didn’t manage to put in which actually wouldn’t add to complexity but would improve things immeasurably. The two main ones being the core Descent mechanics of key-and-lock “puzzles” and escaping the facility after blowing up the reactor. Players understand these tropes without explanation, and they would have made gameplay enormously more fun, more focused and more rewarding.
General polish: We missed out on basic but crucial aspects like screen-shake and more feedback for the player on things like their shield status etc. While less quantifiable than the features we did include, these would have made the overall experience much better.
Version control: Always use it, even for tiny things! The biggest single waste of time by far was manually integrating projects. We would literally have had about 4 more hours to polish, minus perhaps 1 to set that stuff up. A serious percentage on such a short project.
Learn a better input solution: Many people have recommended InControl, a third-party input library for Unity. I’ve been meaning to put this into the other game when I get a chance, but having not done so yet I decided it was safer to go with the in-built Unity stuff I already knew. So I should make sure that next time, I already do know a better solution.
Prioritize features: Rather than make 7 different enemies, 5 weapons and go all-out on the roguelike elements, the game itself would have benefitted far more from key-and-lock mechanics and so on.
Write shorter blog posts: …yeah.
Well, that was a lot. The TL;DR is that Sublevel Zero is a huge accomplishment for all of us, and a fantastic proof-of-concept for this game idea. With a proper development cycle, Sublevel Zero could be really good. The ‘bad’ bits of this post-mortem are mostly down to the time limit than failings on our part, if you’ll allow me some hubris, so given the context it’s a great little game (and you should play it now).
Notes, feet, whatever
 including knowing about more pitfalls to avoid…
 more accurately, it has a couple of not-rough edges
 Phi and I do actually get some credit here though: Phi designed the GUI/HUD, which is one of my favourite parts of the game – it fits the feel perfectly and it’s just cool. I made the explosion particle systems, which again fit nicely even though they were really simple.
 see Gravity Assist’s source code…
 I threw it together in less than an hour at 3AM, and for that I think it’s surprisingly good. I.e.: it works at all.
 You are, however, screwed if you get backed into a corner.