|
|
|
Ask HN: They say no one knows all C++ so what parts do Game Devs need to know?
|
|
13 points
by metacontent
5675 days ago
|
|
I recently heard the expression: "If you think you know C++ then you don't know C++".
I take that to mean that C++ is sufficiently large and complex that it is not very common for someone to be deeply familiar with all of its facets.
So this made me wonder what parts of C++ are really essential to know to become a solid indie game developer.
Are there any dark corners that a developer would do well to learn? |
|
But, you are looking for dark corners full of gold... Here's where to look:
Policy-based design using templates can make generating optimal code for lots of different situations only slightly harder than hand-writing optimal code for a specific situation. "Modern C++ Design" is full of examples that take this to the extreme. Don't go that far. Just figure out why std:sort with a functor solidly outperforms qsort (or std:sort) with a function pointer. Also: type traits are tasty when applied sparingly.
Knowing how to override and augment malloc, new, etc... is critical for instrumentation and segmentation of allocations. In-place new and destructors-without-delete can be handy occasionally.
STL's algorithms are great, but the containers are often overkill. binary_search() and insert(lower_bound()) on a sorted array will often beat a std:set because most common datasets are small enough to fit in cache when stored in a contiguous array. Similarly, a sorted array of key-value structs is usually a better idea than a std:map. If you are on the PC, it is possible to write large amounts of fast, beautiful code using only pre-reserved std::vectors (rarely needing new or delete). Boost is soft, warm quicksand.
Don't get wrapped up counting instructions. Memory accesses and cache misses are 20-200X more important. Most algorithm educational materials ignore this. Data-oriented design trumps OO. Component-based design trumps inheritance --it leads to better composability and it is easy to get good Data-OD by batch-processing arrays of uniform-typed components. Most load screens are 90% disk seeking. Not reading. Not processing. Seeking...
As a systems programmer, I'm a big fan of C++0X. static_assert is my best friend. I'm loving auto and lambdas. Move semantics are great for libraries, but if you need it you might be being a bit too liberal with your allocation patterns. btw: it's easy to make a pre-c++ox
#define staticAssert(x) typedef char[x:1:-1] _assert_type
that you can use anywhere.
Multithreaded design is important. Done well, it can make everything simpler. I greatly prefer share-nothing + message passing. Semaphores are handy, but mutexes usually smell bad. If you think you need to call sleep() you are doing something wrong.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx is handy. Just don't look under the hood. Scary...
Return value optimization is nice. Compiler intrinsic functions (and out-of-order execution cpus) are slowly making writing assembly unnecessary (reading assembly is still important). Getting functions to inline away in optimized builds is nice, but getting debug builds to run fast is nicer. RIAA can be nice. Dependency injection can be worth it to not depend on globals (singletons are self-deception). Careful project structure and #include design can mean a 10x difference in compile times. Short (preferably instant/continuous) iteration time is the key to quality.
There's a dozen doors for ya. Take your time stepping through each one. Just be aware that elegance makes it easier to ship, but shipping is the goal. I've seen big, awesome games full of gross, bloated code. They were horribly painful to ship, but they shipped like hell and that's why they won.