June 8, 2012

Doom3 Source Code Review: Introduction (Part 1 of 6) >>

On November 23, 2011 id Software maintained the tradition and released the source code of their previous engine. This time is was the turn of idTech4 which powered Prey, Quake 4 and of course Doom 3. Within hours the GitHub repository was forked more than 400 times and people started to look at the game internal mechanisms/port the engine on other platforms. I also jumped on it and promptly completed the Mac OS X Intel version which John Carmack kindly advertised.


In terms of clarity and comments this is the best code release from id Software after Doom iPhone codebase (which is more recent and hence better commented). I highly recommend everybody to read, build and experiment with it.


Here are my notes regarding what I understood. As usual I have cleaned them up: I hope it will save someone a few hours and I also hope it will motivate some of us to read more code and become better programmers.

Part 1: Overview
Part 2: Dmap
Part 3: Renderer
Part 4: Profiling
Part 5: Scripting
Part 6: Interviews (including Q&A with John Carmack)


From notes to articles...

I have noticed that I am using more and more drawing and less and less text in order to explain codebase. So far I have used gliffy to draw but this tool has some frustrating limitations (such as lack of alpha channel). I am thinking of authoring a tool specialized in drawing for 3D engines using SVG and Javascript. I wonder if something like this already exist ? Anyway, back to the code...


Background

Getting our hands on the source code of such a ground breaking engine is exciting. Upon release in 2004 Doom III set new visual and audio standards for real-time engines, the most notable being "Unified Lighting and Shadows". For the first time the technology was allowing artists to express themselves on an hollywood scale. Even 8 years later the first encounter with the HellKnight in Delta-Labs-4 still looks insanely great:


First contact

The source code is now distributed via Github which is a good thing since the FTP server from id Software was almost always down or overloaded.

The original release from TTimo compiles well with Visual Studio 2010 Professional. Unfortunately Visual Studio 2010 "Express" lacks MFC and hence cannot be used. This was disappointing upon release but some people have since removed the dependencies.

	
	
    Windows 7 :
    ===========
	
    
    
    git clone https://github.com/TTimo/doom3.gpl.git
	
    
	



For code reading and exploring I prefer to use XCode 4.0 on Mac OS X: The search speed from SpotLight, the variables highlights and the "Command-Click" to reach a definition make the experience superior to Visual Studio. The XCode project was broken upon release but it was easy to fix with a few steps and there is now a Github repository by "bad sector" which works well on Mac OS X Lion.

	
	
    MacOS X :
    =========
	
    
    
    git clone https://github.com/badsector/Doom3-for-MacOSX-
	
    
    
	

Notes : It seems "variable hightlights" and "Control-Click" are also available on Visual Studio 2010 after installing the Visual Studio 2010 Productivity Power Tools. I cannot understand why this is not part of the vanilla install.

Both codebases are now in the best state possible : One click away from an executable !


Trivia : In order to run the game you will need the base folder containing the Doom 3 assets. Since I did not want to waste time extracting them from the Doom 3 CDs and updating them: I downloaded the Steam version. It seems id Software team did the same since the Visual Studio project released still contains "+set fs_basepath C:\Program Files (x86)\Steam\steamapps\common\doom 3" in the debug settings!

Trivia : The engine was developed with Visual Studio .NET (source). But the code does not feature a single line of C# and the version released requires Visual Studio 2010 Professional in order to compile.

Trivia : Id Software team seems to be fan of the Matrix franchise: Quake III working title was "Trinity" and Doom III working title was "Neo". This explains why you will find all of the source code in the neo subfolder.


Architecture

The solution is divided in projects that reflect the overall architecture of the engine:

