From C to Unity in Five Simple Years

Today is my second day of my latest attempt to use Unity. I'm going to try to document a lot of what I'm learning and seeing here. I will frequently be wrong and go down blind alleys, I'm sure, but that's how it goes with new technologies.

The decision to use Unity 3D is an about face for me, certainly.

I've been developing in C99 (no C++) almost exclusively for two years. Honestly, I think the majority of that time was spent writing memory management code. Not in some monolithic project -- just writing functions that initialize and free nested struct fields over and over and over. An attempt in August to port my project and its underlying cross platform library to use Samba's talloc library was the right thing done far too late.

There is a school of thought that says games should never dynamically allocate memory, and the reasoning is informed by more experience than I possess. But it's a hard requirement to meet, and nearly impossible to retrofit. For instance, the first piece of cross-platform C game code I wrote was a system to render text using texture atlases built using FreeType. If no dynamic allocations is the game, I just lost: FreeType, the texture atlas, the atlas regions, the hashmap of glyphs. It's hard to imagine doing things another way. I was so innocent then. I was just glad it worked. I didn't know.

A more realistic approach is to allocate no memory in your own code, and to use trusted libraries wherever a problem is intractable without dynamic allocation. A less realistic approach is to allocate no memory in your own code, except for all the libraries you wrote, which are also your own code.

I still believe C is a productive application development language, if the platform for that development is sufficiently strong. But the platform requirements for some of my prototypes (full 3D, huge amounts of dynamic geometry, custom asset pipeline, in-engine asset building tools with full GUI) were huge. Yes, I'm now referring to my last two projects, Pod and Quanta, as prototypes, after a combined 30 months of heavy development.

Lacking the tools to write 3D prototypes in days, I wrote them in months, predictably resulting in hard-to-ignore sunk costs and bottom-up game design. I didn't want them to be prototypes. In fact, considering the costs, I needed my prototypes to be home-runs. Predictably, they weren't.

Here's my greatest hits collection of huge unrealized prototypes:

Solarium. I wrote it in Java, using everything I knew about enterprise software development. That's not a joke, but it should be.

Such beautiful planets. So much data modelling. So much code.

Pod might contain the best rendering engine I will ever write. Its level of graphical fidelity was so high I could not afford to produce the assets for gameplay. I tried to go all-procedural: the asteroids were procedural down to the pixel. But in the end, fun gameplay is about more than modified ellipsoids. In gameplay terms, this engine was mated to...nothing. Can you make a game about nothing? Maybe Jerry Seinfeld could.

Writing your own game library in C is a stupid way to prototype complex games. There, I've said it, and now I can stop making stupid decisions forever.

Farewell, Quanta. We never knew what ye were.

I love these big, stupid projects. Looking at them breaks my heart. But the fact that they were essentially huge prototypes means that most of the time I spent on them was wasted, and crucially, I could duplicate the results if I had a game development business reason to. I don't. Not yet. Their legacy is a story, a shared universe that I never even began implementing. I need to tell that story. But I need more skills, experience, and cash to tell that story. I get it now. I think.

There are other space games in my brain, fighting to get out. I recently wrote a prototype in libgdx, which is maybe my favourite piece of code that I almost entirely didn't write. I can't say enough good things about libgdx, as a rapid game dev tool, as I've been using it for years in my saner moments. And I have a little game -- not quite a game, really, but already crazy fun. The prototype did its job. I have some big decisions to make.

I could carry on using libgdx, but it is a Java-based platform. I have huge reservations about Java as a runtime environment. No; "reservations" is not the right word. If I am done making stupid decisions, I'm not going to make my life harder by supporting a desktop client with JVM packaging, LWJGL, and everything about JNI you never wanted to know (but were afraid to ask). The JVM as a desktop environment is dead, killed by Oracle's focus on B2B, and Minecraft was its last hurrah.

I thought libgdx was a good idea because it supports so many other platforms: write Java, but run whatever gets you onto the platform in question. I was initially very keen on an HTML5 target via libgdx's excellent HTML5 support. I've tested my prototype on tablets and phones already, simply by connecting to my dev server over wifi. I've confirmed that a phone is a terrible platform for two-axis scrolling. I've also learned a lot about the game I am working on.

The first thing I learned is that it is not a casual game. It's an action game. It's a physics game. It's not for candy crushers and jewel beclickers. So the HTML5 target, a huge strength of libgdx, is irrelevant, and whether to continue with libgdx comes down to the strength of its support for other targets. As I said, desktop is out. Consoles are out (except for Ouya, I suppose). Android is in, but only Android tablets, as I mentioned. iPads are in via RoboVM.

I just don't know if that's enough. I want to reach the platforms where the players want to play my kind of game. If I want to switch toolkits, now's the time.

Unity's not-as-useful-as-it-looks scene editor, lack of nested prefabs, and not-quite-entity-system architecture are all decisions I wouldn't make. But I've already learned enough to work around them and get down to C#, which is the Java I always wanted. I need to make more game with less work. I need to focus on desktop for now but keep my options open in terms of platforms. I need to ship a game.

And if it doesn't work out, "Unity 3D developer" looks a hell of a lot better on my resume than "three years of development on a closed-source C library used in 0 shipped games."