8 ms·
Why I switched from Ruby back to C++
- chrismdp 15y agoI'd be interested in HNers' views on whether I made the right call.
- steve-howard 15y agoSeems 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.
- chrismdp 15y agoThanks: after three days I think it was the right call. I just found myself burning too much brain energy on things I didn't want to have to care about.
- cheald 15y agoSpeaking 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.
- chrismdp 15y agoI'll look into LUA. Never used it back in my games dev days as it was just coming into vogue.
- cheald 15y agoJust because the Lua community will ream you out for the mistake (though it's the only thing they're mean about), it's "Lua" (Portuguese for "moon"), not an acronym. :)
- chrismdp 15y agoThe joys of iPhone autocorrect :) thanks.
- jacques_chester 15y agoThe 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).
- hythloday 15y agoMike Pall's LuaJIT[0] 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). [0] http://luajit.org/ http://luajit.org/
- ntkachov 15y agoUsually 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).
- cheald 15y agoYou 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. (By way of demonstration:) ree-1.8.7-2011.03 :002 > 123.456.object_id => 33681660 ree-1.8.7-2011.03 :003 > 123.456.object_id => 33674740 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.
- petercooper 15y agoI 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).
- udp 15y agoOne advantage of using C/C++ is that (performance allowing) it's going to be relatively easy to port to Android's NDK or iOS.
- anonymoushn 15y agoWriting 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/ http://love2d.org/
- fleitz 15y agoruby 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.
- tjogin 15y agoOf 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?
- teamonkey 15y agoJust out of interest, why did you choose not to use Gosu in your C++ port?
- trptcolin 15y agoI hope it was because of this: http://gosu-lang.org/comparison.shtml http://gosu-lang.org/comparison.shtml
- teamonkey 15y agoWrong Gosu. He said he used www.libgosu.org for Ruby but the library also works with C++, so I'm wondering why he's switched to www.libsdl.org
- chrismdp 15y agoYeah, 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.
- ww520 15y agoYou 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.
- justinhj 15y agoA 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.
- benburkert 15y agoI 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/ http://rubini.us/doc/en/tools/profiler/), JIT/LLVM. It wouldn't solve the C extension problem (maybe FFI does?) or distribution though.
- chrismdp 15y agoNo, 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.
- boneheadmed 15y agoNice 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.
- chrismdp 15y agoEasy porting to iPhone in the future is another big plus I should have mentioned in the original post.
- tptacek 15y agoThe 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++.
- fleitz 15y agoObjC++ might be an even better fit
- tptacek 15y agoI always got a "stay on the golden path and away from ObjC++" vibe from ObjC++, kind of like trying to ask Rails to do database stuff without using ActiveRecord in 2008. You can easily write C++ code without having to bridge ObjC's object system to C++'s object-and-generics system: provide a simple C API to your C++ libraries. But the other thing is, one reason to do ObjC at all is to avoid all the heartache that comes bundled with C++. PS: You got modded down. Baffling. Fixed.
- subwindow 15y agoI 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.
- chrismdp 15y agoPossibly, but I'm much more comfortable in C++ than Java. I also get a much easier route to iOS if I stick with C++.
- prophetjohn 15y agoWith JRuby, you wouldn't have to be comfortable with Java. You get to use Ruby with the benefit of it running in the JVM.
- hkarthik 15y agoSounds 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.
- chrismdp 15y agoUPDATE: 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! http://chrismdp.github.com/2012/01/why-i-switched-from-ruby-back-to-c-plus-plus/ http://chrismdp.github.com/2012/01/why-i-switched-from-ruby-...
- levifig 15y agoThis sounds very "link bait-ish"… 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 15y agoI suppose it does: but it's the honest truth. I have two months of ruby code that's rusting now, and it was quite a difficult post to write.
- levifig 15y agoThat 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! ;)
- chrismdp 15y agoThat's a shame: I didn't mean to come across like that. I love Ruby: it's far and away my favourite language. Anyone reading the rest of my blog can see that very quickly. And I'm not sure Ruby will be the wrong tool forever: there just isn't a way through some of the environment and implementation issues (yet).
- SomeCallMeTim 15y agoRuby was simply the wrong language for games. There's a reason a huge percentage of real-world games use Lua for scripting. Floats for one aren't objects, and LuaJIT is probably 10x faster than Ruby.
- deleted 15y ago[deleted]
- phzbOx 15y agotl&dr: switch for performance but miss Ruby
- frankPants 15y agocough ObjectiveC
- frankPants 15y agoThis 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.
- erikpukinskis 15y agoThis 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.
- zizee 15y agoI thought he was just calling into question the link-baity title. The title is designed to be controversial as people don't like their favourite programming language to be slandered, thus they will be obliged to read the article so that they can defend their baby. Using link bait as a title is contrary to HN guidelines, so if anything, it is the article that does not belong on HN, not the grandparent comment.
- jtc331 15y agoAgreed. This is pure link bait.
- dextorious 15y agoSure. He coded his game in one language and then SWITCHED in mid-development to another, with all the delay and hassles that that brings, in order to get links...
- chrismdp 15y ago
- gravitronic 15y agoI'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/ 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 15y agoJust out of curiosity: why is compiling on Windows important if your target is POSIX? Is it just for development convenience?
- gravitronic 15y agoYes. For other reasons I am generally running Windows.
- mjbellantoni 15y agoI don't why this needs to be an either/or proposition. Write your program in Ruby. Where it needs speed, write the pertinent bits in C++. I've done this before with Ruby and C. Two great tastes that go great together!
- chrismdp 15y agoI 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.
- mjbellantoni 15y agoI 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.
- epynonymous 15y agoit'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!
- rjurney 15y agoThe 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?
- apenwarr 15y agoYou 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).
- rjurney 15y agoWould you rather have: A complete game that people love, and is growing like mad, except for that damned skip at 60fps... or A very smooth 60fps game nobody plays.
- jt2190 15y agoHi Chris, 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 15y agoThanks! I may still do that, if I makes sense to do so and I can distribute it easily enough.
- nevinera 15y ago"Why I switched from screwdrivers back to the hammer." Because, while pounding in a few hundred nails with my trusty flathead, I noticed that it was taking really a great deal of work.
- deleted 15y ago[deleted]
- ansgri 15y agoAfter 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.
- lelele 15y agoWhat about using an higher level language for game logic, and optimizing critical section of code with C/C++?
- Encryptor 15y ago1. not news. 2. ruby? for game dev? really? 3. the author seems to think C and C++ are the same language.
- jrockway 15y agoI 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...)
- atomicdog 15y ago>(I think pretty much every commercial game works like this.) Is it common for commercial games to write AI in Ruby now?
- m_for_monkey 15y agoNot necessarily in Ruby, it may be Scheme or some proprietary in-house scripting language.
- AndrewDucker 15y agoLua is the most common language, I believe. But the pattern still holds.
- lallysingh 15y agoWhat I don't get is why you're writing it from scratch? There are over a dozen high-quality C++ game engines you can use. A quick list: http://nuverian.net/2011/01/17/the-best-game-engines-for-indie-game-developers/ 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.