There's been some discussion about using Rust.
Rust is an interesting language, and has definitely potential substituting C and C++ in some domains. The main reason I'm not so interested in using it is for game development, is because it's more complicated than C (like C++), and the complications are a bit off from what I'd want (like in C++). Just a quick googling reveals that rust mangles names by default, and doesn't have reflection, so I'd probably be in for a lot of negative surprises. Add that with being indifferent about the absolute security, and soon my code is mostly inside unsafe blocks so that I don't have to spend time convincing the compiler my pointers are safe. Maybe. I haven't done much programming in Rust. There are some nice convenience features though, when comparing to C, but they seem to be rather minor things.
It comes down to choosing between two non-ideal solutions. I value simplicity more than some, so favoring the simpler one feels more natural to me. Sure, when you need the safety then Rust seems like a decent choice.
EDIT: Re: pointers -- Rust is a lot easier to write if you just ignore pointers. Really. Either pass small structs by value or pass references (either immutable or mutable), and let the compiler handle the actual pointer manipulation.
* I could be pleasantly surprised, though. In theory, for incremental builds, based on the general design planned [1], rustc should be able to do better even than C in a lot of cases because only changed functions need to be recompiled rather than entire files; but I'm a pessimist and expect there will be something to make it slow in practice. I could be wrong though.
[1] https://github.com/rust-lang/rfcs/blob/master/text/1298-incr...
But I think most of the main points you describe as impossible in C++ are actually completely possible. It means moving away from the 90's paradigm of using C++ to implement deep class hierarchies with design pattern, but after all C++ is a multi-paradigm language. If you can do data-oriented design in C, you could most certainly do it in C++, and the abstractions C++ provides actually make it easier.
In essence, I would separate game objects to a logic instance and state objects (pure structs) and use smart pointers with a generation-counter to point the logic instance, which in turn would have smart a pointer to the state struct. The smart pointer would overload the dereference operator and transparently update the logic instance to get the new vtable if needed.
This decoupling of state and logic could do many nice things, such as serializing the entire game state in a very clean way, and pure state structs would not be harder to parse than C structs (they would essentially be C structs), so you can still have your memory editor.
The main difference between C and C++ here would be the cost abstractions, both cognitive and performance-wise. I have to admit I've never ran into standard abstractions significantly slowing optimized debug code, except for standard library containers. I'm not a game programmer though, so YMMV. I get the cognitive cost argument, but for me the cognitive cost of C (namely having boilerplate noise scattered all over hiding the interesting code and having to be super-extra-careful with memory management) is higher than than the cognitive cost of internalizing all the layers of abstraction in C++.
If you're programming a network game, I still think you'd do your users a better service if you don't dismiss safety offhand. There's a whole class of memory-safety bugs which would never surface during normal play, but could still be exploited with specially crafted packets. Of course, C++ wouldn't give you perfect protection either.
I also think the "convenience features" are a pretty big deal. Generics with traits are a pretty big value add for their complexity, and to me affine types take away a lot of the complexity of C.
No offense, but I think you suffer from the same problem. You're in love with coding, so being forced to micro-manage things the 'C' way isn't a problem for you.
But at some point in time you have to look back and justify the hours spent. You -will- be more productive by having the majority of your code in C++ 11. Things -will- be easier to maintain for yourself and others.
I have written absolutely brilliant C code that I'm very proud of, but if it's been a while since I looked at the project I have to sit down for an hour and re-familiarize myself with how things work....and I'm the one who wrote it.
Based on what you've written I can tell that you don't have the experience to justify writing the bulk of your code in C. Guys who inline ASM all day long can have a hard time doing that. I know it's harsh, but it's meant as helpful criticism.
One other thing: You don't have to pick just C or just C++. If you have engines in your project that are clearly better in C and you enjoy doing it, more power to you....I encourage you to do that. However, it's very easy to get hung up on C and lost in your own C world of imagined optimizations.
My advice: Start off with solid C++, move parts to C later on when testing justifies it and your amount of free time justifies it.
He makes no mention of inline assembler, nor does he encourage premature optimization. He talks instead about a concrete problem he had: the typical performance of operations was not good enough, thus no single optimization would help much. He also mentions that the abstractions encouraged by C++ do not help you build data-oriented applications (e.g. games); using them properly actually hurts performance.
I make games in Unity/C#, and yes, of course it's slower than a custom C solution. But instead of spending time on writing my own containers and memory allocation, I spend time writing game logic. Instead of optimizing game to run from 100 to 150 FPS on my computer, I'd rather spend this productive time making 5 variants of the same game mechanic to find out which is more fun. Even if the game runs in just 30 FPS.
Of course, I sometimes try to research low-level stuff, write my own renderer, or do a small experimental project in pure C, but then my goal is to research, not to write a game. I can hardly imagine a project, where the goal would be to develop a game, and not to research, where using C and having to spend so much time on this matters would be a good trade-off compared to working on actual game mechanics in higher-level language.
The author states at the beginning that his goal is writing an engine and only after that write a game. You are right on all other points though, most people working on game engines simply never get to the making a game part. There's simply too much to do.
I spent a couple years' working together with a friend every now and then on a game+game engine in C#. We did get past the game engine phase because it was kept simple (ECS + box2d and simple monogame 3d renderer) but we eventually gave up because even though game logic was progressing swiftly assets were just a pain in the ass.
Most low level engineers (as we are/were) underestimate the work it requires to get a proper asset pipeline set up. You're never going to build a 3d game if you can't load cheap 3rd party assets with their animations and materials. And then the level designer which is basically just another game in your game.
We went with UE4 as a change of pace and man is it librating not to have to worry about the limitations of your homebrew engine anymore. In UE4 literally anything is possible (you have the full source after all) and its always less work.
I agree that there is a class of games that can be easily implemented with a prebuilt engine, but this is not one of them.
I've written several game engines in the past. I hope to never do it again.
Code-generation all the way. Use an expressive language like python/lua/tcl/lisp/scheme to work on a higher layer than C.
Two-language programming (one GC scripting, the other C) beats the heck out of C++, in terms of best of both worlds: expressivity in higher layer, performance in lower layer.
C++ has a dirty secret no one likes to talk about. Stroustrup himself was a two-language programmer. C++ was C with classes where the classes were built with unhygienic C macros. When he decided to show his work to "average joe programmers" of the world, he turned it into one language (it turned out he was not a very good language designer so the world has to live with it).
If you're working with C++ you are Stroustrup's average-joe customer.
If you're working with two-language programming you're Stroustrup himself (even better cz you're using a higher language way better than the C macro system)!
Other than that. You want superpowers? give your text-editor your C parser (something similar to this [1]). Structured-editing can do amazing productivity gains in C. This is something I'm still looking into (using some vi/vi-clone, or emacs/emacs-clone, and pycparser) but I very excited about the possibilities.
The opposite of what you say is easy to argue for: two languages, twice the headaches.
* first of all, you need to know TWO different languages. C is completely different from a language like Ruby or Lisp.
* even if you manage to do that, you still have two build systems, two things to package and deploy, you need two libraries of everything (e.g: unit testing)
* you need to constantly pass information between the two worlds, which can be both performance costly and challenging from a design perspective.
* normally it's not as easy as "rewriting the slow parts in C". What if your problem is overall memory usage? What if there is no one function to rewrite?
* if you make a mistake in C (super easy), your whole app crashes.
I don't think this is the magical solution you're presenting it to be at all.
There are real costs to building the abstractions needed in order to make a useful scripting environment.
Tried to visit that site, but all I get is this message:
"Sorry, your browser is not fully supported.
There may be some issues with pages layout in your current browser. Please use an alternate browser until we resolve the issues. Thank you."
Since when is it OK to just refuse to serve a page if it's not 'the right' browser? Is this a thing now?
> 6. start to ponder if I really need even the good parts of C++
This reads like wisdom and maturity to me; unfortunate, but not surprising, that people are quick to judge.
Last game studio I worked at, we wouldn't have given up C++, but there were frequent conversations about its pitfalls and complexity, and quite a few rules and conventions recommending against, out outright prohibiting some C++ practices, exceptions, for example.
Before that, the last film studio I worked at, a bad experience with C++ led them to chuck it (before I got there) and go object oriented C. I learned their style of C and quite liked it. I missed operators and templates a bit, and it felt a little verbose, but I came to really appreciate the simplicity and explicitness.
Sounds like it wasn't an easy choice, but on a solo project that large you have to prioritize what makes you feel the most productive in the long term, and there are always tradeoffs.
Also, I observed that "bad experience with C++" is often related to someone using, while not completely understood, some more advanced C++ paradigm.
I feel if the author refocused on his C++ basics instead of bemoaning lots of peripheral crap (like OOP, and the unsuitability of the STL for game dev) he'd reconsider some joy in C++ again.
For example, the paragraph about loading and saving game state postulates "using the ideas of polymorphism and encapsulation", automatically throwing a lot of pointers and vtables in the way of reading and writing a binary blob like in the C engine. A serious C++ engine with a "data oriented" design would have the same arrays of primitive types and dumb structs as its C counterpart, merely dressed as std::vector or std::array.
I agree with the OP on all three counts. I don't think RAII is very nice (python-esque with-statement would be nicer IMO), exception safety is really a mental overhead unless you restrict exceptions to a minimum and the copy-assign-move semantics do add a bit of work to every class you introduce.
These are not outrageous claims, they're rather valid opinions. Feel free to disagree but I'm siding with OP on this one.
Overall I dislike C++'s value based semantics, not because it's inherently bad, but it's just so different to any other (reference based) languages that only a small minority of programmers know how to work with them. Attaching complex semantics to types (overloading, templates) and virtual functions/inheritance (when overused) makes reading code much harder and often you need to resort to stepping in the debugger to find out where a function call actually leads.
Well written C++ can be really nice at best, but unfortunately most C++ code bases out there seem to be either a bastard mix of C, Java and C++ styles or over-the-board boost-ey template mess. Neither of these extremes hits the sweet spot.
Maybe, I don't know. I have been a lot happier with C though, while still writing some C++ code during the year.
Huh? Sure, you can go OO architecture astronaut in C++, but if that isn't a good model for your problem, don't do it. I see more of a focus on generic programming, anymore, in C++.
I've been thinking for a while that the problem with C++ is that 100 decisions have been made both in the library & language and in "best practice" that all individually are good, but the combined effect has been unfortunate.
I'm not quite getting from the article why you can't write in the C "subset" of C++ and add in a few of the more helpful parts of C++ though.
I think this is because of C++ name mangling, which prevents the creation of a quick and dirty reflection system. And maybe compilation times, which must be higher since the compiler has to deal with all of C++, even if you don't.
- user-provided code called when an "object" goes out of scope
- operator overloading sometimes makes sense
- simple template-meta-programming sometimes makes sense (but could be replaced with other sorts of code-generation)
3rd party libraries are usually a pain to integrate when they have a C++ interface, and usually simple when they are just a C header, and when they can simply be dropped in as source into the project.
A good middle-ground is probably to build the building blocks in C, this way they are way better reusable then writing C++ code, also across languages, and tie the low-level buildings blocks together in whatever language one likes (even interpreted languages).
[edit: formatting]
First of all, they are both great languages, no matter what anyone tries to tell you.
I went through this same dilemma and, while I have great respect for C, I soon realized that my situation would be more productive with C++ and its tools immediately available. For one thing, a lot of important libraries that are common in games and graphics have C++ interfaces, so if you use C you are asking of yourself to exclude some great tools out there, or, go through significant steps to wrap some of them (which would still involve some C++ anyway).
Don't focus too much on technology, disconnected from what people (including you) might want to actually use. Otherwise you will not get the real inspirations -- even purely technical inspirations -- that come from something that you intend to use.
That said, author has done a good job explaining his thought process in taking the rewarding-at-every-step path, given he's not a C++-wrangling junkie.
It is still changing fast but I think it could be great for writing games in the future.
Depends on what you consider safety to be. A game engine that doesn't deadlock and doesn't crash should definitely be high priority!
Someone has to.