This post should be titled, "Why I fucked up by choosing Ruby to write a game." - Or "What the fuck was I thinking"
I love Ruby, I spend a lot of time writing it. I also write kids games for iOS. I would never consider Ruby(in it's current state) a good language to write a game in. Anyone who would has clearly; never written a game before; or never used Ruby for anything serious before.
I agree with the other posters, you should investigate ObjectiveC though. You can get ObjectiveC packaged and running on Windows BTW, don't worry about that.
While what you say may be 100% true you might be shocked by the number of Ruby and Python devs I talk to who tell me that Ruby can do anything that C++ does if you're even a half-decent Ruby or Python dev. I've literally asked people, "What about something like Gran Turismo 7?" And I've literally been in rooms where every dev there (none game devs, all web devs) basically said if they were writing it in Ruby it could be done, but they wouldn't trust Sony devs to be able to do it.
This may not be the case for all Ruby devs, but I think having these stories out there is still useful.
I've written lots of Ruby for things that are serious (large websites with lots of traffic), and I've worked as part of a team that built on commercially available games in C++ that sold lots of copies.
Ruby has come along enormously recently, especially with 1.9.3 and the other flavours that are out there now. I thought it might be worth trying it and advancing the state of the possible. Eventually I decided that actually shipping something was more important.
This post is mean, and has no place on Hacker News. It's fine to say there's no reason to ever use Ruby for a game, but it seems like the main purpose of your post is just to call into question the OP's intelligence and experience.
I think the author's problem is not choice of language, but rather choice of architecture. He notes that he was passing a lot of float objects between Ruby and C, eating up valuable garbage collection time. The problem here is not the bridging of Ruby to C, but rather the wrong choice of data structure and design. Ruby should pass high level requests to the (C-based) rendering backend; instead of passing "push a vertex at (1,2,3)", the requests should be like "draw a spaceship at (1,2,3) flying forward with velocity vector (1,1,0)". The means you're going to be writing the core of your game in C, but things like AI and level design will all be handled in Ruby. (I think pretty much every commercial game works like this.)
Another thought is to treat simulation and drawing as separate concerns. Every 1/60th of a second, interrupt the simulation and draw the current state to the screen. This means that you can do things that take more than one frame to calculate without reducing the framerate. (Does Ruby have a good coroutine library?)
Rewriting your entire game because your design is bad is silly. Switching to C++ just makes your mistakes less obvious. (And now you'll be debugging memory leaks and segfaults instead of slow frames. If only there was One Perfect Tool...)
After working 1.5 years on soft-realtime video processing systems (and game development fits this category), I feel like there's no real alternatives to C++. Because (1) when you have performance problems you can inspect the code in the disassembler and get full control of what's going on, and (2) compilers now are really smart (think msvc11 and gcc 4.6), so it just rarely make sense to sacrifice 10x speed for 3x increase in code brevity.
Of course, sometimes you have to dive even deeper, into asm or SSE intrinsics or OpenCL.
Nice write up. I wrote my own 2d game engine in C++ a while back. Switching to Ruby was great, but I never made any games. I did make a couple of JavaScript HTML 5 games. But here again speed is a limitation, and so am looking into C (and eventually Objective C) to eventually do some iPhone game making. As great as it would be to make games soley with scripting/interpreted languages, I don't think we're there yet.
I'm using SDL for writing a DJ application and have it cross-building on Linux, Windows, and the target platform (HP TouchPad).
For the Windows build I'm using the excellent http://www.mingw.org/ Mingw32 environment. I compiled SDL and my other needed libraries myself and there's pretty much no code differences.
The only downside to mingw32 is that my target platform has full POSIX and mingw32 doesn't, so sometimes I have to choose carefully to use stdlib functions and not a POSIX function.
A good takeaway from this is make your tests performance related. Since the op is using unitests already, a test that updated the game loop for a few minutes, rendering the target number of objects and failed if a frame dropped, would have saved a lot of wasted development.
Why were you trying to write a game in Ruby to start with? You didn't "switch back to C++", you simply realized you were trying to use a wrench to tight a philips screw…
As for what's "good performance," ask yourself: what's the clock speed of your CPU, and how much work are you really trying to do? Say you've got a 2 GHz CPU. A 300 FPS rate, is 2,000,000,000 Hz/300 Hz = 6.6 million clock ticks per frame, on a single core. A modern CPU can be really good about using those ticks very well. You can do some dumb blitting to figure out the I/O overhead for getting to the screen.
Speaking as a huge fan of Ruby, I think it's absolutely the wrong language to write games in, because games are enormously sensitive to runtime fluctuations, and as you found out, Ruby has them. In particular, a stop-the-world GC is just never going to give you satisfactory performance, unless every GC pass happens in <1ms and never happens more than once per frame.
That said, you might consider Lua as a primary scripting engine for your game. It's got a lot of your standard scripting language perks, but it's also obnoxiously fast and has an incremental garbage collector. Furthermore, there's no GIL, and it's designed to be embeddable, making it a very powerful choice for game development.
Seems to me that no matter what the language du jour may be, games are still often written in c++. When you're not getting the performance out of the tools you're using and you've spent some time trying to work around the problems, I think it's the right call to switch tools.
You might want to explore Lua as an alternative. Lots of games are written in Lua/C/C++ combo. Low level primitive routines in C/C++ and high level game stuff in Lua.
Writing everything in C++ is not my idea of fun. It's definitely possible to write almost all of the game code in a scripting language. It would be reasonably easy to abstract all the native APIs you want, but you could also just let someone else do it: http://love2d.org/
Of course you did, and I say that as a self-described Ruby programmer. What I really want to know is what gave you the idea that it might be a good idea to use Ruby for a project so obviously not suitable for Ruby?
ruby excels where time to market and RAD are more important than performance, and where the standard and other libraries work well. Ruby saves lots of time doing things like CRUD operations where you're basically mapping on set of fields to another in a predictable way. When performance and memory are an issue and you can't trivially scale your code (eg. More processes or more machines) C++ is a big win.
I looked at this, but the stop the world GC would still kill the frame rate from time to time sadly. Also there's a large amount of inefficiency in the object translation layer between the two languages.
UPDATE: In case anyone is interested, I've just added a screenshot to the blog post by (very) popular demand. It's not final artwork, and it's only a few days work!
I wonder if he gave Rubinius a go before switching to C++. IANAGD, but i'm guessing some of it's features would benefit game engines: Tunable GC, profiling (http://rubini.us/doc/en/tools/profiler/), JIT/LLVM. It wouldn't solve the C extension problem (maybe FFI does?) or distribution though.
No, I didn't. I love the features Rubinius gives you, but Windows support still needs a lot of work, and if I'd dived in to help, I'll never ship the game.
I wonder if switching to JRuby wouldn't have solved some of his problems? I'd imagine that distribution is much easier on JRuby. I suppose the issue is with libraries, but I'm not familiar with the libraries he mentioned.
Sounds like he's wanting to use a lot of native C++ libraries, so I imagine he'd still run into performance problems even if he found a way to use JNI with JRuby.
it's simple, ruby is about scale out, not scale up. and rails helps you to build websites faster. multi-player games would probably be very fast to write compared to c++, however, the code will certainly not be optimized as well as c++, it's an interpreted language for gadsakes!
The author seems to be more interested in obsessive technical improvements than shipping a game many people want to play. One slow frame out of sixty prompts a rewrite? Product doomed. Wait until someone complains to fix anything. Something tells me that frame should not be priority one, but it is. Why?
You are completely right for things that don't involve real-time video (like games do).
A 1/60 frame skip rate sounds like nothing important, but your eye will see it easily and it's instantly annoying. It's not subtle at all, and not something you can write off. Everyone will be annoyed by it and then your product will be doomed.
(Edit) I do however agree that the frame rate is not that important. 30 fps ought to be enough for anyone. However, it has to be a really really smooth 30 fps; all the frames need to come out exactly 1/30 of a second apart. Not realizing this is where a lot of people go wrong. A smooth 30 fps looks much better than 120 fps to a human eye. A game framerate that isn't an integer divisor of your monitor's refresh rate is also a disaster (since it means the display will be skipping frames).
[+] [-] frankPants|14 years ago|reply
I love Ruby, I spend a lot of time writing it. I also write kids games for iOS. I would never consider Ruby(in it's current state) a good language to write a game in. Anyone who would has clearly; never written a game before; or never used Ruby for anything serious before.
I agree with the other posters, you should investigate ObjectiveC though. You can get ObjectiveC packaged and running on Windows BTW, don't worry about that.
[+] [-] kenjackson|14 years ago|reply
This may not be the case for all Ruby devs, but I think having these stories out there is still useful.
[+] [-] chrismdp|14 years ago|reply
I've written lots of Ruby for things that are serious (large websites with lots of traffic), and I've worked as part of a team that built on commercially available games in C++ that sold lots of copies.
Ruby has come along enormously recently, especially with 1.9.3 and the other flavours that are out there now. I thought it might be worth trying it and advancing the state of the possible. Eventually I decided that actually shipping something was more important.
[+] [-] erikpukinskis|14 years ago|reply
[+] [-] jrockway|14 years ago|reply
Another thought is to treat simulation and drawing as separate concerns. Every 1/60th of a second, interrupt the simulation and draw the current state to the screen. This means that you can do things that take more than one frame to calculate without reducing the framerate. (Does Ruby have a good coroutine library?)
Rewriting your entire game because your design is bad is silly. Switching to C++ just makes your mistakes less obvious. (And now you'll be debugging memory leaks and segfaults instead of slow frames. If only there was One Perfect Tool...)
[+] [-] atomicdog|14 years ago|reply
Is it common for commercial games to write AI in Ruby now?
[+] [-] nevinera|14 years ago|reply
Because, while pounding in a few hundred nails with my trusty flathead, I noticed that it was taking really a great deal of work.
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] ansgri|14 years ago|reply
Of course, sometimes you have to dive even deeper, into asm or SSE intrinsics or OpenCL.
[+] [-] lelele|14 years ago|reply
[+] [-] boneheadmed|14 years ago|reply
[+] [-] chrismdp|14 years ago|reply
[+] [-] shaunxcode|14 years ago|reply
[+] [-] gravitronic|14 years ago|reply
For the Windows build I'm using the excellent http://www.mingw.org/ Mingw32 environment. I compiled SDL and my other needed libraries myself and there's pretty much no code differences.
The only downside to mingw32 is that my target platform has full POSIX and mingw32 doesn't, so sometimes I have to choose carefully to use stdlib functions and not a POSIX function.
[+] [-] andrewflnr|14 years ago|reply
[+] [-] justinhj|14 years ago|reply
[+] [-] levifig|14 years ago|reply
Why were you trying to write a game in Ruby to start with? You didn't "switch back to C++", you simply realized you were trying to use a wrench to tight a philips screw…
-.-
[+] [-] chrismdp|14 years ago|reply
[+] [-] lallysingh|14 years ago|reply
A quick list: http://nuverian.net/2011/01/17/the-best-game-engines-for-ind...
As for what's "good performance," ask yourself: what's the clock speed of your CPU, and how much work are you really trying to do? Say you've got a 2 GHz CPU. A 300 FPS rate, is 2,000,000,000 Hz/300 Hz = 6.6 million clock ticks per frame, on a single core. A modern CPU can be really good about using those ticks very well. You can do some dumb blitting to figure out the I/O overhead for getting to the screen.
[+] [-] chrismdp|14 years ago|reply
[+] [-] cheald|14 years ago|reply
That said, you might consider Lua as a primary scripting engine for your game. It's got a lot of your standard scripting language perks, but it's also obnoxiously fast and has an incremental garbage collector. Furthermore, there's no GIL, and it's designed to be embeddable, making it a very powerful choice for game development.
[+] [-] steve-howard|14 years ago|reply
[+] [-] ww520|14 years ago|reply
[+] [-] udp|14 years ago|reply
[+] [-] anonymoushn|14 years ago|reply
[+] [-] tjogin|14 years ago|reply
[+] [-] teamonkey|14 years ago|reply
[+] [-] fleitz|14 years ago|reply
[+] [-] mjbellantoni|14 years ago|reply
I've done this before with Ruby and C. Two great tastes that go great together!
[+] [-] chrismdp|14 years ago|reply
[+] [-] chrismdp|14 years ago|reply
http://chrismdp.github.com/2012/01/why-i-switched-from-ruby-...
[+] [-] benburkert|14 years ago|reply
[+] [-] chrismdp|14 years ago|reply
[+] [-] subwindow|14 years ago|reply
[+] [-] chrismdp|14 years ago|reply
[+] [-] hkarthik|14 years ago|reply
[+] [-] jt2190|14 years ago|reply
Very nice post! I love seeing these kind of comparisons.
I had the same thought as Havoc's comment (not here, on your site): Why not use both languages?
[+] [-] chrismdp|14 years ago|reply
[+] [-] epynonymous|14 years ago|reply
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] phzbOx|14 years ago|reply
[+] [-] frankPants|14 years ago|reply
[+] [-] Encryptor|14 years ago|reply
[deleted]
[+] [-] rjurney|14 years ago|reply
[+] [-] apenwarr|14 years ago|reply
A 1/60 frame skip rate sounds like nothing important, but your eye will see it easily and it's instantly annoying. It's not subtle at all, and not something you can write off. Everyone will be annoyed by it and then your product will be doomed.
(Edit) I do however agree that the frame rate is not that important. 30 fps ought to be enough for anyone. However, it has to be a really really smooth 30 fps; all the frames need to come out exactly 1/30 of a second apart. Not realizing this is where a lot of people go wrong. A smooth 30 fps looks much better than 120 fps to a human eye. A game framerate that isn't an integer divisor of your monitor's refresh rate is also a disaster (since it means the display will be skipping frames).