Projects Builds Observations
Windows MacO SX
Game gamex86.dll gamex86.so Doom3 gameplay
Game-d3xp gamex86.dll gamex86.so Doom3 eXPension (Ressurection) gameplay
MayaImport MayaImport.dll - Part of the assets creation toolchain: Loaded at runtime in order to open Maya files and import monsters, camera path and maps.
Doom3 Doom3.exe Doom3.app Doom 3 Engine
TypeInfo TypeInfo.exe - In-house RTTI helper: Generates GameTypeInfo.h: A map of all the Doom3 class types with each member size. This allow memory debugging via TypeInfo class.
CurlLib CurlLib.lib - HTTP client used to download files (Staticaly linked against gamex86.dll and doom3.exe).
idLib idLib.lib idLib.a id Software library. Includes parser,lexer,dictionary ... (Staticaly linked against gamex86.dll and doom3.exe).


Like every engine since idTech2 we find one closed source binary (doom.exe) and one open source dynamic library (gamex86.dll).:


Most of the codebase has been accessible since October 2004 via the Doom3 SDK: Only the Doom3 executable source code was missing. Modders were able to build idlib.a and gamex86.dll but the core of the engine was still closed source.

Note : The engine does not use the Standard C++ Library: All containers (map,linked list...) are re-implemented but libc is extensively used.

Note : In the Game module each class extends idClass. This allows the engine to perform in-house RTTI and also instantiate classes by classname.

Trivia : If you look at the drawing you will see that a few essential frameworks (such as Filesystem) are in the Doom3.exe project. This is a problem since gamex86.dll needs to load assets as well. Those subsystems are dynamically loaded by gamex86.dll from doom3.exe (this is what the arrow materializes in the drawing). If we use a PE explorer on the DLL we can see that gamex86.dll export one method: GetGameAPI:



Things are working exactly the way Quake2 loaded the renderer and the game ddls: Exchanging objects pointers:

When Doom3.exe starts up it:

        
        
    gameExport_t * GetGameAPI_t( gameImport_t *import );
        
        
        

At the end of the "handshake", Doom3.exe has a pointer to a idGame object and Game.dll has a pointer to a gameImport_t object containing additional references to all missing subsystems such as idFileSystem.

Gamex86's view on Doom 3 executable objects:

        
        
        typedef struct {
            
            int                         version;               // API version
            idSys *                     sys;                   // non-portable system services
            idCommon *                  common;                // common
            idCmdSystem *               cmdSystem              // console command system
            idCVarSystem *              cvarSystem;            // console variable system
            idFileSystem *              fileSystem;            // file system
            idNetworkSystem *           networkSystem;         // network system
            idRenderSystem *            renderSystem;          // render system
            idSoundSystem *             soundSystem;           // sound system
            idRenderModelManager *      renderModelManager;    // render model manager
            idUserInterfaceManager *    uiManager;             // user interface manager
            idDeclManager *             declManager;           // declaration manager
            idAASFileManager *          AASFileManager;        // AAS file manager
            idCollisionModelManager *   collisionModelManager; // collision model manager
            
        } gameImport_t;
        
        

Doom 3's view on Game/Modd objects:



    typedef struct 
    {

        int            version;     // API version
        idGame *       game;        // interface to run the game
        idGameEdit *   gameEdit;    // interface for in-game editing

    } gameExport_t;

    

Notes : A great resource to understand better each subsystems is the Doom3 SDK documentation page: It seems to have been written by someone with deep understanding of the code in 2004 (so probably a member of the development team).


The Code

Before digging, some stats from cloc:

        
        
     ./cloc-1.56.pl neo
        
     2180 text files.
     2002 unique files.                                          
     626 files ignored.
            
     http://cloc.sourceforge.net v 1.56  T=19.0 s (77.9 files/s, 47576.6 lines/s)
        
     -------------------------------------------------------------------------------
     Language                     files          blank        comment           code
     -------------------------------------------------------------------------------
     C++                            517          87078         113107         366433
     C/C++ Header                   617          29833          27176         111105
     C                              171          11408          15566          53540
     Bourne Shell                    29           5399           6516          39966
     make                            43           1196            874           9121
     m4                              10           1079            232           9025
     HTML                            55            391             76           4142
     Objective C++                    6            709            656           2606
     Perl                            10            523            411           2380
     yacc                             1             95             97            912
     Python                          10            108            182            895
     Objective C                      1            145             20            768
     DOS Batch                        5              0              0             61
     Teamcenter def                   4              3              0             51
     Lisp                             1              5             20             25
     awk                              1              2              1             17
     -------------------------------------------------------------------------------
     SUM:                          1481         137974         164934         601047
     -------------------------------------------------------------------------------
            
        
        


