Live data from Hacker News

Why I Write Games in C (yes, C)

jonathanwhiting.com

531–540 of 556 posts

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

#531
post #522

Earlier quoted context omitted.

That API is new and was just added to 2018.3 in December, around the same time they started previewing the incremental garbage collector and promoting ECS. From Unity: > Being able to control the garbage collector (GC) in some way has been requested by many customers. Until now there has been no way to avoid CPU spikes when the GC decided to run. This API allows you disable the GC and avoid the CPU spikes, but at the…

All true. However, even before you could disable the GC, you could ignore it as long as you weren't allocating and hit framerate. Unity isn't magic but the way people talk it's like Unity games don't exist.

But things like this would happen, even from acclaimed developers, giving the engine a bad reputation among players:

> The frame-rate difficulties found in version 1.01 are further compounded by an issue common with many Unity titles - stuttering and hitching. In Firewatch, this is often caused by the auto-save feature, which can be disabled, but there are plenty of other instances where it pops up on its own while drawing in new assets. When combined with the inconsistent frame-rate, the game can start to feel rather jerky at times.

That studio is part of Valve now!

> Games built in Unity have a long history of suffering from performance issues. Unstable frame-rates, loading issues, hitching, and more plague a huge range of titles. Console games are most often impacted but PC games can often suffer as well. Games such as Galak-Z, Roundabout, The Adventures of Pip, and more operate with an inherent stutter that results in scrolling motion that feels less fluid than it should. In other cases, games such as Grow Home, Oddworld: New 'n' Tasty on PS4, and The Last Tinker operate at highly variable levels of performance that can impact playability. It's reached a point where Unity games which do run well on consoles, such as Ori and the Blind Forest or Counter Spy, are a rare breed.

https://www.eurogamer.net/articles/digitalfoundry-2016-firew...

https://www.eurogamer.net/articles/2016-02-10-firewatch-dev-...

Hopefully as the engine continues to improve dramatically, this kind of thing will be left in the past

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

#532
post #77

Earlier quoted context omitted.

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

Only operator overloading is really important and would cut down the size of code written substantially. Thats the only real advantage of using C++ vs C. Everything else oop, function overloading,RAII,etc can be replaced with macros and structs.

Pretty sure you can't make destructors with macros?

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

#533
post #470

Earlier quoted context omitted.

> Even std::unique_ptr has runtime costs in release builds that a raw pointer does not. O RLY ? https://gcc.godbolt.org/z/QhbUjI

Yes, really. It's fine for simple types but for more complex types in more complex situations, you pay the price. Unique pointers carry around not just the type but also a default deleter, if you provide one. That deleter has to be copied around, checked for nullptr before execution and set to nullptr when ownership changes. For even more examples of this have a look at this talk when it comes out: https://cppcon2019…

It's pretty stupid to compare a unique_ptr with a deleter that contains state to a pointer - obviously those two things are completely different and the unique_ptr contains way more information.

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

#534
> The ideal language would be one I can memorize, and then never have to look things up.

If the language is so small I never have to look up anything when using it, it's also so small I'm going to have to spend ages re-re-re-implementing basic functionality that I get for free from a higher level language.

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

#535
post #87

Earlier quoted context omitted.

you would probably like zig, if you haven't given it a look yet.

I feel zig is now experiencing feature creep now too sadly. Async and await and coroutines are being added to it, because it's the new-ish hotness I guess? Stopped paying attention to the language after that. I was hoping for a more streamlined language.

it's been planned since the beginning: https://ziglang.org/download/0.3.0/release-notes.html#concur...

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

#536
post #522

Earlier quoted context omitted.

All true. However, even before you could disable the GC, you could ignore it as long as you weren't allocating and hit framerate. Unity isn't magic but the way people talk it's like Unity games don't exist.

But things like this would happen, even from acclaimed developers, giving the engine a bad reputation among players: > The frame-rate difficulties found in version 1.01 are further compounded by an issue common with many Unity titles - stuttering and hitching . In Firewatch, this is often caused by the auto-save feature, which can be disabled, but there are plenty of other instances where it pops up on its own while…

If you continue reading that article, they go on to say Unity is not to blame...

There's a lot of reasons shipping Unity games is hard but the GC and C# are not among them or at least much lower than, say, dealing with how many aspects of the engine will start to run terribly as soon as an artist checks a random checkbox.

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

#537
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…

Java has a pauseless GC called Shenandoah, and Zing JVM from Azul systems also has pauseless ZGC (I believe Zing implemented it first). What most people don't realize is that eg. Shenandoah can slow down the allocation rate to keep GC in the time budget.

I think people prefer C and C++ because they can control the memory layout of the app, and specially in console games they can do much more low-level optimisations than using a higher level language. Besides, I'm guessing the pain in C++ doesn't come from memory allocation, you probably follow a well defined ruleset for freeing objects and you know you will be OK.

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

#538
post #525

Earlier quoted context omitted.

Well, of course, that's how you fix such a bug, however, when using third party libraries and other people's code, you don't necessarily know that this is happening until you have missing exceptions. In my opinion, exceptions also complicate code by taking error handling out of the scope of the code you are writing, since you can't know whether anything you call throws, so you may not catch, and some higher level cod…

If you don't know what functions you are passing to third-party libraries, you have a much bigger problem than any language can help you with. Google's proscription on exceptions is purely historical. Once they had a lot of exception-unsafe code, it was too late to change. Now they spend 15-20% of their CPU cycles working around not being able to use RAII.

When you write modern software, most of your executable ends up being third party code for commonly done things, it's both wonderful since you can move fast, and a curse, because you inherit others' bugs.

My example with libcurl was very simple, but in real systems, things are less clean. You may be using a network tool that hides libcurl from you, and your code is being passed into a callback without you even knowing it until it causes a problem. Other places where C++ exceptions fail would be when you dlopen() a module, or one of your binary C++ dependencies is compiled without exception handlers. The code will compile just fine, but exceptions will be lost, there's not so much as a linker warning.

Google uses RAII just fine, it's just you have to be careful with constructors/desctrucors since they can't return an error. There's no way it burns 15-20% CPU not using RAII - where are you getting these numbers? I used to work there, in C++ primarily, so I'm well familiar with their code base.

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

#539
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…

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 for that article, especially the part about OOP downsides at scale and batch memory allocation. Love to see more!

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

#540
post #439

Earlier quoted context omitted.

Exception handling doesn't work very well. It requires exception frames on the stack, and those go missing sometimes, leading to leaked exceptions and unexpected crashes. For example, if you pass a C++ callback function into a C callback, say in libcurl, the C library doesn't have exception handler frames in the stack, so exceptions are lost. If your C++ code throws from within that C callback, any catch above the C…

Don't pass functions to libcurl that throw. Otherwise, exceptions make code simpler, cleaner, and more reliable. They will never "go missing" unless you do something to make them go missing. Code that does those things is bad code. Don't write bad code. Do use exceptions.

> Don't pass functions to libcurl that throw.

Unless you know the details of how every function (and every function that function calls, and so on) handles errors, the easiest way to not pass functions to libcurl that throw is to not write those functions in a programming language with exceptions :)

Post reply on HN