Quick Thoughts on this LD

What Went Well

In general, the process for programming this game seemed to go really smoothly - perhaps I've finally done enough work with vectors and such that writing this sort of physics engine isn't too bad. I'm really pleased with how smoothly it works too - the movements feel quite natural and are workable for a player. Granted, I think this was helped by the physics engine not being very ambitious: it does rectangles and circles and nothing else, but that seems to suffice. Plus, the code around this engine is not so horrible for the speed at which it was written - a lot of the features from recent C++ standards were a boon in developing this.

I liked working with WebAssembly too - the ability to deploy code so quickly is quite convenient, as I'd always found packaging code to really suck in a short time frame and that's basically entirely eliminated in this approach. I was almost surprised at how seamless it was to transition from writing for actual platforms to WebAssembly.

I'm very pleased with how the music came out - especially since I was able too sit down and pound out a loop of a little more than 2 minutes in a little more than 2 hours. It was nice to do this early, since it set some amount of mood for the game going forward.

I did a lot of polishing working prior to really fleshing out the gameplay. I'm not exactly sure how this worked out for the gameplay, but it sure made the process feel smoother - no last minute scrambles for assets or for code to put things together. Plus, I think I saved myself time by writing the code right the first time so that it could support some nice flourishes rather than having to go back and hack things in.

What Didn't

Well, setting aside graphics which are a perpetual source of trouble, I had a fair amount of difficulty with using WebAssembly, which is a new technology to me. The big two issues were in compilation time and debugging - the project is rather small, given that most the game-specific code was written in a day, and the engine itself was largely written in the three days prior to that, yet it took about a minute to compile each time! Plus, I haven't worked out a practical way to debug WebAssembly - I had been relying on Chrome's debugger to work well, but it's not very useful to try debugging when you can't see variable names and when pointers print as their literal values - and long compilation times made it hard to debug by printing from the code.

There are definitely some issues that I think are something to do with my use of WebAssembly, though - the frame-rate seemed perfectly good most of the time, except for occasional spikes in lag. I'm not so pleased with that, since it certain worsens the game experience, but it's not overwhelmingly prominent.

I didn't really feel like my level design is so good - it feels like I made levels just because a game needs levels, rather than because I had anything really clever to do with them. I'm concerned that my game might not do enough to teach players the mechanics - but we'll see. I also definitely felt limited by the tooling I had for level design - everything had to be hard-coded, but this meant that testing was a pain (because it took at least a minute to test event any change - though I was smart enough to add a level skip button this time around) - and it also involved a lot of data entry. I worked out everything on graph paper prior to coding it. I also think that a lot of the "fun" of platforming games comes from fluid sequences of motions - which is hard to do without a lot of tweaking. I also started to feel that my frame was too small to accomplish a lot - scrolling would have been helpful to implement, and not really that hard, except for the issue with entering data. It also occurred to me only very late that, since I was hardcoding things, I didn't need to invest time in building a level framework that would support serialization - it was a lot easier to make interesting things happen in levels once I realized that I could just store all the information in opaque function objects since nothing ever left the C++ context. I spent a really large amount of time on making levels, so it's a bit of a shame that it didn't work out better.

Things to Add To My Toolchain

  1. Generation for Level Data: It would be nice to have a tool for inputting lots of coordinate data - even something as simple as "draw rectangles, get output in desired format" would be great. Heck, even without serialization/deserialization, a tool that would spit out the source code to hard code that kind of data would be great. I know there's lots of tools out there for generating this sort of level data, but I'm not familiar with any.

  2. Proper compilation for WebAssembly: I'm sure a lot of my compilation woes would have been solved by building separate object files and linking them at the end of the build, rather than feeding the entire source to the compiler each time around. This wouldn't be so hard to accomplish by changing my Makefile, but I just didn't have the time to learn to do this during the competition.

  3. Debugging for WebAssembly: I'll have to look into whether a gdb-like tool exists for WebAssembly - it seems like Chrome's facilities for this are still quite new and not yet well-featured. It might just be a matter of time before good debuggers become standard.

  4. Integration of C++ with Javascript: One thing that would be really excellent would be to learn to use Javascript together with C++ - if I could have made it so that Javascript would talk to C++ well enough to "write" level in Javascript, I think I would have saved a lot of time and opened new possibilities; it just strikes me that "use an interpreted language" is a nice middle-ground between "hard code stuff" and "load levels from files" since it leaves open all the customization of a programming language, without the pain of hard-coded assets.

  5. Some sort of sound generator that's not bfxr: I generally find that bfxr conflicts with my aesthetic preferences for audio; I like to make sounds with smooth envelopes and lots of reverb, which is not really what bfxr is good at. I might have to think about writing something for this purpose.