The number of line of code is not usually a good metric for anything but here it can be very helpful in order to assess the effort to comprehend the engine. 601,047 lines of code makes the engine twice as "difficult" to understand compared to Quake III. A few stats with regards to the history of id Software engines # lines of code:

#Lines of code Doom idTech1 idTech2 idTech3 idTech4
Engine 39079 143855 135788 239398 601032
Tools 341 11155 28140 128417 -
Total 39420 155010 163928 367815 601032


Note : The huge increase in idTech3 for the tools comes from lcc codebase (the C compiler used to generate QVM bytecode) .
Note : No tools are accounted for Doom3 since they are integrated to the engine codebase.

From a high level here are a few fun facts:

It is also interesting to take a look at idTech4 The Coding Standard (mirror) defined by John Carmack (I particularly appreciated the comments about const placement).


Unrolling the loop

Here is the main loop unrolled with the most important parts of the engine:

        
        
    idCommonLocal    commonLocal;                   // OS Specialized object 
    idCommon *       common = &commonLocal;         // Interface pointer (since Init is OS dependent it is an abstract method
        
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) 
    {
            
        
        Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 );   //Min = 201,326,592  Max = 1,073,741,824
        Sys_CreateConsole();
            
        // Since the engine is multi-threaded mutexes are initialized here: One mutex per "critical" (concurrent execution) section of code.
        for (int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) { 
            InitializeCriticalSection( &win32.criticalSections[i] );
        }
            
        common->Init( 0, NULL, lpCmdLine );              // Assess how much VRAM is available (not done via OpenGL but OS call)
            
        Sys_StartAsyncThread(){                          // The next look runs is a separate thread.
            while ( 1 ){
                usleep( 16666 );                         // Run at 60Hz
                common->Async();                         // Do the job
                Sys_TriggerEvent( TRIGGER_EVENT_ONE );   // Unlock other thread waiting for inputs
                pthread_testcancel();                    // Check if we have been cancelled by the main thread (on shutdown).
            }
        }
        
        Sys_ShowConsole
            
        while( 1 ){
            Win_Frame();                                 // Show or hide the console
            common->Frame(){
                session->Frame()                         // Game logic
                {
                    for (int i = 0 ; i < gameTicsToRun ; i++ ) 
                        RunGameTic(){
                            game->RunFrame( &cmd );      // From this point execution jumps in the GameX86.dll address space.
                              for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) 
                                ent->GetPhysics()->UpdateTime( time );  // let entities think
                        }
                }
                
                session->UpdateScreen( false ); // normal, in-sequence screen update
                {
                    renderSystem->BeginFrame
                        idGame::Draw            // Renderer front-end. Doesn't actually communicate with the GPU !!
                    renderSystem->EndFrame
                        R_IssueRenderCommands   // Renderer back-end. Issue GPU optimized commands to the GPU.
                }
            }
        }
    }        
        
        


For more details here is the fully unrolled loop that I used as a map while reading the code.

It is a standard main loop for an id Software engine. Except for Sys_StartAsyncThread which indicate that Doom3 is multi-threaded. The goal of this thread is to handle the time-critical functions that the engine don't want limited to the frame rate:


Trivia : idTech4 high level objects are all abstract classes with virtual methods. This would normally involves a performance hit since each virtual method address would have to be looked up in a vtable before calling it at runtime. But there is a "trick" to avoid that. All object are instantiated statically as follow:

        
        
    idCommonLocal    commonLocal;                   // Implementation
    idCommon *       common = &commonLocal;         // Pointer for gamex86.dll
        
        

