From Twins to Battlecruisers

Since our twins were born, I’ve had the graveyard shift, which often leaves me sleepless between midnight and 3:00AM. So, I finished Grand Theft Auto IV, watched Season 5 of The Wire, and even read a couple of books. Could I complete a (simple) game in this odd little pocket of spare time?

Well, no. But I could come close.

Inspirations

For those of you who don’t know, Manta is named for the aircraft in the classic 80s game Carrier Command. Carrier Command would be an almost laughably spare game by today’s standards — it featured about ten different 3D models (islands, for example, were frustrums with the sloping sides colored yellow and serving as beaches), flat shaded (remarkable for the time), and each no more than 50 polygons.

If we can't have 'em, we can blow 'em up.

At first I thought I’d try to clone Carrier Command (as others have tried) but it occurred to me that this would be surprisingly difficult, that the fun part of carrier command was flying Mantas, and that a lot of Carrier Command’s gameplay was badly broken anyway. That’s the problem with classic games — upon examination, they kind of suck.

So I decided to build a game about flying around and blowing stuff up. In other words, a 3D version of Xevious or Time Pilot 84. (Classic 80s games that actually don’t suck at all.)

Nothing as satisfying as blowing up a big round thing.

A lot of the 3D models aren’t incredibly original. (A few obvious Star Wars references just for starters.) That’s what you get when you build a game more-or-less single-handed in a few weeks, I guess. Besides, I think pretty much every shape for a spaceship has been tried several times over by now, and you really can’t beat triangles and circles.

Rapid Game Development

Also, to avoid problems I’d had with some earlier game projects, I decided to build the game from the gameplay out, and with rapid iterations to allow critical feedback. (I promised the others in the group that I would provide a complete working update at least once per week, and delivered. In fact, sometimes I would chat with Levan (the composer) and he’d complain about stuff and I would post new versions as we talked. It’s the gameplay, stupid.

Unity: Lessons Learned

I’ve been working with Unity for almost two years, but I didn’t really start to get it until a few months ago. Unity’s scripting engine sits on top of Mono, and the languages you have to pick from are a consequence of this. They are C#, which has many of the annoyances (i.e. verbosity) of Java; Boo, which has many of the annoyances of being someone’s hobby project; and “JavaScript”, which has the annoyance of not actually being JavaScript. These languages all compile and run fast, so the choices are mainly aesthetic (which syntax do you like) and a little bit functional (e.g. I recently discovered that Unity JavaScript’s implementation of polymorphism is broken).

So, learning Unity means getting to know its IDE, which is wonderful but very different (from anything), learning a new language (such as C# or Boo) or a strange implementation of a familiar one (JavaScript), and learning Unity’s and Mono’s APIs.

Unity’s class structure is very flat, or at least feels like it is. Almost every internal class is either a GameObject or a Component and every object has handles to directly attached objects, and very effective ways of getting handles to anything in its hierarchy. Getting at stuff outside the hierarchy is trickier. This is a clue… It turns out that subclassing when writing scripts is not a very effective approach.

My initial Unity code tended to involve writing a lot of fairly elaborate one-off classes. This turns out to be very hard to maintain.

When I started writing Manta, I was experimenting with polymorphism — e.g. there’s an abstract “Pilot” class that controls ships, a “Pilot_AI” that controls non-player ships, and a “Pilot_Player” that allows the user to control a ship. I ended up having a lot of trouble with JavaScript’s incomplete implementation of polymorphism (I still can’t figure out how to call an inherited method from an overriding one), but along the way realized that I was simply wasting my time.

Later in the Manta project I finally “got” how to code in Unity. Well, how I want to code in Unity anyway. The trick is to treat everything as a “helper” or “mixin” and ignore subclassing.

Let’s take a classic OO example. You create a vehicle class which has color and passenger capacity properties, and a driveTo method. Then you create two subclasses, car and plane. The plane needs a few flyTo method, and also a maximumAltitude property. Later you add a ship, and a subclass of ship called submarine.

More likely what happened was you wanted a car class but this is OO programming, so you built an abstract base class and then you build the class you really wanted and some half-thought-out additional class to prove it was all working.

In Unity what I’d do is build a car class. If I needed to create a plane class, I would do so. If I found out I needed to rip stuff out of car to make it work, I’d take that (say it’s the passenger handling component) and make it a separate class. Now I’ve got three classes — passenger_compartment, car, and plane. Later we add a submarine and then when I need ships I rip the ship bits out of submarine and make that a class.

Each of these classes’ instances can instantly detect which of their fellows that they might care about is present. So cars and planes can grab references to their passenger_compartments. This turns out to be a lot more natural in Unity, and also matches more closely how Unity’s internal classes work.

Cheetah 3D: Lessons Learned

I am not a “lush detail” kind of guy. I’ve tried a few times, but I’m just not built that way. If I produce a 3d model or a picture, it never really occurs to me what detail I would populate it with. With Project Weasel I wasted a lot of time trying to texture models, even though my early work used simple flat colors and baked lighting and looked great. With Manta being developed with a ridiculously short schedule I decided to stick with what comes natural — simple models with very simple textures and baked lighting maps. I think it worked well.

Another thing I still suck at is character animation. Part of it is my lack of skills (and patience), but part of it is also the tools I’m working with. Frankly, Cheetah 3D doesn’t cut it as a character animation program (at least, not as of version 4.6.2). I hope the next version will surprise me, but in the mean time I have been trying to learn Blender’s character rigging and animation tools, which seem to be extensive and good (and no more incomprehensible than any other serious 3d program). I will probably never do my modeling in Blender (Silo 3d and Cheetah are just so pleasant in comparison) but I will probably do my animation in Blender, and quite likely my rendering and baking too.

Results

Well, a beta of MANTA is available for play on the web. Maybe by the time you read this, there will be downloadable versions too. So you can see for yourself the results of about five months of midnight coding and modeling. I’m pretty happy with it, but there’s plenty of stuff I’d like to do before I try releasing this game as shareware (and possibly release an iPhone version).