I recently participated in the Github Gameoff game jam back in November. I did not finish my game, but had a playable prototype (or maybe tech demo is a better term): Foxback.


I finally had some time and energy last November when the Github Gameoff was taking place, and decided last minute to participate. I was eager and excited to get going on a new project since my last game jam.

I started with very little: I wanted to continue targeting Clojurescript+WebGL using a custom engine (albeit using Three.JS for some corner cutting). I failed to get a playable MVP last time, but this game jam was a month long and I am stubborn. I didn't have a game idea when the jam started, but I knew I wanted to attempt a 3D game and likely wanted to attempt a platformer. I knew I had to keep it simple and started work on the engine basics while I tried to flesh out a mechanic/narrative/hook.

A week in after some discussion with my partners, I was reminded of the old vector based arcade games, and thought this would be a fun achievable aesthetic. Furthermore I thought a mechanic that used the fading phosphor glow and tracing time would be fun: something along the lines of controlling when objects are drawn and being able to move through them, or having to wait for a platform to be drawn before jumping. As for content, I found a cute fox on Google Poly and thought, "eh, why the hell not? A fox 'thrown back' into a retro vector forest" and started trying to get an engine working with that model.

What went right.

I took a break from engine programming two weeks in to work on rigging and animating the fox model. While a bad decision for getting a quick prototype, it felt like something I personally needed as I was starting to get a little discouraged and burnt out. Animating was a lot of fun, and I was extremely happy with the final result. Watching all those Youtube animation videos certainly paid off :D:D:D. There was something very zen about getting lost in making the walk cycle believable, natural, and fluid.

I wanted to adapt a scene based approach for the engine, and after stumbling upon GLTF, I thought this would be a great fit: I could create the scene in Blender, attach properties as needed, and import and use in the engine. While this took me longer than I would have liked (bugs in exporters, not full import support), it ended up working well! This came in very handy when I was crunching to get a playable level ready for the deadline--I was able to copy-pasta a level in Blender in a few hours that "just worked" when loaded into the engine. Awesome.

I also added namespace support to node names which allowed me to use "group" properties in the scene definition: a group could be added, and any entity in that namespace would receive those properties, and this namespace support was also extended to the collision system to reduce superfluous collision events firing by ignoring entities in the same group, such as overlapping ground blocks.

What went wrong.

NIH (not invented here) syndrome and stubbornness. I still tried to make an immutable, functional, from-scratch Clojurescript game engine and spent too much time and energy in building the needed components, and trying to solve problems in an idiomatic way. I waited too long to cave into a "just get it done" attitude. When I did things went much faster and much smoother (albeit with ugly spaghetti code).

I also hit some last minute bugs with my physics code. I didn't do semi-fixed timesteps on physics propagation which resulted in lags causing annoying things like pushing the character through the floor and into the void. I'm really surprised no one reported it, even though I'm sure people were effected (especially on older hardware). Especially disappointed since I am aware of it and even had this in my last game jam entry.

Relying on GLTF for a scene format worked well in the end, but relying on a third-party Blender export plugin proved stressful. I was bouncing back and forth between two different ones, but hit bugs with both. Luckily [in the spirit of Github and FOSS], I filed some bug reports and had some responses with the Kupoman exporter that I was able to get working well enough after some patches.

Further, while I tried to use Three.JS again to cut corners with respect to rendering backend, Three.JS is very much idiomatic Javascript and is not afraid of mutation. To keep my other code pure I had to work hard to isolate it, which took time and complexity. I finally gave up on isolation and purity the last week, and was able to actually get some stuff done.

All this time wasted meant I never got to play with the aesthetic and visual effects and mechanic I was excited about implementing. I had platforming available and just went with that.

What went ...okay?

I had read about devcards for Clojurescript and was really excited to attempt using them when developing this game. The last game jam I was forced to refresh my game to try new changes. Devcards should help me solve this, as it ties better into figwheel's hot code reloading, which meant changes to engine code would be automatically compiled and loaded without needing to reset state or refresh the page. I could also make small cards to test new features and this should ease debugging when I accidentally broke something. I got this up and running and have to say it's a great library for Clojurescript! It came in handy when trying to debug the signals library, and the introspection came in extremely handy for debugging various other things as well.

...however, I didn't use it to it's full potential. After some initial cards like "test loading OBJ" and "test spawning cube" I just had the single "load the main scene" card I kept using. Further, if I needed to change the initial state or change the state data layout (adding a new attribute, renaming an attribute, etc), I'd need to reload anyways and I hit a lot of errors related to running out WebGL contexts from this. I didn't take the time to find a good solution to this. As devcards added some overhead, it became more of a hindrance later in the project: large scenes lagged heavily, and averaged maybe 20 fps, and often triggered the physics bug mentioned above. Loading the raw page without devcards would see a fairly stable 60 fps, but made debugging things difficult, or relying on sprinkling println in the code.

But, devcards are still awesome and worth checking out if you write Clojurescript.


Adding another unfinished project to my list really made me introspective. What did I want to accomplish? I wanted to make a game, sure, but did I want to be an engine programmer? Make content? Make demos? I at least wanted to start making a portfolio of prototypes and demos, and maybe someday make a full-fledged game, but I also enjoy getting my hands dirty and trying to do some crazy things like, "can I make a game using functional immutable programming?". It was interesting to try some things like: oh, this ECS thing is really interesting, and a data-driven approach seems like a great fit for an immutable language like Clojure, what would an idiomatic ECS look like? or maybe FRP is good fit for an event system. These were fun and educational challenges, and I certainly like my "signals" based approach (where the game-loop is a fold of the game-state onto an event stream), but these little victories are also stuck in unfinished demos and tied to a framework and language most people wouldn't use, made by someone lacking a big picture view of game development and experience with what makes a finished game.

After playing so many awesome games submitted for the jam, I finally accepted that even if I wanted to continue to push game engine technology, or do crazy things, I needed a better grasp on what modern game engines are capable of and what/how they do the things they do. I also needed wins, and I needed finished demos and prototypes. This is my hobby and I want it to be my art--I can't produce works while forcing myself to always build it from scratch with crazy handicaps added as well.

So, where's the middle ground? Well, I've done the original technology approach many times, so I decided to learn a modern game engine, and have started to work with Godot following their 3.0 release (which includes C#, yay!). I've actually been having fun with it, and with the 3.0 release, I feel I can contribute just by writing about what I'm doing, and they certainly need help documenting the C# API.

I also think I want to start adopting a tick-tock approach to my projects (similar to Intel's tick-tock architecture releases).

Tick: using what I have and what I know, try and make a new game demo/prototype. Focus on polish and completeness and working faster and smarter. Good time to finish a previous project or experiment.

Tock: experiment. Try something new and crazy and see if I can make it work. New visual effect, new FSM approach, new event loop, whatever. Indulge that side of curiosity.

At the conclusion of the jam, I was also made aware of #1GAM, as someone tweeted about their intent to make a follow-up for it. #1GAM, being a "make a game a month" personal challenge seemed like a good framework and motivator for this approach. The website explaining the challenge also had an amazing write-up with suggestions how to accomplish this.

Oh, and did I mention there's a version of Clojure that runs on CLR? Or that Godot is open source and I can start digging around in its internals? How interesting ;D

Let's see if I can make this work.