« Is There A Reference For Why Structures Better Than Parallel Arrays? | Main | Free Game - Brik: Tactiks »

July 04, 2007

Comments

Nathan McKenzie

Thanks Jamie - this is tons of really great information.

I've been meaning to take closer looks at C# memory management, but because I've been mostly focusing on the PC, and because my current project doesn't have an incredibly large memory footprint (although it burns up fill rate like there's no tomorrow), I've been kind of leaving it on the back burner.

I have to say - I'm nearing the point where I'd almost advocate writing games that ultimately will be C++ in C# or Java or, well, anything higher level, and then doing a massive (painful) line-by-line translation in the last few months of development... or outsourcing that translation, maybe, or having dedicated optimization engineers who eat that sort of thing up. Maybe my instincts on that are misguided, but I'm finding I'm so vastly much more productive working in C# (and the tools and lack of compile time are so much better) that I have a hard time picturing myself wanting to do any sort of iterative development in C++ again.

Anyway, thanks again.

Do you know if Sony or Nintendo are making any efforts to provide any higher-level language support for their consoles? It seems like this might be an area, much like XBox Live, where Microsoft's extensive and far-reaching background in writing software really helps distinguish them from people mostly focused on hardware.

Charlie Tangora

I think the central issue is that there's no language designed from the ground up for game development. C is for systems programming, where speed is more important than everything - including iteration time. C++ is a kludge for people forced to develop applications that have to interface fluently with systems code. Neither one have any benefit for game programmers except that it's easy to optimize C and C++ code.

C#, on the other hand, is an application development language. It's not for people who think of 100 milliseconds as a long time. (Frankly, 14 ms to run GC on 100,000 objects is pretty impressive - especially on a pig like the 360! That's why GC is still a bad idea on consoles.)

Naughty Dog gave it a decent try with their in-house GOAL language - for performance, GOAL had every assembly instruction available as an intrinsic and various cute compiler features like a "this function is not allowed to spill registers" pragma, and for quick iteration it had the ability to dynamically relink code into a running game. Plus it used Lisp syntax, so you could write macros to build your own high-level language features.

On the other hand, GOAL only ever had one programmer working on the compiler and debugger, so lots of programmer time was lost to compiler bugs. And it never had any optimization features beyond register coloring.

Martin Vilcans

Thanks for an interesting post! I've never used C# for anything big, but I've worked on a lot of Java projects, and these two languages share a lot of traits. I agree that garbage collection is not the only productivity-increasing feature in these languages. Yes, garbage collection is nice, but once you have worked on a C++ project that used smart pointers from the very beginning, it's not that big a deal.

Nathan: I have thought along the same lines, i.e. to code in a higher language first and then port to C++. It's not very flattering for C++ to think that we'd save time by developing that way. :-)

Charlie: I agree with your point, but I don't think there's a need for a language that is targeted just at games programming. What we need is a language that is higher level than C++, but not quite as high level as C# or Java. So what we're looking for is a language that allows you to handle memory manually, make low-level optimizations etc. and still provide decent abstractions for higher level programming. One such language that seems to fill this middle ground perfectly is D, but that is new and unproved. Perhaps old statically compiled languages such as Ada might fit well, but it's not very mainstream obviously.

The most realistic approach to this problem right now is to combine a very high level language that gives good abstraction with a low level language that gives speed in low-level code. I'd probably chose Python and C++ for this.

Andy Larder

'Frankly, 14 ms to run GC on 100,000 objects is pretty impressive - especially on a pig like the 360! That's why GC is still a bad idea on consoles.'

But the real issue with XNA on the 360 is the lack of generational GC.

I have had games code running in the desktop Java VM with 100,000's of live objects, with collections taking place every so often of no longer than 0.1 mS. So long as objects are either extremely short lived, or permanent, there should never be any longer collections. I can live with 0.6% of my frame time going to the GC!

The XNA team have made a great start getting the .NET CLR onto the 360 in the first place, but I really hope they have plans to change the GC to something either generational or incremental.

Nathan McKenzie

Martin:

It seems like the longer C# is around, the more it diverges from Java (in, I would say, often good ways). In particular, where as the spec in Java seems largely frozen (much the same way that C++ mostly has been for several years now), C# has been more aggressive about incorporating ideas from languages such as Ruby, Python, Javascript, and so on. I'm not sure what impact that'll ultimately have on the complexity of the language, but so far it's making a lot of my code progressively smaller, cleaner, and co-located, which I like.

