Categories
Game Development Game Jams Software Development

Ludum Dare 41 Postmortem

Ludum Dare 41 came to an end just a little more than a week ago. I believe I’ve finally recovered from the mayhem and come through the better in the end.

Project Status

Unfortunately, my Ludum Dare 41 project, a “turn-based AI battle-royale game” called “Turn-by-Turn Deathmatch” was not finished when the 72-hour deadline hit. This was, unfortunately, my expectation for this one. I may continue working on the game in the future, but I am particularly averse to the theme and not satisfied with the idea that I was able to come up with.

The Theme

My struggle for this Ludum Dare originated at the outset of the theme announcement. The theme for 41 was “combine two incompatible genres.” I know a lot of people had differing opinions on this, but it is mine that it is the worst theme yet. For those of us that are relatively new to the game-design scene, the theme is asking us to throw out any convention of design that we may have relied upon to make a game that is not a complete flop. For those more experienced, I will grant that it does provide a unique challenge, and for that reason I was almost somewhat conflicted. That said, it is my opinion that Ludum Dare should be welcoming to new developers, as Ludum Dare is often some of the first exposures to the indie game dev scene that they will get. It should be a good impression. I believe this theme, by significantly raising the difficulty of creating a workable concept, likely created a bad first experience for them.

I created a very large, very time-costly spreadsheet of an incomplete list of game genres in an adjacency-martrix-like spreadsheet, which ranked the combination of any two genres as “good,” “neutral,” or “bad” based on how well it fit the theme, which is to say that a “good” combination was two genres that one would not expect to see combined. Even with this chart, I found myself struggling to come up with a theme, because as it turned out, many of the “good” combinations sounded like awful games, or they required some complexity that I knew would take longer than the deadline. For example, I really wanted to do a “first-person platformer,” which would be a 3D game where you basically see something like Super Mario from Mario’s eyes. It’s been done before, and I recall positive reception. Unfortunately, my 3D-focused game engine did not have a completed rendering engine, and with 3D being somewhat new territory for me, I scrapped that idea. Eventually I came up with combining “turn-based” and “shooter” and then eventually I realized that “shooter” could be replaced with “battle-royale” if the enemies are roughly equally equipped and trying to kill each other as well. I thought it was a neat concept, but I also knew that I had minimal experience with AI, and no experience with turn-based games. I was also looking at just over 24 hours left on the deadline when I had the theme nailed down, so I knew it would be a big challenge.

The Technical Struggle

I wanted to go into this jam using my custom 2D game engine, ArcticWolf. I saw this as an opportunity to, as I did last time, use the game jam as a sort of excuse and motivation to further my progress on the mundane core subsystems of my game engines. I had intended to work out a simple painterly blitting rendering engine, because I thought it would be the most straightforward design where the least issues could crop up. What I did not realize, however, was that rendering things in the correct order being mandatory in a painterly renderer, would actually prove to be a nightmare of a challenge.

In C++ there is no STL container that allows indexed access and automatically organizes them based on a comparison. There is a container called std::priority_queue, but that will only provide access to the front element in the queue. This could work if we rebuilt the entire rendering queue every frame, but I knew that would be a huge detriment to the performance of the game, since elements would not be frequently (probably never) changing their z-indices, and therefore what I really wanted was a std::priority_vector.

Well, I hate to break this to you all, but no such thing as std::priority_vector exists. So I made one. In the ArcticWolf code, there is a class called aw::PriorityVector, which does everything that I needed. It took a lot of work, but it is one of the pieces of my creation during this game jam that I am the most proud of. It’s very simple, and all it does is store elements into the vector in the correct order based on a comparison type, the same that you might pass to std::sort. If the attributes defining the comparable values of the contained objects change, there’s a method that allows reordering the entire container, which is expensive, but useful if z-indices change. Another couple of useful helper classes were created to be used with this: aw::PointerGreater and aw::PointerLess. They are equivalent to std::greater and std::less, but they dereference each element being compared. This was necessary because the aw::Renderable class was polymorphic and referenced via pointer only, which meant the usual comparisons would have actually compared their addresses, not their values.

The main technical struggle, however, was in the complexity of my ambitious rendering engine. I decided it to render a scene which contains polymorphic layer objects, each of which can contain a polymorphic aw::Renderer and a bunch of objects that contain aw::Renderables, getting passed as pointers back to the aw::Renderer when the layer is rendered. With this system, I could have a base that is a tile map, representing the game world (which I also intended to allow multiple layers with different parallax values to make it a 2.5D engine if I wanted), and then a sprite layer on top of that into which the player and other entities would be placed, and then a UI layer on top of that which uses a rendering pattern similar to HTML5 DOM.

I spent a lot of time on this rendering code, and I am glad to say that I made quite a bit of progress in the process, but it also means that I didn’t have enough time as the idea that I had would have required. I was able to get the preloading and menu completed, but not much beyond that. I actually ended up trying to temporarily bail on the new rendering engine and write raw rendering code within the last 12 hours of the jam as a last-ditch effort to get a workable game by the deadline, but by that point I had not slept in a long while and I didn’t have the focus to keep myself awake.

At some point, I decided that this jam and its very undesirable theme was not worth the suffering. I remember waking up with my face down on my laptop, completely disoriented, with the morning sun shining brightly on me, and at that point I decided to close the project on the ldjam website and go to sleep. I woke up at about 11PM that evening. So much for my sleep schedule.

Future Plans

I was quite disappointed in the theme for this Ludum Dare, and I can’t help but wonder if the reason we’ve started getting worse and worse themes over the last few years might be directly correlating to the improvements being made to the ldjam website and making voting easier. They received well in excess of three thousand votes for the theme, but based on past trends, I think we can expect approximately a third of those people to submit games. Thus, it seems likely that many of the people voting on the theme have little to no intention of making a game for it, and therefore they have no interest in making sure the theme is workable, reasonable, and doesn’t cut out new developers.

My suggestion of improvement would be to allow theme voting only for users with submitted, completed, and rated jam or compo submissions to vote. In my opinion this would drastically improve the themes. That said, I don’t think that is likely to happen. Given that, next Ludum Dare, I may or may not participate depending on the theme. If the trend of worsening themes continues, I will not be participating in Ludum Dare 42. Nonetheless, I do intend to do a game jam in August. That is not a question, what is a question is whether or not I will be following the chosen theme or the standard deadline. I’ve been toying with the idea of running my own week-long jam with a theme chosen by either myself or by taking one of the losing themes from a previous Ludum Dare. Obviously I’d lose out on some of the community features of Ludum Dare, but it would still provide more or less the same training effect, and I think in the course of a full week, I’d be able to create a more-than-trivial game design.