Since an object allocated statically in the data segment has a known type the compiler can optimize away the vtable lookup when commonLocal methods are called. The interface pointer is used during the handshake so doom3.exe can exchange objects reference with gamex86.dll but in this case the vtable cost is not optimized away.

Trivia : Having read most engines from id Software I find it noticeable that some method name have NEVER changed since doom1 engine: The method responsible for pumping mouse and joystick inputs is still called: IN_frame().


Renderer

Two important parts:


Profiling

I used Xcode's Instruments to check where the CPU cycle were going. The results and analysis are here.


Scripting and Virtual Machine

In every idTech product the VM and the scripting language totally changed from the previous version...and they did it again: Details are here.


Interviews

While reading the code, several novelties puzzled me so I wrote to John Carmack and he was nice enough to reply with in-depth explanations about:

I also compiled all videos and press interviews about idTech4. It is all in the interviews page.

Recommended readings

As usual a few books that you may enjoy if you enjoy the code:

One more thing

Summer is coming and it was not always easy to focus...





...but overall it was a blast to read most of it. Since idTech5 source code will not be released anytime soon (if ever) this leaves me with idTech3 (Quake III) not yet reviewed. Maybe I will write something about it if enough people are interested.


Add a comment



Name Homepage
E-mail
(Will not appear online)
Comment



Comments (75)


#1 - Kel Solaar - 06/09/2012 - 03:31
Awesome and very interesting review! Definitely worth a read!
#2 - Nicolas - 06/09/2012 - 04:29
Hi Fabien,

Very nice article, thanks for sharing your work, I hope you will write a review of id tech 3.
#3 - Rich Jones - 06/09/2012 - 05:07
Excellent! I'm so glad you're doing this for Doom3 - hopefully your insights will help the Doom3 Mod/TC community thrive!
#4 - stef - 06/09/2012 - 05:25
Great article as usually... thanks !!
#5 - Paul - 06/09/2012 - 06:38
I'd to love to read Q3 source review - this game inspired me to start hacking my own little games.
#6 - Hannes - 06/09/2012 - 07:03
Thanks for the analysis and write up.

I cloned repo and tried to find unit and integration tests, but couldn't. Did I miss something?

It's quite amazing that such a big project could be maintained and developed with reasonable velocity without tests.
#7 - Job - 06/09/2012 - 08:21
Nice deconstruction as always!

I found the way Doom 3 did the interfaces on the screens very impressive and immersive - maybe even more than the lighting effects. Can you elaborate a bit on how they did that?)
#8 - Sha - 06/09/2012 - 08:40
Very interesting read!

Of the many forks you mentioned. Can you name some that are actively improving the code and adding features?
#9 - frostyNinja - 06/09/2012 - 09:10
Interesting compilation. Thought I should let you know about a typo:
"...Carmack and we was nice..."
I believe you meant to say "he was nice"

Great article, nonetheless!
#10 - daniel - 06/09/2012 - 11:10
Hi Fabian,
Great read... again!
It is really astonishing that there is one render-pass per light and still run so fluid on 2004 graphics hardware.

Definitely looking forward to a review of idTech3. Besides from the write-up and nice graphics it might be a an "easy" job for you compared to anyone else. With the knowledge of Quake 1 and 2 this will also make it possible to set everything into perspective nicely.

Cheers,
Daniel
#11 - Tom Campbell - 06/09/2012 - 12:24
Love these. Of course I'd be delighted if you did an idTech3 review.
#12 - Shawn - 06/09/2012 - 12:34
A wonderful article!

I've enjoyed your past code reviews so much I've gone back and read them more than once; I'm certain I will read this at least a few times!

