Cross-posted from my blog:
So, this past weekend I participated in the 22nd Ludum Dare competition. You have just 48 hours over the weekend in which to create a game. The crux of the competition is that you create all code and content within that 48 hour period. No re-used assets at all. Only engine/middleware/framework code is permitted to be prepared beforehand.
I wrote my game with Unity. It’s the first project I’ve ever undertaken in Unity, and I had very little experience of it. I came out of the other side with a very positive impression, I really liked using it. As much as I love C/C++; given the time constraints, it seemed a good idea to go with Unity. The other big upside is that you can deploy the game to be played via a web browser. This was definitely what I wanted. I didn’t want people to have to go to the hassle of a download-and-install, just to play the little toy game I made over a weekend.
I wrote a turn-based strategy RPG game. My inspiration was the “Shining Force” series of games. The theme of Ludum Dare this time was “Alone”; every game submitted had to follow this theme. This obviously doesn’t fit the team-based gameplay of Shining Force, but mine has a twist. You just play as a single character. It just takes the combat part of those RPG games, there’s no walking around and talking to villagers. There is a shop to purchase and sell items between battles, but that’s it.
Here’s a link to play the finished game:
I was disappointed with what I ended up with, mostly due to how much work I had to squeeze into the time. In my eyes the game had two major failings:
- A lack of polish. The art is my placeholder art, and the GUI is the default-Unity GUI.
- Little game balancing. The first world is decently balanced, but after that it gets way too easy. The game is completely procedurally-generated. I just didn’t have the time to playtest it.
The biggest achievement though was:
- I wrote a game in 48 hours, that’s actually playable; and a little bit fun!
That’s my introduction out of the way. Now, onto the postmortem…
What Went Right?
- Choosing an idea which I’d see through to the end. I actually lost most of the first two hours to thinking over what type of game I’d do. The theme ‘Alone’ was tricky for me, as most of the ideas I had before it was announced didn’t fit it. I ended up taking one of those ideas and simplified it. In retrospect doing a full-blown party of player characters would have been ridiculously hard to do in 48 hours. But yeah, I was excited by the idea and that helped me keep my motivation.
- Using a higher level language like C#. Considering the game didn’t make too much use of Unity-specific ‘scene’ features, and was mostly generated in code; I could have had similar results using something like XNA instead. Either way, this sort of rapid development lends itself to something higher-level like C#. Out of habit, I think I would have been too anal about my code if I wrote it in C++. C# just lets you throw caution to the wind that little bit easier!
- Enemy AI. Pretty close to “Shining Force”’s enemy AI. It slotted in well to the turn system I had set up; so it followed the same rules and states the player had. The turn system I wrote had its positives and negatives, but since I left the AI to pretty late on, I’m happy I spent the time earlier making the turn system generic.
- The UI. I left it to pretty late on. I hate coding UI. I’m glad though I just used the stock Unity functions and didn’t try any fancy rendering techniques. I went for the basics, and that was the right decision. I’d hoped I’d get the chance at the end during the polish phase to ‘skin’ it, but I had no polish phase.
- Save and load. Lost close to an hour implementing it, but it’s a pretty cool feature. It autosaves after each battle (Unity stores web-app info on your hard-drive, so it’s transparent). I also got in a crude Base64 load/save screen, to bring your save to other computers.
- Bug free? Well, it seems to be for me. I kept it in a pretty stable condition, considering the game’s complexity and reliance on procedural generation, and AI.
- Food, drink, and breaks. I think I was sensible with what I ate and drank. I took pretty regular short breaks. Even if it was to just chill on the sofa with a notepad for five minutes, and plan out my next coding session. I’m not a coffee or energy-drink guy, so just cups of tea kept me going. I’m unsure how I wasn’t totally fatigued by the end, I’m guessing it was adrenaline.
- The ‘all nighter’. It saved me from not finishing. I’m an optimist when it comes to scheduling time. Re-reading my journal log, I hardly meet any of my set goals (but to be honest I did surprise myself with getting ‘unscheduled’ stuff done really quickly). If I’d had lost say, another five hours to a second nap, there is no way I’d have had a functional game come submission time.
- Placeholder work. Crappy art, blocks instead of characters, a checkerboard playing area for 90% of development. These sorts of things meant I had systems playable sooner. This helps my motivation, there’s nothing worse than building up to a point, where you’ve seen nothing on screen and hoping ‘everything will work out at the end’…. And then it inevitably doesn’t. My longest blind-coding run without actually seeing anything on the screen working, was about half an hour; for the turn system. Everything was short and sweet to rapidly iterate on.
- The audio. I think it went well. I dropped in the sound effects just after the halfway point, which provided good battling feedback, with the lack of particles/visual effects. The music I also procedurally generated. I lucked out with some good classical piano pieces which fit the style of game well. The voiceovers by the wife I threw in at the last minute. They worked out well, but I’d have liked to try and fix the audio balance between her and the music a bit more.
- Not caring about the code quality. It’s awful. Terribly hacked-about stuff that reminds me of the sort of thing I’d have written in college. I however still coded pretty defensively though. I just didn’t worry about things like commenting, and whitespace/indentation being off. Fix something ‘properly’, or throw in a sure-fire hack? A no brainer. I also committed many cardinal sins with global static singletons, instead of jumping through Unity’s component hoops. My typing fingers thanked me!
- Stand-up desk. I have an IKEA Jerker desk. It’s not adjustable, but I have a high stool which I use when I need a rest. Being able to constantly switch between two was awesome. When I’d feel lethargic in the chair, I could stand. When my feet got tired of the standing, I’d be able to take a load off and sit. I probably was about 50/50 in each position, time-wise.
- No internet distractions. I know some people who do these completions regularly like to use Twitter and IRC extensively during the dev time. I’m a bit of a procrastinator; those sorts of things can be a big timesink. I told myself I would just check my emails on my cellphone, and do nothing more than that. It worked out well. I’m real surprised that I didn’t feed my Chaos Engine addiction, throughout the whole 48 hours!
What Went Wrong?
- I left some important features until way near the end. In particular the attack logic I rushed through, such that it doesn’t scale into later battles. Enemy placement and the map terrain generation I did with less than two hours to go. I should have had all the procedural-generation stuff done very early, and other risky things like the battle logic calculations too. Instead I did the bread-and-butter stuff that’s hard to get wrong first, and did the risky stuff later.
- Very little playtesting. It’s a slow game to play through to test leveling into later battles. I should have made leveling stats deterministic and had some way of starting myself off in the later, harder battles to test balancing.
- Graphics/art. I spent hardly any time at all on the graphics. I can’t draw for shit, but I can usually fudge things to look very aesthetically pleasing despite that lack of talent. I didn’t even get any time to try that.
- A lack of preparation. I’d planned each day during the week prior to “look at Unity tonight”. I hadn’t got around to it. So I had to learn as I went. Some aspects like hooking up audio took a little longer than they would have, if I knew how to do it beforehand. I also found myself dropping in and out of the ‘component’ model that Unity has for objects, because it didn’t ‘click’ for me until a few hours in. I think I would have likely pen-and-paper planned out my components to be better organized, than the ad-hoc mess they ended up as.
- AOE (area-of-effect) magic; stuff that affects more than one tile. Probably lost a couple of hours spread over the whole period, to implementing it, and dealing with fallout from it. I envisioned it as being useful in later battles when there are tons of enemies; which drove me to add it in the first place. It’s a shame later battles are such a walkover, which kind of renders it just a time-saving device.
- I started working at about 11am on the Saturday, after about five hours of sleep. I took it easy in the morning, and watched some football as I coded. That time was actually pretty productive. I then carried on for well over 24 hours and worked up to the 6pm deadline the next day. I really didn’t feel too tired, but my productivity certainly slowed. I didn’t have many bugs to fix, but one in particular was niggling in the last four hours. I only fixed it shortly before submission. I think with a fresher head, I’d probably have not caused the bug in the first place.
- UI and state machines. I hate coding UI. I hate coding state machines. This game had plenty of both. I’m surprised it didn’t demotivate me. State machines always seem such a chore. So much code for what has very simple intentions. Scripting languages can make this a lot easier with their micro-threading capabilities. I remember reading something about C# and the ‘yield’ statement lending itself well to state machines, but it’s a little less straightforward to grok. I should have probably checked that out again.
- The scope. Too big. Too ambitious. Given my lack of preparation too, it was silly to think I could do the idea justice in less than 48 hours. I had a good stab at it, though.
“Picasso” – Look at that work of art!
My TODO List At The End
I had to prioritize the last few tasks, so I inevitably had some on the cutting room floor. Here are the features I really wanted to add:
- Particle effects on attacks. I’d seen some demos of particles in Unity, and they looked really simple to set up. A good bang-for-buck. Didn’t even give it a slight look.
- More/better character graphics. I also rushed through naming and giving stats to the enemies that did make it in. The art in the game isn’t good, and I don’t think I’d have made it that much better; but I’d have liked to added more varied enemies for sure. I think I probably spent a grand total of about twenty minutes the whole project (if that), making art.
- I had functionality to ‘slow’ the player movement over harsh terrain, and collision for impassable squares. I always planned to procedurally generate the terrain, but I didn’t get the chance to hook this stuff up. Impassable squares would have been tricky, in order to avoid blocking the player out of areas. ‘Slow’ terrain though wouldn’t have been much work.
- Healing spells for enemies. ‘Buff’ and ‘debuff’ spells for the hero player, as well as the enemies. Similar ‘buff’ and ‘debuff’ items to use as well. Some of the turn-logic for this sort of thing was in place; it would have probably taken less than an hour to add these.
- A better looking GUI. I’d have liked to try changing the font and colour used. I did Google search at one point, but it looked pretty involved, and would require me to go through all my UI code and hookup references to a ‘GUISkin’. Probably not much time to do at all, but every minute counted at this stage.
Of course, all of these things still fall way below ‘fixing the balancing’, and some other things mentioned in the “What went wrong” section. The Perlin-noise, colored and textured terrain was actually a wishlist item for me originally. I wonder if I’d have left that on the wishlist, I would have been able to fix the balancing?
In all, I enjoyed the experience. I was disappointed that the game I was intending to be challenging and provide seemingly ‘endless hours’ of battling, only holds up for about ten minutes. But I had fun coding something that quickly under a time pressure. Sure, the code looks absolutely horrible, but it’s a thrilling experience just churning out stuff at that speed, and having it all come together.
I would consider doing another Ludum Dare in future, but I’d definitely want to do more preparation. I’d also certainly scope my idea much better. I think a shorter, tighter game is the way to go. Something that would be doable with two ‘sleeps’ in there as well. I’d like to get a good twelve hours of sleep next time, instead of five!
My Journal Log
You’ll notice the log ends at about 2pm, four hours before my 6pm deadline. That last four hours was just a whirlwind, the time flew by ridiculously fast!
I found it pretty useful to keep this log. It helped with motivation, and helped me focus on what I should be doing next.
I also have half a dozen mini-notepads full of ramblings about movement, AI, and the turn system. Taking a break from the computer and sitting down with a pad and paper is pretty valuable. Just gives you time to refocus, so you don’t just sit there coding down a blind alley.
My Time-lapse Video
~38 hours in ~4 minutes:
The first session was about 10 hours; the second session was about 28.