Doom3 is the proof that “keep it simple” works
gamedev.net
gamedev.net
I had C and Objective-C background, and I sort of "slid into C++" by just looking at the code that the C++ guys were writing. In hindsight, I wish I had budgeted the time to thoroughly research and explore the language before just starting to use it.
You may still be able to tell that the renderer code was largely developed in C, then sort of skinned into C++.
http://fabiensanglard.net/doom3/index.php
The vanilla code review goes into the app structure first, and (what little I've read of) the BFG review compares that codebase against the vanilla one.
"CppDepend Tutorial" would be a better title
And the article is written by the creators of CppDepends
I've been a longtime fan of Carmack, and I wish I could read and understand his work for myself!
That's the very problem he tries to address I believe...
Welcome to the future where everything is branded and everyone is an Avon lady, endorsing some set of pet products :)
[a] http://www.rbahelp.com/toilet-partition-privacy-strip-instal... [b] http://www.partitionsandstalls.com/partition-privacy-cover.h... [c] https://www.youtube.com/watch?v=WxWnqR77Dzc&feature=em-uploa...
This is the "nicest looking code [you] have ever seen" ?
C-style declaration of all the variables in the beginning? (Yes, I know what Carmack said about how he written the project; this explains it, but doesn't make it good C++ code.)
Unclear flow with just one comment, which doesn't really explain anything?
There is a logic to keeping logic together if it is isolated: http://number-none.com/blow/john_carmack_on_inlined_code.htm...
Context is important, to anyone developing D3 code, this code might be obvious and comments would be unnecessary. Considering 'geterdone' attitude of many game projects, with high levels hackery, this is very nice code.
Notice, though, that each section is pretty straightforward in what it does...basically forEach's.
You could make the argument for greater polymorphism in types, or something like a visitor pattern over collections or something, but honestly this is readable and maintainable code.
More comments at the function declaration would've been nice, but the implementation is pretty straightforward.
Well, some familiarity with the game helps, too. This is the code that runs when a certain pick-up item's effect activates.
if ( ent->GetRenderEntity()->gui[ j ] &&
ent->spawnArgs.FindKey( j == 0 ? "gui_demonic" : va(
"gui_demonic%d", j+1 ) ) ) { ent->GetRenderEntity()->gui[
j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0
? "gui_demonic" : va( "gui_demonic%d", j+1 ) ), true );
Really?"As we can observe many structs are defined, for example more than 40% of DoomDLL types are structs. They are systematically used to define the data model. This practice is adopted by many projects, this approach has a big drawback in case of multithreaded applications. Indeed, structs with public fields are not immutable."
This statement suits even better to id Tech 3 (Quake 3). John Carmack mentioned: I still think the Quake 3 code is cleaner, as a final evolution of my C style, rather than the first iteration of my C++ style [Doom 3]: http://kotaku.com/thanks-a-few-comments-in-some-ways-i-still... and he linked to his blog post about "Functional Programming in C++" on the now defunct but former popular AltDevBlog: https://web.archive.org/web/20130126164111/http://www.altdev...
The engine of Doom 3 (id Tech 4) was good. The game itself was repetitive and a bit boring. It was a few months late Aug 2004, and Far Cry 1 (March 2004) already overshadowed it in terms of graphics and gameplay.
Licensing the id-Engine to other companies was very successful during the id Tech 2 (Quake 1/2) and id Tech 3 (Quake 3) era. Back then the Unreal engine was only used in Unreal and Unreal Tournament '99, with Deus Ex as an early adopter.
But few games were released starting with id Tech 4 (Doom 3) and later id Tech 5 (Rage). Compromises during the development of id Tech 4+ meant it wasn't suitable for many different purposes. Only small levels with a few light sources were possible - the later "mega texture" addition partly solved that issue but meant a huge hardware step during development and prevented Mods and custom maps. In retrospect the Unreal 3+ and CryEngine 1+ offered comparable results without sacrifice their universalizability. http://en.wikipedia.org/wiki/Far_Cry_(video_game) , http://en.wikipedia.org/wiki/Doom_3 , http://en.wikipedia.org/wiki/Id_Tech_4
The Call of Duty franchise is still using modified Quake 3 engine heavily extended with Ritual's ÜberTools, now named IW engine and comes with many modern features like texture streaming. Half Life 1+2 are based on a heavily modified Quake 1 engine. http://en.wikipedia.org/wiki/Quake_engine , http://upload.wikimedia.org/wikipedia/commons/6/63/Quake_-_f... , http://en.wikipedia.org/wiki/File:Quake_-_family_tree_2.svg , http://en.wikipedia.org/wiki/Heavy_Metal:_F.A.K.K.%C2%B2
All of these id tech engine games can be edited with the GtkRadiant map editor (Half Life, Call of Duty, Quake 3, Doom 3, etc.): http://en.wikipedia.org/wiki/GtkRadiant
GoldSrc was again heavily modified to become the Source engine, but it does retain direct lineage to Quake.
http://en.wikipedia.org/wiki/Source_%28game_engine%29#Origin...
Gotta love how well-known brand names like Source originated as internal dev jargon. I've always been fascinated with things like that.
Pass by reference hides the implication of a side effect on the parameter. If you expect the function to manipulate the parameter, passing by pointer is clearer.
Pass by reference was also only added to efficiently support copy constructors and more importantly operator overloading, both of which are syntactic sugar that a C with Classes style would normally avoid.
Template programming also requires pass by reference but templates are sugar on sugar so not the core reason why pass by reference is needed.
Ps. Disclaimer: I haven't checked if the Doom3 code uses these features.
References also help avoid problems with pointer aliasing, and make it clear that the called function definitely cannot delete the passed objects. So it's more than just syntactic sugar.
(n.b. I'm not arguing that pointers are bad and should never be used, I still just don't see a clear reason never to use references. The id Software coders are smart, they must have had good reason to pick their choice)
Though, the most important thing is consistency and readability over using fancy new features, so they should stick to the style they were using for the project.
But if the argument is "'keep it simple' works for some software projects," one example proves the point. This seems the more generous interpretation.
The C++ Programming Language, 4th edition
Bjarne Stroustrup
The C++ Standard Library, 2nd Edition
Nicolai M. Josuttis
Effective C++, More Effective C++, Effective Modern C++
Scott Meyers
http://en.cppreference.comA Tour of C++ by B. Stroustrup is a good start point for a beginner too
Exceptional C++ by Herb Sutter
More Exceptional C++ by Herb Sutter
Exceptional C++ Style by Herb Sutter
And Templates:
C++ Templates: The Complete Guide by Josuttis & Vandevoorde
And of course you need some background in generic & metaprogramming, so add:
Modern C++ Design by Alexandrescu
Advanced C++ Metaprogramming by Gennaro
So you're looking at over ten books. What does this say about C++? Can you think of another language that has a ten book prerequisite?
If you want to start writing highly generic libraries with the intention of submitting them to boost, then absolutely you should be reading everything in your list and more. But how many C++ programmers are writing boost libraries?
Also, avoiding Boost and Qt early on is also a good idea. Both have tremendous stylistic and design differences from ISO C++ and while the language supports all of them when using the Boost libraries and Qt toolkit you need to shift mindset entirely in how you are writing code to match the backing architecture. Learn the core language first.
Having said that, I used to write tutorials using the old ways as well: http://flipcode.com/archives/Theory_Practice-Issue_06_Event_...
Does anyone love the new C++, and if so, what are their experiences with being on teams that use the full range of functionality? Do you need a language lawyer?
Also STL has improved a lot and I am very happy that I don't need to include a huge dependency such as Boost or POCO just to have a hash table for instance.
There's no reliable way for languages themselves to standardize and aggregate the work that others do. You just hope the language designers are willing to put up a new version, (and that it's a decent one) and they end up doing it ever-so-slowly because it's not automated in any way. Hand-pick and re-roll. There's no metric-based signaling or automated analysis or anything, it's just whatever your experts opine.
"you shouldn't have to rewrite some code that does something that's already available and well-written"
How are those not contradictions?
And keep your rose-colored glasses on at all times. You shall see no evil, hear no evil, speak no evil and never grow out of childhood.
If you're using any kind of IDE then this wouldn't bug you as you can just jump to the point in the file you need.
https://github.com/dhewm/dhewm3/blob/master/neo/idlib/Heap.c...
(Inspired by https://news.ycombinator.com/item?id=9303351 )
The entire point of "tabs to indent; spaces to align" is that you don't need to make sure everyone displays tabs the same way. If we are using that scheme and I have mine set to 4 spaces but you have yours set to 8, everything is fine. There is no problem there.
https://github.com/dhewm/dhewm3/blob/master/neo/game/ai/AI.h...
Scroll down and watch the readability disappear.
diff --tabsize=4 ...
vim "+set tabstop=4" ...
http://github.com/.../file?ts=4Wrong/Cheated. It was such a success that they had to sell the company - they sold ID-Software...
ZeniMax - 2009
It seemed to do well enough to slow the need to sale for five years or so.
Or maybe, just maybe, it was so successful of a company that another company bought it to share in the success.