Global Game Jam 2017 Postmortem: Flipwrecked

So I went to Global Game Jam 2017 with only one real goal: Write a game in Rust, using ggez. My previous game jams had all been Ludum Dare, which is very much an exercise of one lone madman trying to do everything, while it turns out that GGJ is much more of a team-based endeavour. I had no team already built, so I swiftly judged my chances of getting a team together with such a dev environment to be pretty low.

The theme was “Waves”. It’s a good theme! After brainstorming and BS’ing with all the other unattached programmers, I came up with a game idea I liked and thought I could implement, and went off all on my lonesome to do it. To my surprise a couple other coders wanted to help, and to my greater surprise they weren’t completely turned off by the prospect of using Rust and a, shall we say, quite young game framework. One of them had played around with Rust but not managed to climb the wall of the borrow checker yet and was happy to work with someone who had. As he put it, “all my coworkers are going to laugh when I tell them what I did this weekend.” The other was a complete newbie to Rust but was game to dive in.

So, after 48 hours, we actually ended up with a game! Didn’t win any prizes for it, but with three coders, no actual artists or other content-type people, and a toolset that is honestly pretty darn spartan compared to any professional game engine (jammin’ games like it’s 2003 again!), I think we did pretty well anyway. (And props to Daniel Cohen for making us awesome music! Even if I made the mistake of getting it into the game early; I still hear the first four bars of it in my sleep…)

Game available here: Flipwrecked!

Rust

Rust was darn painless to use, honestly. Even the semi-learned and completely new teammates I was working with had minimal problems with it. Though with a 48 hour game, we really only made one scene in the game and not a whole lot of complex interactions, so there were very few opportunities for the borrow checker to make life tricky. But rustup got people’s compilers working easily, cargo got libraries working (excepting C dll’s), all that basic stuff that’s so painful in many other languages. By pure chance we had one person using Linux, one using Windows, and one using Mac, so we had the full spread of platforms, and it worked pretty much flawlessly and identically on all of them. The only hiccup was having to install MSVC build tools on the Windows system.

Dream come true there, really.

One entertaining fact is that we ended up with the game running at about 0.5 FPS in Debug mode and 300 FPS in Release mode, so we just ended up always building in Release mode by default. Fortunately we didn’t need to do too much debugging! At first I thought that LLVM must be doing some kind of bleak space magic to make this possible, but lore from the Rust IRC channels suggested that it’s more just that Debug mode generates very pessimal code, and that “hopefully MIR will make it better.” Fair enough.

Another interesting tidbit is that removing a single ? from a tight inner drawing loop and replacing it with an “eh this Result will never fail, right?” ignored return value took the game from 275 FPS to 325. Not a significant difference, really; 0.6 microsceonds per frame. But still an interesting demonstration that Result handling is not free.

ggez

ggez also worked very well for the most part, and I actually got complements from my teammates on how easy it was to use. I saw them browsing the docs for it to find bits they needed to get stuff done, and seemed to more or less figure it out without problems. So huzzah, it works! Props to the LÖVE game engine for making a pretty sweet API for me to steal. :-D

Were there bugs in it? Of course there were! …though surprisingly few of them to be honest, and now that I look at them… they’re actually all in SDL2. Either in the Rust binding, because SDL2 defines its memory use so poorly that it’s very hard to map to Rust’s expectations, or just outright things that didn’t work. In order of discovery…

(Yes I need to do some hunting and replication and then actually submit them to the sdl2 crate maintainers. Sigh.)

I had to apologize to Ralith in #rust-gamedev , ’cause he badmouths SDL whenever it comes up and I end up defending it. I mean, it’s been what I’ve been using for gamedev off and on for 15 years, it can’t be THAT bad, right? Well, yes, unfortunately it can. So, making ggez be pure Rust and getting away from depending on SDL is now high priority for me. At least then it’ll be easier to build and distribute, and if there’s bugs we have a prayer of hunting them down and fixing them.

There WAS one actual change I had to make in ggez; it started out as an experiment I was playing with before the game jam, and I think my experiences with the game jam itself more or less confirmed it:

It’s basically one of the few parts where translating the Love2D API into Rust didn’t work well. Ah well, they can’t all be winners.

Overall, though? GREAT SUCCESS.

Next steps

RIP AND TEAR! Specifically, get as much SDL2 code out of ggez as is feasible, and replace it all with pure Rust. Before I was worried about degrading functionality; for instance, SDL2 runs on Android and iOS, while getting Rust to go on those platforms is pretty painful, and SDL2 handles controller input, which glutin (the best-so-far pure-Rust window management library) does not. But if that functionality is bloody broken anyway, then there’s not much downside.

But I think I need a break from game dev for a bit. Maybe in a couple weeks.