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...)
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.
For what it's worth, I help to organize a fairly active Ruby group, and I am certain that, if not zero, nearly zero of us would make this proclamation. In fact -- and I mean not to attack you, but just to illustrate how incredulous I am -- I tried to think of a reason there might be for you to fabricate or exaggerate that story. I don't really think you did, but my mind went there.
Didn't make it up. No reason to do so, although I suspect if I spent some time on HN I could find some posts about Ruby perf that don't jive with reality.
But I will say this, do you think this guy made up his post about using Ruby to try to write this game? If you don't think it fabricated, do you think he's alone?
I do think there is a fundamental problem, especially with respect to perf, that a lot of people have never looked at what code actually runs on their box. Never looked at the emitted or generated asm. Don't know the cost of calling a method, much less invoking some framework routine to do something. And then you couple this with a lot of devs think their the cats meow because they got x trans/sec and hear horror stories about the ceremony and inefficiency of C++.
And it doesn't help with the blogs and articles that constantly come out saying that Java or Ruby or Lisp is faster than C/C++ (the answer is never pleasingly straightfroward).
While I appreciate that none in your Ruby group would think this, I'd also ask why do they believe this? It's no more reassuring if they don't have a clear understanding of why C++ might be better for the job.
Lastly, I should add that the conversation was a heated discussion where I was playing devil's advocate that I thought they were going to switch off of Ruby like Twitter. I don't think they really appreciated it, although I wasn't actually being all that serious at the time.
> But I will say this, do you think this guy made up his post about using Ruby to try to write this game? If you don't think it fabricated, do you think he's alone?
I neither think his story is fabricated, nor do I think he's alone. (I didn't say I really thought your story was fabricated, either.)
> While I appreciate that none in your Ruby group would think this, I'd also ask why do they believe this?
I don't know that we would all choose C++, were we building a game, but the performance of Ruby is frequently a topic of discussion. We are lucky enough to have several members that have significant experience working with/around Ruby performance, and they share their knowledge. In other words, were you to choose one of us at random, we would more likely be able to tell you why Ruby is not a good idea, as opposed to why C++ is.
I'm a full-time ruby developer (have been for 6 years). I do web development exclusively and all the experience I have with C and C++ came in college. In other words, I'm pretty ignorant when it comes to game development.
What you're saying here is extremely disturbing to me. For one inexperienced developer to make a wild unsupportable claim like Ruby can do anything C++ can do performance-wise is an act of hubris. For a whole roomful of such devs to nod in agreement is a little microcosm of willful ignorance that must have been terrifying to behold. If this is typical of your experience with Ruby devs I will suggest that your moving in C-player circles and you should expand your travels. We are not all that ignorant.
It's not because it would not be wise to write a Gran Turismo 7 in an interpreted language such as ruby or python that writing any game with such language wouldn't work.
Not all games have such specific requirements as Gran Turismo 7 where huge teams want to extract the most power out of some very specific piece of hardware.
Nowadays it gets easier and easier to use interpreted language as the hardware gets more and more things delegated.
For some games, it may be better to do everything in C/C++, some others C/C++ with some interpreted language on top for some parts, and some others whatever language you prefer.
Given higher level language usually help you write code faster, I would definitely give up some performance (which is not really visible usually) in exchange for some efficiency. Even for some 3d game.
But then again, not everyone is writing the next Gran Turismo :)
Although I can't speak of ruby or its vm since I never used it, but have used python + OpenGL or pygame quite a few times.
In his case not only performance suffered too much from ruby but writing code in ruby didn't make him more efficient. So ruby didn't bring enough value.
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.
The title of your self-submitted post is misleading. The bait post you're referring to stated the obvious, albeit in highly charged language.
It's one thing to choose the wrong language for a project. But having done that, please don't submit a post that suggests expert knowledge or deep experience in Ruby.
For what it's worth, I use both Ruby and C++. I would probably have gone with Qt if I wanted to build such a game. It would never have crossed my mind to write it in Ruby, and I don't consider myself an expert in Ruby.
Reasonable comments - thanks for the HN feedback. It's not for me to say if I'm an expert in Ruby or not, but I don't think attempting something to push some boundaries is mutually incompatible with experience or knowledge. If I'd succeeded, it would have been awesome for Ruby (far and away my favourite language).
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.
It is mean. That's nothing wrong with trying new thing even if most people are saying it's the wrong choice. And there's no shame in failing in the process. People will say, I told you so. But you never know until you have tried it, and you would learn a lot in the process. And sometime you might just have a break-thru.
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.
The ObjC object model is very similar to Ruby's object model.
ObjC's way of handling mundane data structures (strings, arrays, hashes) is (once you learn to stop worrying and love long sequences of calls to very long method names) very similar to how Ruby addresses the same problems.
ObjC lets you drop into vanilla C code when you want to.
ObjC doesn't impose GC.
ObjC implements a form of duck typing.
You might be surprised at how good a fit ObjC is for a game engine you prototyped in Ruby, as opposed to C++.
Obj-C++ is working well for me so far and the STL is much better than Obj-C's awkward and slow collection classes for anything that needs to run fast or that requires significant algorithmic complexity.
One of the nice things about going back from Ruby to a C language is, it's hard to think of anything you could do in the C language that would be as non-performant as Ruby. As slow as ObjC's collections are, they're faster than Ruby's.
yeah corona sdk (which is not free, but seems to be worth the price of entry from my dabbling) compiles for iphone and android from common lua codebase. The api docs are easy to read, tons of examples and plugins (box2d etc.). I threw together an ipad app for my "boiling water" game I've been joking about for years with corona in about an hour having only ever looked at lua from afar. If you grok js/ruby/python than lua will be simple.
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.
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.
That was not the point of my comment. It was a realization of how it came across (aka how I got here).
My main point, however, and this in reply to your post (that I have no doubt it was honest and on the back of some tough thinking) was that you simply started using the wrong tool for the job and then, realizing this, found a more appropriate tool. Nothing wrong with that, but your post came across as "Ruby sucks so I'm going with C++".
Having said that, I'm glad you "saw the light" and I do wish you the best of lucks in your development endeavors! :)
And remember: your next endeavor might be in Ruby, C++, whatever… Just do some thinking beforehand and choose the right tool for the job to avoid "rotting code", which we all know is incredibly frustrating! ;)
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.
Usually the way you solve GC issues is by either not allocating after some initial massive allocation, or by running the GC constantly and having it clean up bits and peices every frame. I don't know enough about ruby to know if this is possible but this is how you handle GC in Java and C#.
As for Lua, Garry's mod runs almost entirely in Lua (outside of the source engine).
You can run GC manually in Ruby, but at the end of the day, it's a stop-the-world GC; your program doesn't get to do anything until it decides that it's finished. If that takes too long, you drop that frame. Additionally, Ruby doesn't have the concept of primitives (mostly), and all objects are stored on the heap! So, every time you use a float (which you do a lot of in games), you end up with a new struct on the heap that has to be garbage collected eventually. Ouch.
Languages with incremental GCs will yield between phases of the GC pass, letting program execution continue even when a GC pass is in progress, making sure that you don't end up with dropped frames, which vastly improves the player experience.
Mike Pall's LuaJIT is excellent from a game dev perspective--incremental GC (so you can spend a fixed amount of your frame budget in it) and JIT with a huge number of optimisation make it fairly compelling to write the top 50% of your game in (and not a terrible choice for the bottom 50%).
I think you were absolutely right to switch from Ruby, I can't see the problems that you had getting any better unless Ruby lets you manage object allocation (in which case you could allocate to a per-frame memory buffer and just nuke it at the end of every frame).
The cause of its popularity in the games community comes from the fact that it is, by design, meant to be embedded in larger programs. So, for example, it will compile on any platform with a conforming ANSI C compiler.
And for x86/x64 and ARM, you can try LuaJIT to get even more zing (though you probably won't need to).
I think it's absolutely the wrong language to write games in, because games are enormously sensitive to runtime fluctuations
No-one is nailing down the definition of "game" in this entire discussion. For a FPS or game filled with live special effects, sure. For a chess game, a puzzler, or even a graphic adventure? Ruby's GC wouldn't be a problem at all (although Ruby has other issues that could well crop up).
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.
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?
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/
Yeah, thought about it (Gosu was great for getting started), but decided I wanted to get back to fundamentals and switch to a slightly lower level framework to aid my understanding of what's really going on under the hood.
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.
I can believe that, but wonder if it needs to be so.
For example, in my (limited) experience, you have to draw the boundary between what's in Ruby and what's in C/C++ intelligently. If you're still doing most of your computation in C on Ruby Arrays and Hashes, you're not going to get much of a performance win at all.
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.
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.
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).
If it's the difference between shipping and not shipping, ship, of course. But you propose a false dichotomy; the OP can both ship C++ code and avoid frame skipping.
Speaking as an avid gamer, that dropped frame matters, a lot. It's incredibly annoying to the gamer, and will produce an attitude of general discontent with the product that will earn it reviews like "sluggish", "slow", "unoptimized", and "chunky", none of which are exactly going to help you sell copies.
You might have missed the part where the author was saying that he wasn't even nearly done with feature implementation; the problem was only going to get worse as he added more garbage overhead. When you're talking about relatively expensive GC passes in a stop-the-world garbage collector, that dropped frame can turn into 150 dropped frames every 30 seconds pretty quickly (ie, a 2.5-second freeze/hitch), and that's enough to turn any player batty.