I know it's a trivial thing, but as I think Python has proven, syntax matters, particularly for readability. I can't count the number of times I've seen critiques of both C++ and Java where the response has been, "Oh, that's just syntactical sugar. All you have to do to do that is " and then a giant unreadable blob of boilerplate code that involves either verbose template programming or verbose anonymous inner classes that obscures what the code is actually DOING. It reminds me of C programmers who point out that you can get much of the functionality of classes by manually writing your own virtual function tables in structures, coupled with aggressive uses of macros. Ugh.

In many ways it's unfortunate that languages have to advance as clumps of features (which seems to reek of the inheritance versus composition problems in class design, if you'll allow the metaphor). By tying syntax improvements to specific memory management schemes, newer languages provide too many features that a person might have to balk on, even though they'd like all the other improvements the new language provides. That seems like a shame (though it's understandable).

My main concern with C# if, of course, that it's controlled by Microsoft completely... but that's also likely what's allowing it to evolve so quickly. I guess it's tough to say.

Oh - and I have to say, if I never see another custom game scripting language again, it'll be too soon. At this point, I think I've learned about seven different custom game scripting languages. None of them were supported by even one full time programmer. None of them had any meaningful documentation or tool support. None of them had access to good libraries. Occasionally they tried some interesting, game specific things (QuakeC gave free serialization, Unrealscript has special language-level constructs to support client-side prediction of real-time stuff across the client-server boundary), but in general, using them was not a win.

Martin Vilcans

Nathan: "In many ways it's unfortunate that languages have to advance as clumps of features (which seems to reek of the inheritance versus composition problems in class design, if you'll allow the metaphor). By tying syntax improvements to specific memory management schemes, newer languages provide too many features that a person might have to balk on, even though they'd like all the other improvements the new language provides."

I'm not sure what you mean with this. Are you referring to the fact that if you want a language with new useful features, you have to use a language with garbage collection? I guess there's a reason for that. For example, to implement useful closures, you'll need garbage collection. So, like it or not, any language with powerful features is likely to have garbage collection. I also have the strong impression that it's less work to implement powerful new features in dynamic languages. There are features in Ruby that would be close to impossible to implement in C# or Java and definitely impossible in C++. The power comes at a price though, which is performance. Ruby is orders of magnitude slower than C++.

Nathan McKenzie

Martin:

Yeah, of course Garbage Collection is, in fact, needed for a host of other language changes. I think I was playing a little fast and loose with what I was saying.

What I meant was, for example, if you want C#'s anonymous methods, or if you want C#'s namespacing, then you're going to have to accept C#'s lack of macros. If you want Java's memory management, then you're going to have to accept Java's lack of overloading the addition symbol for strings. And the reason I would consider that unfortunate is that it seems like game development slips through the cracks because of this - we want many of the language improvements from more recent languages, and many of the improvements are just straightforward improvements with no specific trade-offs, but because languages are general all-or-nothing affairs (aside from outlawing techniques internally at a company), one glaring language choice can make all the other improvements off limits (since you can't use the language in question). That's kind of what I was getting at - that, in a sense, many of the language features are by no means tightly coupled, but because compilers work on specific languages, one red flag can jettison all other improvements. Obviously memory-management techniques ARE tightly coupled to certain things, such as closures - but even there, it's certainly not connected to, for example, policies about operator overloading, or the existence of macros or template programming.

That's all I'm saying. Maybe it's an analogue to the infinite debates on the MMO message boards about class based vs skill based game rule systems - we're always having to pick between the fighter and the magic user of programming languages, but we can't easily make a customized magetankhealer.

The comments to this entry are closed.

Jamie's Bragging Rights

  • Spider-Man 2
    The best superhero games of all time Game Informer
    Top five games of all time Yahtzee Croshaw
    Top five superhero games of all time MSNBC
    Top 100 PS2 games of all time Official Playstation 2 Magazine
    1001 Games You Must Play Before You Die Nomination for Excellence in Gameplay Engineering Academy of Interactive Arts & Sciences
  • Schizoid
    Penny Arcade PAX 10 Award
    Nominated for XBLA Best Original Game
    Nominated for XBLA Best Co-Op Game