UPDATE: This post was pretty popular. I've posted a followup This post was pretty popular. I've posted a followup here

After two months of Sol Trader development in Ruby, I took a difficult decision last Wednesday morning: I've decided to rewrite the game code from scratch in C++. Let me explain my reasons.

If you'd like to purchase Sol Trader you can now do so at soltrader.net

Why I did it

Slow frames: When working with Ruby, I use the excellent Gosu library to do all my game specific coding. This initially worked great, but occasionally I'd just get slow frames coming up. My game is timed to run at 60 frames per second, which means that each frame should take no more than 16.67ms to run. Yet every so often my profiling would come up with a frame that would take 25ms or 45ms for no discernible reason. I just couldn't find the issue here: I turned every sub system in the game off. I disabled garbage collection. I hacked my slow frame detection code into the simplest gosu sample I could find, and they still existed. I didn't feel like I could quite trust the stack to deliver the framerate I needed, and I hadn't yet put in half the features I wanted to.

Object explosion when bridging to C: A lot of the libraries I was using were written in C, and therefore there was several thousand objects (mostly floats) being created each frame to act as a bridge between Ruby and C code. It feels like that that CPU time should be better spent in the AI improving the quality of the simulation, or on better effects, rather than loading the garbage collection with an unnecessary burden.

Ease of packaging and distribution: I feel like packaging is going to be a lot easier. I'm not too bothered about hiding the source code: I may well do that anyway to purchasers of the game. It's the running on Windows I'm worried about: from my research it feels like it's going to take some effort to push the game out on a non-Unix platform. And with a video game, releasing on Windows is a must.

Manual memory management for performance: The garbage collection is still too stuttery under MRI (even with Ruby 1.9.3, which is a huge improvement on what's gone before) - it still stops the world each time. I looked at other implementations, and even considered learning all about garbage collection to help improve Ruby myself, but then realised that getting royally distracted wouldn't help me ship a working game.

What do I miss about Ruby?

I miss using RSpec hugely: There are ways of doing testing of C programs using RSpec but it doesn't feel like I want to wrap each of my C++ classes with a SWIG interface just to check they're working. I may still do this for some form of Cucumber testing, I'm not sure. I'm using UnitTest++ for my testing at the moment, which is very lightweight and good enough for my purposes.

Duck-typing: defining interfaces for everything is a pain in the backside, although it does force you to think more clearly about the roles of your classes.

Easy mockist testing: There's no built in reflection in C++ so it also makes you have to code to interfaces if you want to do any mockist testing. I'm mostly returning to a classist style of testing with small well defined groups of classes being tested at once. It's not a perfect system and I still have much learning to do here.

Terseness of syntax: There's just a lot more characters to type, and a lot more ceremony for each class. This tempts you to larger classes and methods, which I'm resisting at the moment. I need to take the time to set up c.vim exactly how I want it.

Funnily enough, I don't miss the automatic memory management: I like having that level of control. Old habits die hard.

So how far have I got?

Thankfully, it's not a complete rewrite as I'd already done a lot of thinking about the architecture and a lot of the basic classes translate directly over. I worked really hard at the end of last week and got a lot done:

I put in SDL to build the basic game framework: hopefully building on Windows will be a snap. I plan to have a working Windows build as soon as I can lay my hands on a cheap Windows 7 PC.

Basic testing using UnitTest++, with tests that are compiled and run as part of the build process.

Decoupled gameplay/physics updates from the graphical framerate using the techniques here. I have zero temporal aliasing bugs right now, which makes for a super smooth 300+ FPS graphic loop with a fixed 60FPS physics loop.

Re-imple