I sincerely appreciate the time you took to write this. I hope that you have the time to review iDTech3 as well, especially since it will provide an opportunity to compare and contrast how the codebase has progressed since then.
#13 - Brian Cardarella - 06/09/2012 - 13:13
Awesome, amazingly well done!
#14 - J - 06/09/2012 - 14:30
Vancouver? Cool! Nice views. Thanks for the article.
#15 - Amir Masoud Abdol - 06/09/2012 - 15:31
Such an interesting thing to do :) Thanks for the notes.
#16 - Indloon - 06/09/2012 - 15:50
Please,review the Id Tech 3 engine :)

You ill get a cookie for that ^^
#17 - Los Puerco Lobos - 06/09/2012 - 16:26
I felt the love so hard
#18 - Neil - 06/09/2012 - 16:55
Great article!

Can you explain how the use of statically instantiated instances of system level objects and the use of a pointer to their abstract base classes avoids the usual vtable lookup overhead?
#19 - Will Lam - 06/09/2012 - 18:35
Nice write up! Didn't know you're leaving in Toronto - awesome!
#20 - Gaffer - 06/09/2012 - 19:02
Fantastic work. Thanks!
#21 - Venser - 06/09/2012 - 19:39
Quake 3 please
#22 - Kaiyi Li - 06/10/2012 - 01:38
Fabien, I spotted this on hacker news. You effort in this article is incredible and impressive, very clear and easy to understand. If you remember, we've worked together briefly in 2009, and I am happy to see that you're doing well in Toronto. Hope all the best.
#23 - Albert1 - 06/10/2012 - 07:27
Good work, Fabien!
However, id's Trinity is named after the Dallas Trinity River, as Carmack explained in this interview http://www.firingsquad.com/features/carmack/
#24 - Ralph Schaafsma - 06/10/2012 - 08:09
Very interesting read. I'd like to see a ID-T3 code review from you as well.
#25 - Nikita - 06/10/2012 - 08:12
That's so awesome! I've been waiting for id Tech 4 review for ages!
You've got some very interesting stuff here :)
#26 - Emmanuel Astier - 06/10/2012 - 08:26
Hi,

Great job for this very interesting article.

One question, you said :
"Abstraction and polymorphism are used a lot across the code. But a nice trick avoids the vtable performance hit on some objects."

Can you tell us a little more about this 'nice trick' ?

Thanks !
#27 - Harley - 06/10/2012 - 15:16
+1 for idTech3 review
#28 - Volker - 06/10/2012 - 15:43
Really great article. In-depth explanations like this is what a lot of open source projects would need to attract more developers.

A Quake3 review would also be very nice (or even ioquake3?).
#29 - cristaloleg - 06/11/2012 - 02:25
Great work! Thank's.
#30 - Keith Kaisershot - 06/11/2012 - 03:17
From your notes in renderer.txt:

// the following is Mr.E's code
// Note from FAB WHO is Mr.E ?

FWIW I'm going to hazard a guess and say that Mr.E is "Mr. Elusive" a.k.a. Jon Paul van Waveren. =)
#31 - Carsten Holtkamp - 06/11/2012 - 09:20
Haven't read this article yet. Just a quick overview, but it looks good. I am quite interested in static source code analysis, especially with nice helping graphics. Just wanted to add as a note, there was a overview of the id3tech source already started:
http://element61.blogspot.de/2005/08/looking-at-quake-3-source-part-1.html
http://element61.blogspot.de/2005/08/looking-at-quake-3-source-part-2.html
http://element61.blogspot.de/2005/09/looking-at-quake-3-source-part-3.html

