Andrew Russell is an independent game developer from Australia; he developed Dark for the 2009 Dream Build Play contest and more recently released Light Blocks for iPhone and iPad. Last weekend I had the opportunity to talk with Andrew about his newest project: ExEn, an implementation of XNA for the Silverlight and iOS platforms.
Josh Petrie: Tell me a bit about yourself and the ExEn project. You’re an indie game developer, right?
Andrew Russell: Yup. Let’s see… I got a degree as a software engineer, then decided I’d rather do indie game development, and since then I’ve pretty much been using XNA exclusively. I dabbled a bit with OpenGL and stuff, while I was at university.
My last major game was Dark, which was an entry in Dream Build Play 2009, which I then released onto Xbox Live Indie Games after the competition. My current game is Captain Stretchy–Arms. When I was designing CSA, I really had touch–input in mind – and of course the best (or at least most popular) place to do that is on the iPhone.
One of the big inspirations for CSA was Canabalt, and that runs on the web and on iPhone. So I figured, “why can’t I do the same thing?” I’d heard about SilverSprite and XnaTouch to make games run on those platforms respectively.
Up until that point I’d been telling people, “Hey XNA is so cool – and it runs on so many platforms like Silverlight and iOS!” Anyway when I actually went to use those things myself for CSA, I was very disappointed.
JP: How so?
AR: I mean – the libraries work – but they just don’t work very well. I started with SilverSprite – I basically put together a project with all my code and the SilverSprite library in place of XNA. That didn’t take long. And then I ran it, and it didn’t run.
So I had to go through and pull out a few bits and pieces that were throwing exceptions and so on, and then it ran. But all the graphics were messed up. Sprites were being drawn in the wrong place, textures had weird artifacts on them (premultiplication bugs, specifically) and most of all the performance was really bad – maybe ten frames per second.
JP: I gather that your experiences with XnaTouch were similarly disappointing, then?
AR: Well, it was at that point I decided that I’d make a fork of SilverSprite internally. I had downloaded and looked over the XnaTouch source code, but I hadn’t used it yet. But because of SilverSprite I was prepared for the worst. So forking SilverSprite allowed me to basically fix it. Which was a much bigger task than I had anticipated – I had to learn how Silverlight worked (which was something I had actually hoped to avoid).
It was one of those things that, I guess, started out looking like a small project – and it turned into a big one. At this point, by the way, my Silverlight implementation wasn’t a drop–in replacement for XNA. What I had actually implemented was a scene graph that had a Silverlight implementation and an XNA implementation.
I had my little test–bed application (the “Cat Girls!” thing on my website) running on Silverlight and I went to port it to iPhone. It actually went a lot better than SilverSprite – I guess because on iOS you get OpenGL, so an XNA implementation is actually pretty straightforward.
It was still buggy – but now I was prepared because of what happened with SilverSprite. For example, two of the major bugs I found with XnaTouch… first of all there was a bug in its matrix calculations so all my sprites were also drawn in the wrong place there. And there was a performance bug in the startup and loading code, the upshot of which was that it would load so slowly that, if run in debug mode, iOS would kill the game because it started too slowly. In fact, even in release mode, it barely started in the available time.
So those two bugs gave me a reason to start fiddling with the XnaTouch code as well… and I’d see all these other areas where there was huge room for performance improvement and so on. By the time I was done I had basically rewritten huge sections of it. So now it’s a lot faster and has fewer bugs.
To test out this system before using it on Captain Stretchy–Arms, I made Light Blocks, which is a simple falling–block game that has become my go–to game for learning and testing new technology. I must have remade it about five times over the last decade or so.
Anyway, that works, gets released on the App Store…
JP: At this point you haven’t decided to call this derivative project ExEn yet, right? It’s still just kind of a fork of the other two APIs with major rewrites?
AR: Well, when I first decided “I’ll stop using the official code for these libraries, I’ll make my own,” also decided “I’ll call this the ‘ExEn’ library.” But I didn’t intend to make that public.
JP:
It seems most of the best OSS projects start that way… not intending to be released. I think thats what helps contribute to the problem you described on your blog, the problem where SilverSprite, etc, were uncomfortable to use for production work.
AR: That is one of the big reasons why I don’t want to just toss this out there. ExEn still has its own problems – unimplemented bits, even a bug! It’s not ready for production work, and there’s quite a bit of effort involved in getting it up to that standard.
JP: You’ve written a lot of games, is ExEn the first piece of middleware you’ll have released?
AR: Yes. I’ve always had this problem myself – and I see a lot of beginning developers with this problem – where they make some big complicated “engine” – or at least try to. Since making that mistake myself in a big way, I’ve said “you know, indie developers, you are not in the middleware business.”
JP: Yeah – that is a subject that is very near to my heart. My “write games, not engines” article is hands–down the most re–linked thing I’ve ever written. But I think your approach is still very grounded in “what does somebody really need out of this API to make a game?” instead of “loop through every interface in the API, implement interface.”
AR: Yeah. I think that one of the lessons from ExEn is: making middleware is really easy if you’re just implementing someone else’s API. And half your code was written by somebody else, and you’re only implementing a small subset (in ExEn’s case, the 2D API).
So – I’m not exactly following my own advice on this one. But that’s another reason why I’m doing the funding thing and making it open source: because I knew people would find ExEn useful. The idea of licensing it came to mind but then I don’t want to run around managing all of that.
Anyway, so after all this had happened I figured, “well, that’s done, back to work on CSA.” At this stage my Silverlight code was not really an XNA implementation, just a scene graph. I had seen SilverSprite’s attempt to implement the XNA API in Silverlight and it was, well, a huge mess and very slow because of the difficulty of matching up draw calls with objects in the scene graph (I wrote a big article about this on my site).
But I realized that, through implementing the scene graph and using it in a finished game, I had gained enough knowledge now to properly implement the actual XNA API (immediate–mode rendering instead of a retained–mode scene graph).
So I did. It was around then that I thought, “I’ve got a complete solution that works really well, that people will want to use.”
JP: What is the biggest difference – performance–wise – in ExEn versus the other APIs you’ve tried? You’ve mentioned that SilverSprite and XnaTouch were slow. What were they doing that was so slow that you were able to fix?
AR: Wow… where to start? The biggest performance win in the whole thing was getting ExEn to run in entirely on the hardware–accelerated path on Silverlight. As well as… there are many ways to structure your scene in Silverlight – and some of them are much faster than others. It has to do with how much of Silverlight’s scene graph gets “touched” when you modify it.
You can do it where you modify the position of a sprite on the Silverlight canvas and it causes a relayout of everything, or you can make it so it only redoes layout on the thing you’re actually modifying. It basically involved a lot of experimentation, researching how Silverlight worked internally, and profiling. Finally the way that I update the scene graph on (I guess), “my side” has been heavily optimized – SilverSprite was doing a lot of unnecessary work.
On XnaTouch the changes were much less exciting. The vast majority of it has been more micro–optimizations, rather than big structural changes or changes in technique. Not reallocating a buffer here, using a smaller vertex format there, using vertex arrays properly. Probably the biggest win is in startup time. I found that XnaTouch was doing a lot of unnecessary work at startup, so I removed that. And of course on an iPhone you want your startup to be fast. I got it down from like fifteen seconds to three.
JP: That’s a pretty big improvement.
AR: And entirely necessary. iOS kills you at twenty seconds, so if you ever want to debug your game (MonoTouch uses a soft debugger), you’ve got to start up in time even with debug settings. That was pretty much my starting point on iOS: “Hey, I can’t debug this, I’ll have to go in and start fixing stuff.”
JP: You’re still sitting on top of MonoTouch on iOS, I assume?
AR: Yes, I use MonoTouch, because that’s by far the best way to get C# running. The downside is that it costs $400. But on the other hand, with the App Store, you’ve got plenty of opportunity to make your money back, and you really do save that in production time. Actually that’s one of the huge things about ExEn.
JP: The time savings?
AR:You write and test your game in XNA, and it just magically runs on the iPhone.
JP: I saw your fifteen minute port video, it was pretty impressive. Very well put together, too – did you have to rehearse it a lot or did you just wing it?
AR: Thanks! Yes, with that video, that was a lot of scripting and rehearsal. But it was a single unedited take. I did cheat a little bit and use a few code snippets I had prepared earlier, too. But I made sure to limit that to the section where I was updating the XNA game itself, rather than doing the actual porting. I like to think of it as a “cooking show” style video.
To put it into perspective, when I first did the port it took about three hours. That included making all those graphics, figuring out what sound files match with what sound effect names, and so on.
JP: It does a good job of showcase how easy it is to build for all the supported platforms though, presuming you stay within the confines of the API subset that ExEn supports. Speaking of which, is there anything missing from ExEn you consider really critical?
AR: All the really critical things that are missing are things I intend to fix up before release. They’re just little things that I haven’t used in my own games, so I haven’t implemented yet – but I would absolutely want to have implemented before doing a public release (as we were discussing before). For example, I haven’t implemented XNA’s sprite sorting modes, because I don’t use them, or SoundEffect’s MasterVolume property. Those are going to be implemented as part of the release.
JP: Do you have a roadmap for future development, beyond just getting the Android support built out?
AR: I don’t really have a roadmap, as such. I’d like to see what the community thinks, and I don’t want to commit myself to more features than I can implement as part of this current funding process. At this stage it’s just completing what’s already there – which is certainly enough for a 2D game.
JP: Do you ever intend to support 3D rendering, or are you strictly going to focus on the 2D subset?
AR: I’d really like to implement 3D rendering, especially on iOS because it looks kinda fun. So far I’ve focused on 2D because it’s what I use and it’s obviously a lot easier to do. The other reason is that it’s what Silverlight 3 supports. I’d like to see what Silverlight 5’s hardware–accelerated 3D is like, before I think too much about 3D.
But at the same time I don’t really have a problem saying “no this isn’t implemented because it’s too hard to do, or performs badly, or something,” and putting the onus on the game developer to modify their game code to suit the library. I’d much rather have a small and solid library than one that tries to do everything that XNA does.
To give you an example, there’s no support for render targets or viewports in ExEn on Silverlight. It can be done, but it causes a whole lot of rendering to happen through the software path, and so it’s a lot slower, and it requires doing special–case stuff through the rest of the rendering code. So rather than implementing them – badly – myself, I’d rather say to the game developer, “it’s not implemented, here’s why, you should find an alternate solution.”
JP: So you’re essentially making your API hard to use incorrectly.
AR: Yes. I’m prioritizing my work toward features that actually will work well.
On iOS those things are possible, but I haven’t implemented them yet, because my main priority so far has been to keep the functionality in sync between iOS and Silverlight.
I have no idea what Silverlight 5’s rendering will be like – I have just heard the announcement that it will have hardware–accelerated, immediate–mode 3D rendering. On iOS the difference is between OpenGL ES 1.1 (no shaders, works everywhere) and 2.0 (works only on newer devices).
JP: And you support 1.1?
AR: Yes, at the moment I use only 1.1, which is good enough for the time being but adding a 2.0 path is important, particularly if 3D support is added. Also if I port to desktop OpenGL for a potential Mac port, 2.0 is a closer match to that.
JP: Is an OS X port an actual long–term goal, just an idea?
AR: If I had just kept ExEn internally, I wouldn’t be doing an OS X port – at least not in the foreseeable future. Maybe if I became super famous and had a game on Steam or something, I’d do it then. But I figured while I’m porting to Android, why not take this opportunity to also port to Mac – but only if I can make enough through crowd funding to justify the time required to do that.
JP: How is the crowd funding going? What’s your experience with RocketHub been so far?
AR: I started out wanting to use Kickstarter, because that’s where all the “cool kids” go. But they don’t support international projects – this is my first time doing any kind of crowd funding, by the way. RocketHub itself seems to be a fine website – nothing really special to report good or bad. It seemed like the best out of the alternatives.
JP: Are you making the kind of progress towards your funding goal that you’d hoped?
AR: The crowd funding itself seems to have slowed right down after a good start, but I suspect that’s because I launched it right before Christmas.
I had hoped to launch it in early December, but it took a lot longer than I thought to do up the videos and everything – it was a toss up between getting it out as soon as possible, or avoiding Christmas and New Year’s. Before new years it was “on track,” and I was pretty pleased to have 10% of the funding at 10% of the time available. Then I went away for nearly a week to see family, and in that time, while I wasn’t around to promote it, it slowed down to nothing. But now it’s picking back up again.
So I am still confident that it will hit the $10,000 required for launch – there’s still a lot of time left. Ideally I’d like to see it hit $12,000 so that I can do that OS X port. I really appreciate everyone who has contributed to ExEn so far. I know it’s kind of an unusual project, so thank you.
Andrew’s goal is to raise $10,000 in the next few months in order to fund the remaining development work necessary to release ExEn as an open source library, one that would undoubtedly help many indie developers deploy their games to a much wider audience with much less effort than they’d need to put forth today – take a look at the ExEn project page and see what you can do to help out.