Live data from Hacker News

Why I Write Games in C (yes, C)

jonathanwhiting.com

311–320 of 556 posts

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

#311
After I got past the horrible misspellings and atrocious grammar, I could appreciate what the author is saying. The author is privileged to be able to concentrate on and enjoy a particular language. That is great, for him.

Most of the rest of us have to learn and use a wide swath of languages, features, and technologies to stay a leg up in this world. We seldom have the choice to pick what we work on. Sure, we can change jobs, but inevitably it requires conforming to someone else’s opinion.

The author makes me want to go back and pick C up again. But like so many times in the past, I will probably find it needlessly painful and go right back to the more modern languages which already solved so much for me. I don’t mind standing on the shoulders of past C developers. I, for one, also do not mind learning the details of any particular modern language because, if anything, it makes me more marketable.

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

#312

Earlier quoted context omitted.

I’ve shipped C++ games and Unity games. I have never spent more time managing memory than in C#. You have to jump through twisted, painful hoops to avoid the GC. Memory management is ultimately far simpler and easier in C++ than in C#.

I do gamedev in Unity and avoiding garbage creation feels easy enough to me for the most part.

It could be worse. Once upon a time a common "trick" was to avoid using foreach loops because they generated garbage. LINQ also generated garbage. I'm not sure if the .net 4.5 upgrade fixed that one.

Ultimately you wind up doing the exact same thing in C# that you'd do in C++. Aggressive pooling, pre-allocation, etc. A handful of Unity constructs generate garbage and can't be avoided. I believe enable/disabling a Unity animator component, which you'd do when pooling, is one such example.

It's all just a little extra painful because you to spend all this time avoiding something the language is built around. Trying to hit 0 GC is annoying.

It also means, somewhat ironically, is that GC makes the cost of allocation significantly higher than a C++ allocation. In C++ your going to pay a small price the moment you allocate. But you know what? That's fine! Allocate some memory, free some memory. It ain't free, but it is affordable.

In Unity generating garbage means at some random point in the future you are going to hitch and, most likely, miss a frame. And that's if you're lucky! If you're unlucky you may miss two frames.

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

#314
post #81

Earlier quoted context omitted.

The guy should try Rust and then explain why he prefers either, that would be interesting.

I like rust, but for me, it is significantly more difficult to read and write. Same can be said about C++ with extreme STL code.. I prefer to read and write simple C like syntax. I would love it if I can get Rust concept of borrowing in C, or even simple operator overloading..

Same, I heavily prefer less symbols in my code. I think it might also relate to how I find it much harder to remember long formulas but than remembering the sentence describing the formula. If I could type for example `brw x` instead of `&x` I think I'd like it more - I guess I like it more Python-y?

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

#315
>>I am not an OOP convert. I've spent most of my professional life working with classes and objects, but the more time I spend, the less I understand why you'd want to combine code and data so rigidly.

He doesn't want to combine code and data rigidly, so he uses a language without any concept of generics.

I think he doth protest too much, he can write code however he feels like, and Im not going to deny his personal opinions, but the justifications and reasons for those opinions are all just uniformly nonsense.

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

#316

Earlier quoted context omitted.

Disclaimer: I'm not a game developer; but, I've worked on a lot of projects with tight frame time requirements in my time at Netflix on the TVUI team. I also have no experience in Go so I can't comment on the specifics of that garbage collector vs. V8. I don't think it's necessarily that it "can't" work as much as it takes away a critical element of control from the game developers and the times you find yourself "at…

> it was generally non-deterministic This is basically it. People who have never worked on actual real-time systems just never seem to get that in those environments determinism often matters more than raw performance. I don't know about "soft" real-time (e.g. games, or audio/video) but in "hard" real-time (e.g. avionics, industrial control) it's pretty routine to do things like disable caches and take a huge perform…

""soft" real-time (e.g. games, or audio/video) "

Hah. Who sez that audio and video products have 'soft' real time? Go on now.

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

#317

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…

It would be interesting to see what the impact of adding hints about allocation lifetime to malloc would be. I have to suspect someone has already written that paper and I just don't know the terminology to look for it.

Given the problems people have with Rust and the borrow checker, I would guess that people will not accurately predict how long an allocation will live (it's a similar issue with profiling---programmers usually guess wrong about where the time is being spent).

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

#318
post #278

Earlier quoted context omitted.

Its not just pauses either. Non-deterministic memory usage is a big deal too.

I have actually worked on a system where malloc() was forbidden. In fact it always returned null. Buffers were all statically allocated and stack usage was kept to a minimum (it was only a few kB anyways). The software was shipped with a memory map file so you know exactly what each memory address is used for. A lot of test procedures involved reading and writing at specific memory locations. It was for avionics BTW.…

Why even define a malloc() in this environment if it always returns NULL?

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

#319

Earlier quoted context omitted.

> it was generally non-deterministic This is basically it. People who have never worked on actual real-time systems just never seem to get that in those environments determinism often matters more than raw performance. I don't know about "soft" real-time (e.g. games, or audio/video) but in "hard" real-time (e.g. avionics, industrial control) it's pretty routine to do things like disable caches and take a huge perform…

""soft" real-time (e.g. games, or audio/video) " Hah. Who sez that audio and video products have 'soft' real time? Go on now.

What percentage of the market is A/V build to actual hard real-time standards, and not expected to run on devices that can't provide it (so no PCs with normal OSes, no smartphones)? For the vast majority, soft real-time is fine, since an occasional deadline-miss results in minor inconvenience, not property damage, injury or death.

I assume some dedicated devices are more or less hard real time, due to running way simpler software stacks on dedicated hardware.

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

#320

Earlier quoted context omitted.

It's a requirement if you do network I/O whether you realize it or not.

In gamedev, we often use UDP for network I/O. I am far from an expert in security but I've done a bit of reversing/hacking when I was 16 years old (DOS era) I think this is hard to check for everything, but in my opinion, good security can be achieved with extreme simplicity. Packets are fixed-size, every fields are manually bound checked and the packet is rejected if anything looks wrong.

That jibes with my knowledge.

But I've seen some real weird stuff before. ;) Folks using variable-length fields and happily just dumping the contents into eval(), all sorts of awful.

Post reply on HN