A lot of work was done on ioquake, and there is a nice improve code aswell (normal maps, png textures and so on):
http://www.moddb.com/mods/etxreal
#32 - Yiming Qian - 06/11/2012 - 10:07
LOL,in the second last picture, I can see the background was Ryerson University
#33 - Jean-Francois Moy - 06/11/2012 - 11:24
Great post, thank you for your in-depth analysis.
#34 - Vikram - 06/11/2012 - 11:34
You made me cry.. Thanks for this
#35 - Viktor Liehr - 06/11/2012 - 12:09
Thanks Fabian for your Review, it was a great read! I would be really interested in if you complete your review of idTech3.
#36 - Jonathan - 06/11/2012 - 16:49
Thanks for this! I found it very interesting to read! I happen to have the Doom 3 cds laying around so I installed it and played it a little (brings back memories). I was able to compile the Doom 3 source code successfully but when I transferred it to where the original Doom 3 exec is(and where the Base dir is) I got the following error. It seems to find the pak files okay but then exits out.

DOOM 1.3.1.1304 win-x86 Jun 11 2012 15:14:43
4081 MHz AMD CPU with MMX & SSE & SSE2 & SSE3 & HTT
15840 MB System Memory
0 MB Video Memory
Winsock Initialized
Found interface: {53C6CF71-C4AA-4430-9C4C-DAF112BEA668} Intel(R) 82583V Gigabit Network Connection - 192.168.1.130/255.255.255.0
Found interface: {2B7C12A1-7F58-4FAE-B3EA-1A35703E9055} VirtualBox Host-Only Ethernet Adapter - 192.168.56.1/255.255.255.0
Found interface: {0D903444-3D1B-4028-850D-2058C798DBBF} VMware Virtual Ethernet Adapter for VMnet1 - 192.168.88.1/255.255.255.0
Found interface: {4EB006CA-2A77-4C41-9349-05E7EDCEE56B} VMware Virtual Ethernet Adapter for VMnet8 - 192.168.109.1/255.255.255.0
Sys_InitNetworking: adding loopback interface
doom using MMX & SSE & SSE2 & SSE3 for SIMD processing
enabled Flush-To-Zero mode
enabled Denormals-Are-Zero mode
------ Initializing File System ------
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\game00.pk4 with checksum 0xf07eb555
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\pak000.pk4 with checksum 0x28d208f1
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\pak001.pk4 with checksum 0x40244be0
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\pak002.pk4 with checksum 0xc51ecdcd
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\pak003.pk4 with checksum 0xcd79d028
Loaded pk4 C:\Program Files (x86)\DOOM 3\base\pak004.pk4 with checksum 0x765e4f8b
Current search path:
C:\Program Files (x86)\DOOM 3/base
C:\Program Files (x86)\DOOM 3\base\pak004.pk4 (5137 files)
C:\Program Files (x86)\DOOM 3\base\pak003.pk4 (4676 files)
C:\Program Files (x86)\DOOM 3\base\pak002.pk4 (6120 files)
C:\Program Files (x86)\DOOM 3\base\pak001.pk4 (8972 files)
C:\Program Files (x86)\DOOM 3\base\pak000.pk4 (2698 files)
C:\Program Files (x86)\DOOM 3\base\game00.pk4 (2 files)
game DLL: 0x0 in pak: 0x0
Addon pk4s:
file system initialized.
--------------------------------------
----- Initializing Decls -----
------------------------------
------- Initializing renderSystem --------
using ARB renderSystem
renderSystem initialized.
--------------------------------------
4966 strings read from strings/english.lang
Couldn't open journal files
execing editor.cfg
execing default.cfg
execing DoomConfig.cfg
"\\" isn't a valid key
couldn't exec autoexec.cfg
4966 strings read from strings/english.lang
----- Initializing Sound System ------
sound system initialized.
--------------------------------------
found DLL in pak file: C:\Program Files (x86)\DOOM 3\base\game00.pk4/gamex86.dll
copy gamex86.dll to C:\Program Files (x86)\DOOM 3\base\gamex86.dll
idRenderSystem::Shutdown()
Shutting down OpenGL subsystem
...shutting down QGL
wrong game DLL API version
#37 - Jonathan - 06/11/2012 - 20:07
Ok..got this fixed. Updated to the latest patch (1.3.1) and now it works now with the compiled code!
#38 - Pavel Shevaev - 06/12/2012 - 00:01
Fabien, many thanks. It's an amazing amount of priceless information. id should hire you, seriously :D
#39 - Dominik - 06/12/2012 - 03:56
Thanks a lot Fabien for your great work here! This is so damn interesting. Keep it on! :)
#40 - abitofcode - 06/12/2012 - 04:15
Great write up!
#41 - vanhelgen - 06/12/2012 - 06:21
Great article, as for the tool support: I recommend using a vector drawing program (e.g. Inkscape) the svg markup can be embedded into the html document and you can even style the svg elements with css. If you prefer something more geeky you could use some charting library with an svg renderer like Raphael.js to implement a tool by yourself.
Hope this helps, have fun!
#42 - Joe Garret - 06/12/2012 - 06:56
nice what you are doing. Anything in plan for android?
#43 - Kirill - 06/12/2012 - 12:04
Man, thats great work !!! Thank you very much!
#44 - Nick - 06/12/2012 - 18:38
Thank you!!! I appreciate it to nth degree! Keep being awesome!
#45 - Gustavo De Micheli - 06/13/2012 - 10:09
Great reading!! Its awesome how the article explains the insides of the engine.
I think that it would be super cool that you do the review on idTech3 (for the sake of completitude? he).
#46 - Edouard - 06/14/2012 - 05:16
Amazing, as usual !
And yes, a Quake 3 code review would be awesome ;)
Keep going, you rock.
#47 - bijup - 06/14/2012 - 08:38
for those who want to compile iodoom3 source in visual c++ express editions, please follow this guide http://icculus.org/~riot/doom3_vcpp_express.txt
#48 - bijup - 06/14/2012 - 08:40
yes please, could u review idtech3 as well? tyvm for this
#49 - Lelala - 06/14/2012 - 10:50
Fabien, WOW! Thanks for that great article.
Nice to see someone actually took down some deep steps into Johns system.
Just inspirating :-)
#50 - Den - 06/24/2012 - 22:10
Wow cool. thanks man. very thanks for review.
#51 - slaj - 06/25/2012 - 19:34
really awesome article!
#52 - Tigrou - 07/06/2012 - 08:01
Hi Fabien, very nice review as usual. I already figured out a lot of things a long time ago while looking at code by myself but some things remained a mystery and your review cleared them out.

