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.
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).

Javascript Dick Waving FTW

Ars Technica’s rather gushy coverage of Squirrelfish Extreme (and the somewhat critical comments on that coverage) prompted me to do some of my own testing. Certainly, Squirrelfish Extreme keeps Webkit (and, ultimately, Safari) among the contenders for best endowed web browser, but my results were a little less definitive.

Google’s V8 benchmark suite is here. The Sunspider benchmark suite is here. Domaeo (the Mozilla test suite) is here. You might like to check them out in a few browsers. I just tried the current Safari release, the current Firefox release, and the Webkit Nightly Build. As I understand it, the Webkit speed claims are based on testing the JavaScript engines in isolation from the command line. Of course, very few folks run JavaScript this way…

The following are my very slipshod results obtained by firing up browsers and trying each benchmark once or twice. (I wasn’t careful about shutting stuff down, minimizing background activity, closing extra tabs, etc.)

Google’s V8 Benchmark Suite

This set of benchmarks takes less time to run and appears to be less thorough. (It certainly produces less immediately intelligible results… you just have to accept that big numbers are a good thing.)

Firefox 3.0.1 (OS X 10.5.5)

  • Score: 213
  • Richards: 226
  • DeltaBlue: 238
  • Crypto: 205
  • RayTrace: 162
  • EarleyBoyer: 245

Safari 3.1.2 (OS X 10.5.5)

  • Score: 218
  • Richards: 124
  • DeltaBlue: 173
  • Crypto: 187
  • RayTrace: 309
  • EarleyBoyer: 401

WebKit r36685 (OS X 10.5.5)

  • Score: 1312
  • Richards: 1317
  • DeltaBlue: 990
  • Crypto: 2553
  • RayTrace: 575
  • EarleyBoyer: 2035

