I could have titled this post “Flawless victory!”
Or at least something along those lines (let us not get cocky here…).
First thing first, this post is going to be a pretty big one, so if you would rather see the game and play it, you can find it at the link below (Source, Windows and Linux64 at the moment, more platforms to come).
With that out of the way let us get down to business, shall we?
What went right
Most of the Ludum Dare, for a change. But in more or less chronological order…
- Theme & Idea : At first, as usual, the theme did leave me scratching my head. Most probably because I had started formulating a very cool idea for “End of the World”, which I thought would be picked because of the date. But it was not to be, and I had to find something else. I did not want to shoehorn my idea into the theme somehow, so I started by scouring the Internet for ideas. I wanted something a little more original than casting the player as an archetypal video game villain. The answer came from Wikipedia and its disambiguation page for “villain”. A game idea fell right into place as soon as I had read a particular page. You can either play the game and beat it to find out what it is about, or I will give you the link at the bottom of this post if you want to spoil yourself. But nevertheless, it was really a good find, and really fit the theme (guess what the V. in Raoul V. actually stands for?).
- A roguelike! : I have wanted to make a roguelike(-ish) game for quite a while now, so I was thrilled to see that my idea actually could be implemented as one. And it was the right way to go. I could have done it as a first-person 3D game, but I am pretty sure I would not have finished in time. So not only did I have the opportunity to code a small roguelike, it was very much instrumental in achieving the next point…
- Proper scoping : This is what I always did wrong in my previous attempts. Except maybe for OUT OF HERE, but I had the idea for that one way before the LD, and even then I completely shoehorned the theme via an ugly wall of text. Here, I managed to implement all the core features of my initial design. Except for one thing, which is handling a restart after the game is over. But more on that particular point later. The point is that my idea was very much doable in the time frame of 48 hours, without really skimping on anything.
- Letting features drop like flies : This sounds at odd with the preceding point, but what I mean is that, as usual, I continued to came up with new features and refinements as I progressed. One such thing was a minimap. I implemented one, but turns out that the particular way I went about it slowed the game down to a crawl. So, instead of trying to push forward and lose a big chunk of time, I simply dropped the feature. Same thing for my level generation, I ended up leaving the first, somewhat “buggy” version in the final game. By buggy I do not mean that it crashes, but simply that it gave different results than I had planned. So be it, it was playable, and actually doing what I had in mind would have been really too much work. Several things like that didn’t make the cut, but I never mourned them for long. And that meant I got a game done.
- Procedural everything : The map, but also the combination of elements that make up the NPCs, and the notes revealing information on your target are all procedurally generated. It does tend to feel a bit same-ey, but it was a great way to keep the game interesting for multiple playthroughs.
- Mixing known and unknown tools : I went partly against common sense, and decided at the very last minute (meaning after I had actually started writing code) to use Cocos2D instead of pure Pyglet. I had never used Cocos2D, but as it was based on something I was quite familiar with, it went rather well. The only downside of Cocos2D is that while it is a Python library, almost all the documentation you can find on the net is aimed at its mobile ports, and more specifically the iOS one. That made the learning experience quite a bit harder, but as I was able to fall back on Pyglet for things like sound (which I never got Cocos2D to play…), it never became a showstopper. And in the process, I have become proficient with a new API. Success!
- Pixel art : I suck at art. No, really. But I am still happy of the graphics for my game. The neat thing is that I was able to work the setting of my theme into a constraint that eased the creation of a coherent art style. And I am quite pleased of my characters. With more time, I would refine the aesthetics, and improve the readability of the graphics, but for my skill level I really think I did quite ok. That I even had time to revisit my initial tile set was just icing on the cake.
- Music and sound : After my attempts at playing a sound effect with Cocos2D fell through, I shelved the idea of putting sound into the game (and it would have been more or less justified by the “silent film” motif of the game), but I went back later and succeeded. I quickly whipped up a couple of music tracks and went along with it. I would have loved to make a piano-based score, but my MIDI keyboard was having troubles and so I fell back on my trusty guitar and my drums (for the sound effect), which I filtered to have an “old telephone” sound to them. All in all I do not think I have spent more than 15 minutes on actually creating the sound, and as everyone will tell you : sound ties a game together.
- Coherence : I think the game fits together nicely. Everything plays off the same theme, and the game mechanics relate to the historical facts (albeit loosely). I worked a goat or two in there (in the written text), there is some flavor text on some of the notes, and all in all nothing seems too out of place. Even the dialogues improve (or their presentation at least) the impression of you playing in a silent movie. So there, very happy with that.
- Blogging, Twitter, etc. : While I did not post as much as I would have loved to (not to mention I did not have someone dedicated to documenting the process as I had for my last participation in the jam), I still managed to post some screens, check out the IRC, Twitter, and even record a timelapse! This last one is a first for me, and both days are actually uploaded on Youtube, and embedded at the bottom of this post. I also commented and “hearted” here and there, and there are now a bunch of entries I really look forward to playing!
- Packaging the goods : PyInstaller has become pure awesomeness. If you are using Python and have access to your target platforms, use it, it is really great, and version 2.0 really makes things a breeze.
…That is a lot. To conclude, the most important point : I submitted a game, not a half-broken prototype!
What went wrong
All is not sunshine and rainbows though, and there are definitely things I could have handled better.
- Awful code architecture : As if that was not a given in Ludum Dare games? Still, because of my inexperience with Cocos2D, I ended up digging myself into a design hole, and had to spend several hours at the end of saturday and sunday morning cleaning up the mess. At the end it turned out ok, but I could have polished the game a little bit more if I had that time left.
- Not having everything ready : I almost failed at creating music because of problems with my MIDI keyboard. I should have tested all my things prior to the compo, and not leave anything untested until the last quarter of the time. At least I managed to record my guitar and my drums without any problem.
- A couple of bugs : Unfortunately, there is, to my knowledge, a single bug that could potentially prevent you for playing or winning the game. Sometimes, the level generator will create a room sealed off from the rest of the level, and if you or your target end up being put there, you might as well restart the game. Speaking of which…
- The missing features : I really wanted to get the restart working, but thanks to my crappy code architecture, it was almost impossible without yet another rewrite, for which I had no time. This means that the game will exit rather unceremoniously after the end screen. And you have to relaunch it if you want to have another go. The game also should have provided a way to look back at the notes you collected. Right now, you will need to use paper or your memory to keep track of the information. It should also have warned you when you killed the wrong guy. At least it will be evident when you have shot the good one. Lastly, the full screen mode (which is provided by default by Cocos2D) does not work correctly in regard to aiming. That is quite the bummer.
So, there you have it. I think the only way to improve on these is to continue practicing making games, and probably to collect some kind of base code which enforces a sane structure rather than throwing code around and see if it sticks together.
I think you have had enough to read, right? So instead, here are the two parts of my timelapse. The image quality is poor, I need to improve my timelapse-fu. I had also planned to make an “IRL” timelapse synced with the screenshots, but that did not work out. Enjoy!
This weekend was a blast. With everything going smoothly, it managed to be a very interesting learning experience, while being incredibly rewarding. For now, I will leave the game be while I rate other entries, and I will also provide an OSX version, as well as one for 32 bits Linux. Thank you for reading, and have fun playing…
Spoiler : You can check the Wikipedia article from which my idea came. Meet the real Raoul V.
Over and out!
- Bastien ‘Grungi Ankhfire’ Gorissen [@b_gorissen]