There is still one thing i don't not understand : network update code (idAsyncNetwork::RunFrame()) seems to be called only once in main loop.

Thats means someone with a pretty slow graphic card (eg : only capable of 10 fps) will only send packets to server at same rate.
Other players would see him with "laggy movement" while it could be a lot better.

Why idAsyncNetwork::RunFrame() could not be placed in a separate thread (like input and sound mixing) and thus packets would be send to server independently from updating the world and rendering ?

IMAO mostly user commands are send to server, so there is no need to have world updated (using game->runframe()) before sending this information.
#53 - Fabien Sanglard - 07/06/2012 - 08:09
@tigrou:

1. Shaggy movement are avoided via client position prediction.
2. There is little value in sending commands at 60Hz is the player cannot even see the result of its actions.
#54 - Prashant - 07/07/2012 - 00:59
the link to id tech 4 coding standard work:
ftp://ftp.idsoftware.com/idstuff/doom3/source/CodeStyleConventions.doc

is there any other place this can be downloaded from?
#55 - Fabien Sanglard - 07/07/2012 - 15:28
@Prashant: I uploaded a mirror in pdf version:

http://fd.fabiensanglard.net/doom3/CodeStyleConventions.pdf
#56 - Viktor - 08/17/2012 - 11:09
Another little GEM of a review.

Big Thx
#57 - Caveau - 09/20/2012 - 10:59
Hi, This is a very great article. Nice deconstruction as always.
Thank you for sharing with us !
#58 - M. Sponholz - 10/06/2012 - 22:32
You inspire me good sir!!
#59 - Pesarak - 10/15/2012 - 00:53
I don't get this part "The engine was developed with Visual Studio .NET (source). But the code does not feature a single line of C#" ... hearing this from -you- is really strange since you seem to be an experienced professional ! it gives me the impression that you think VS can/should only be used when C# is needed, am I right?!

