Live data from Hacker News

Why I Write Games in C (yes, C)

jonathanwhiting.com

201–210 of 556 posts

Re: Why I Write Games in C (yes, C)

#201

Earlier quoted context omitted.

I know this subject quite well and I will later publish a detailed article. The real run-time cost of memory management done well in a modern game engine written without OOP features is extremely low. We usually use a few very simple specialized memory allocators, you'd probably be surprised by how simple memory management can be. The trick is to not use the same allocator when the lifetime is different. Some resourc…

+1. We have a large Rust code base, and we forbid Vec and the other collections. Instead, we have different types of global arenas, bump allocators, etc. that you can use. These all pre-allocate memory once at start up, and... that's it. When you have well defined allocation patterns, allocating a new "object" is just a "last += 1;` and once you are done you deallocate thousands of objects by just doing `last -= size…

Is this code base open source? Or do you know of open source rust code like it?

Re: Why I Write Games in C (yes, C)

#203
post #58

Earlier quoted context omitted.

> I do write games and game engine code and tools in C++ without using any of the OOP features. Excuse my C/C++ ignorance, but why not simply use C?

Because c++ without OOP still gives you RAII (which is neutered a bit if you don't write your own classes but still), safe pointers, references, lambda, and an immense standard library, to name a few.

C++ RAII is completely gone without the use of classes; it requires something with a destructor.

Re: Why I Write Games in C (yes, C)

#204
post #77

Earlier quoted context omitted.

If C gets operator overloading and RAII, there will be no good reason to use C++ for me!!

Is RAII in C a serious suggestion being made anywhere?

GCC has it as an extension. See the cleanup attribute:

https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attribute...

Re: Why I Write Games in C (yes, C)

#205

Earlier quoted context omitted.

I’m not a game programmer but with RAII for example (I realize this is not a C idiom), it really becomes a non-issue if you have things scoped properly. For everything that doesn’t fit into this box you probably wouldn’t be relying on a GC anyway, the GC may do the final memory reap but scope control is still often manual in memory-managed languages.

That's not entirely true. If you only rely on RAII you may end up with millions of shared pointers, each of which needs to be managed independently and having its own overhead. They may also be independently allocated, which means they will be fragmented in memory. Not so simple.

I think it’s safe to say for the general case that if you have millions of widely-shared smart pointers you are not following RAII principles. At that point you are left with poorly-implemented reference counting, with a ton of synchronization overhead.

Re: Why I Write Games in C (yes, C)

#206
post #46

> The stop-the-world garbage collection is a big pain for games, stopping the world is something you can't really afford to do. I love this opinion from games programmers because they never qualify it and talk about what their latency budgets are and what they do in lieu of a garbage collector. They just hand wave and say "GC can't work". The reality is you still have to free resources, so it's not like the garbage c…

By game programmers you probably mean AAA console game programmers. I was once one, and I know that those games have to account for every byte of memory. Garbage collection has not only cpu overhead which can be unpredictable, it also requires memory to potentially sit around unused waiting for the next cycle. Your question is what is our budget for gc in terms of cpu work and memory overhead, and the answer is zero for both.

Re: Why I Write Games in C (yes, C)

#207
post #174

Earlier quoted context omitted.

> If you have a garbage collector that runs in 200us The problem is GCs for popular languages are nowhere near this good. People will claim their GC runs in 200us, but it's misleading. For example, they'll say they have a 200us "stop the world" time, but then individual threads can still be blocked for 10ms+. Or they'll quote an average or median GC time, when what matters is the 99.9th percentile time. If you run GC…

these aren't theoretical numbers, they're the numbers that people are hitting in production. See this thread wrt gc pause times on a production service at twitter https://twitter.com/brianhatfield/status/804355831080751104 also referenced here, which talks at length about gc pause time distributions and pause times at the 99.99th percentile https://blog.golang.org/ismmkeynote

> they'll say they have a 200us "stop the world" time, but then individual threads can still be blocked for 10ms+

As far as I know this is still true of the Go GC. Write barriers are also there and impact performance vs. a fixed size arena allocator that games often use that has basically zero cost.

Re: Why I Write Games in C (yes, C)

#208
post #40

Earlier quoted context omitted.

Basic games like...Quake 3?

Yup. Quake 3 is basic. I remeber that the whole game had a "measly" 150.000 lines of code or so. It doesn't do a ton of things modern games do. The list of things expected from modern games these days in comparion is far too long to list here. These things have become elaborate world simulators. And all of these features add up. The Unreal Engine is around 4 million lines without dependencies (e.g. PhysX, a proper au…

Quake 3 has 230.000 lines of code. If Quake 3 is considered basic, then any studio with less than 100 developers can probably reach for C.

The Unreal Engine is far more than a modern game. You wouldn't call Clang and editor just because Vi was compiled with it.

Re: Why I Write Games in C (yes, C)

#209

Earlier quoted context omitted.

My experience with Rust is that I have to fight the compiler a lot, but when the program compiles, it works . If it doesn't work, it means there's an error with my file/network paths or I did something in the wrong order, errors which no language can save me from. Rust also becomes a lot less verbose when you get better at it. The ? operator is especially useful.

> but when the program compiles, it works That's not even true for languages with dependent types, which Rust lacks.

It is (or should be) read as slightly hyperbolic, as there isn't to my knowledge a language that actually works that well. I could water down my message by saying "it mostly works", but then I fail to convey the main reason why I posted in the first place.

I could also instead spend a lot of time and words to explain things about Rust's design that I presume anyone who is slightly interested in the language would already know (specifically: lack of null, strict ownership checking, having to explicitly deal with errors), in order to explain that the language succeeds at solving some of the problems it was specifically designed to solve. But then I would just be repeating things that HN readers presumably already know. Instead I can use a shortcut in my communication which is perfectly understandable if you assume minimal intelligence, and take the other person's comment in good faith.

See, by the time we've reached the bottom of this wall of text, anyone who read this far through my intentional rambling has presumably forgotten my initial point: I had a positive experience with the language.

Post reply on HN