This is just wonderful. (I tried to download a Firefox Nightly to check out Tracemonkey for myself but figuring out how took more than ten seconds, so I gave up. Here are some stats from Windows (note that these are running under VMWare Fusion, so it’s not fair to compare to the Mac figures directly).

Firefox 3.0.1 (Windows XP Professional/VMWare Fusion)

  • Score: 208
  • Richards: 207
  • DeltaBlue: 264
  • Crypto: 157
  • RayTrace: 180
  • EarleyBoyer: 251

Google Chrome (Windows XP Professional/VMWare Fusion)

  • Score: 2117
  • Richards: 2593
  • DeltaBlue: 2482
  • Crypto: 1692
  • RayTrace: 1456
  • EarleyBoyer: 2685

Internet Explorer 8.0 Beta 2

Note: IE8 interrupts each run with a “script is running slowly” dialog. I tried to click this off as quickly as I could but it definitely hurt the benchmark slightly. I ran it three times, dismissing the dialog as quickly as possible and took the best score.

  • Score: 58
  • Richards: 47
  • DeltaBlue: 52
  • Crypto: 50
  • RayTrace: 69
  • EarleyBoyer: 75

Sunspider

Sunspider’s results are really detailed, and I’m not going to post the whole things here, but I got the following bottom line results from a single run of each. In the Webkit case, this was with half a dozen tabs open (including this blog entry), while Chrome had two tabs open, one of which was displaying the results of its earlier benchmark (not very taxing, I expect).

Webkit r36685: 1614.6ms +/- 7.5% (running native under OS X)

Google Chrome: 1458.2ms +/- 0.4% (running under XP/VMWare; yes, faster is better)

Dromaeo Results

Again, the results are very detailed and also seem very real world (they use code from a lot of widely used JavaScript libraries such as ExtJS, Dojo, and Yahoo Widgets as part of the suite). You can see them for yourself here (Webkit) and here (Chrome). During the Chrome run, Chrome kind of seized up, whichwas probably Windows XP’s fault. So the overall result may be garbage, but if you look at the details you’ll find that V8 is clearly faster at some things and Squirrelfish at others. What this says to me is that both have quite a bit of headroom even yet.

Webkit r36685: 6652.60ms (running native under OSX)

Google Chrome: 10540.80ms (running under XP/VMWare)

So on both Google’s and Apple’s preferred benchmarks, I’m seeing better performance out of Google Chrome, but not by much. Dromaeo, which is a very DOM-intensive suite and also appears the most comprehensive, favors Webkit. (And, yes, IE8 is pitiful. No, I am not going to try Sunspider or Dromaeo on IE8.)

The really annoying thing is that Apple isn’t very aggressive about pushing advances in webkit out to the masses. Or, to put it another way, they use new versions of Safari to sell new versions of Mac OS X*. Chances are Squirrelfish Extreme‘s performance will be a key selling point of Snow Leopard when it ships, instead of a free upgrade to Safari, which is what it ought to be. In the mean time, we’ll probably need to use some other Webkit-based browser or Webkit Nightly, or simply use Firefox to enjoy better performance.

Note: as a comment — rather rudely — points out, Apple doesn’t charge for Safari upgrades. But it does hold new features back so it can announce them as though they were new OS features. (Edit: and, actually, it doesn’t support Safari on versions of Mac OS X before 10.4.x, so technically I was completely correct and the aptly named “bs” was full of bs.) A case in point is the debugging functionality added to Webkit over a year before it became available in Safari as part of Leopard. (And yes, you can get it for Tiger, but the marketing would have you believe it was a Leopard feature, and you simply can’t get it for Panther or earlier.)

And the really puzzling thing is that Microsoft seems to be happy to allow JavaScript performance to suck dog’s balls under IE8.

So, Javascript is fast now?

This site is the most interesting attempt I’ve found to seriously compare execution speed across languages. It should obviously be taken with more than a grain of salt since, apart from all the usual issues with benchmarks (artificiality, etc.), the quality of the code written in each language may vary greatly, as may the actual algorithms, and different algorithms may favor different languages, and different languages are used for different things and, obviously, benchmark comparisons try to force everything to do the same thing. Still, it is interesting.

Based on some quick spelunking, JavaScript (Spidermonkey) is comparable in speed to PHP or Ruby, perhaps a third as fast as Python, a fifth as fast as Lua, about a hundred times slower than Java, C# Mono, or Lisp, and a hundred and fifty or so times slower than C++.

What that says to me is that JavaScript should easily be able to get two or three times faster than Spidermonkey (because it has a lot in common with Python), but then it will get tough. It also speaks rather well of Lisp (which manages to be truly dynamic and still competitive with the big guns). Since it looks like Squirrelfish Extreme and V8 are both around twice as fast as Spidermonkey, and that if you took the best bits out of each from the detailed benchmarks and combined them you’d maybe get 50% faster again, it looks like we’re nearly out of low-hanging fruit in the JavaScript engine race.

The Best Programming Language Ever?

I was having a conversation at work today about what people’s tastes in programming languages were and there was some discussion about human readability, which led me to mention HyperTalk. HyperTalk was the programming language used by HyperCard, it had the virtue of being incredibly readable and (unlike the similarly readable AppleScript) also very easy to write. I mentioned that “whenever you see — used to denote a comment, there lies the ghost of HyperTalk” to which someone replied, “like in HTML?”.

An HTML comment is denoted by “<!–” and “–>” (note that WordPress is screwing this up, I really do know what HTML comments look like) which seems like a non-coincidence. Tim Berners Lee invented HTTP and HTML using NeXT computers, which didn’t run HyperCard, but which were spiritually related to the Mac, and it’s hard to imagine that HyperCard wasn’t a major influence on the design of the web.

HyperCard has the distinction of being one of the most influential programs ever written, perhaps the most. (Bill Atkinson wrote HyperCard and MacPaint, two of the most influential programs ever written. Photoshop is, essentially, MacPaint running on modern hardware.) Paul Allen spent a fortune cloning it (Toolbook) and it was clearly a huge influence on Visual Basic. Director’s Lingo started out as a straight clone of HyperTalk. Even 3D Studio Max’s MaxScript bears its mark. If we assume that the web was directly inspired by HyperCard — a not unreasonable assumption — that makes it perhaps the most influential  program ever written.

HyperCard was amazingly nice to code in. HyperCard 2 had a modern debugger, there was a third party compiler (written in HyperTalk that could compile to assembler), and it virtually never crashed. By default, all state was preserved (in fact, if you wanted to write a conventional application you had to jump through hoops to create “empty” documents). The main failing of HyperTalk was its lack of support for OO and functional programming (it was internally an object-oriented message-passing architecture, but you couldn’t build your own objects). It would be pretty simple to bolt that kind of functionality onto it, but no-one has, and HyperTalk has largely passed into obscurity.

Surprisingly, there are three modern HyperCard clones still being maintained. Toolbook has focused on authoring CBT, while Runtime Revolution tries to be all things to all people, and SuperCard is Mac only. Unfortunately, all seem pretty clunky by today’s standards. (And, frankly, for all its virtues, HyperCard was a bit clunky even when it was new. It never allowed you to build proper user interfaces.)

It would be interesting to see HyperTalk updated to support modern language features OR something like HyperCard built on top of a modern language like Python or Ruby. The obvious thing to do would be to build a web-based IDE on top of Django or Rails.