anyways... like it or not, good or bad, when your main target platform is MS Windows, your best option is Visual Studio !
#60 - Pesarak - 10/15/2012 - 01:56
I'm going through this review and your notes and I have to say THESE ARE GREAT ! thanks for posting them
#61 - fabien sanglard - 10/16/2012 - 19:10
@Pesarak

Of course you can use C and C++ with VS.NET.

But when the .NET framework and associated Visual Studio were released, there were strongly associated with C#, VB and J++ (see CLI Infrastructure). Developers were strongly encouraged to use things that would have tied the codebase to Windows but the id software dev team did no use any of those Microsoft only features and I found it amusing.
#62 - Pesarak - 10/17/2012 - 11:44
@Fabien

Hi there, thanks for the reply :)

I do agree with your statement, Microsoft naturally intended VS to be used mainly for Windows-only purposes, but as I said in my first comment, in general, if your main target platform is MS Windows (or Xbox) or even if it is not, but you're developing on an MS Windows machine (personally I've been doing iOS and Android development on VS2010), your best option in terms of both the IDE and the C/C++ compiler is Visual Studio. In particular Visual Studio's profiler, performance analyzer, code analysis, and even debugger -at least on MS Windows- is truly unmatched.

I'm not saying it is the best option that could exist, of course people with another mindset than Microsoft's could come up with something much better, but the truth is that at least on the MS Windows front this hasn't happened yet. VS is the best option that does exist at the moment until someone or some company comes up with something better.

So I still don't get your point but that doesn't really matter :)

I'm truly amazed by this review and your notes, believe it or not I have made this page as one of my many browser's home pages ! again, thanks for posting your notes and this review. I really needed it and it has helped me a lot.
#63 - john Smith - 10/17/2012 - 13:26
Great work Fabien, thanks!
#64 - Judd - 10/26/2012 - 15:42
Holy cow! my friend sent me this link knowing that I was such a huge Doom and Quake nut. Such memories.. ahh.. the LAN parties.

Thanks for digging into the source code to write this. I wish I took up programming in my earlier years to understand the more technical aspects of this post :)
#65 - FipS - 12/21/2012 - 11:32
Good reading! Thanks for your effort.
#66 - Alistair - 01/15/2013 - 16:04
I'm not sure I would have done anything with that view from the window! Great review, very helpful. Thanks.
#67 - Latorie - 01/17/2013 - 21:45
Great game, great article - thanks!
#68 - nitrofurano - 01/18/2013 - 15:25
i wonder why Linux and others are not being cited in this article? :S
#69 - André Taiar - 01/25/2013 - 13:13
Wow... That's a cool article!

Congratulations!
#70 - Eli - 01/29/2013 - 07:17
Well done Fabien! Another masterpiece article.
#71 - Arman - 02/17/2013 - 13:37
Awesome job, this helps immensely the programmers, to learn about a huge project's architecture. The notes you made are priceless! Can't thank you enough, keep it up :]
#72 - Robert - 02/21/2013 - 21:22
Does anybody know why the Game is a DLL and the Engine is an EXE file? It looks counter-intuitive as we normal see it the other way around. Is it for modding? Or does it have some inner design decision that I can't understand?
#73 - Jay McGavren - 02/27/2013 - 23:11
Here's the game footage from my first couple experiments (bouncy barrels, enemies attack each other): http://www.youtube.com/watch?v=fjs8FHtrxf0
#74 - stephen - 03/12/2013 - 00:03
Thanks for your work! I plan on starting my study of this well documented site!
#75 - Xiaoming Nan - 05/16/2013 - 05:47
Awesome! you are from Ryerson U? Great! I'm at Ryerson, too. Just start studying cloud gaming. Maybe we can find a time to chat.

 

@2012