Element 61

Wednesday, August 24, 2005

Looking at the Quake 3 Source -- Part 2

I had previously said that I was planning to cover the rendering architecture in part 2. I even wrote up a draft. Problem is, it isn't any good. I tried to describe both the architecture and the code at once, and ended up doing a miserable job of both. So instead, what I'm going to do (presumably for part 3) is to cover the high level rendering system, which has been publically known for several years if you've worked with modding or even just artwork. After that, I'll delve into how that architecture is actually implemented underneath. In the meantime, I want to address some of the questions people have been asking, and also generally give an overview of how the game flow is structured. The actual entry point, WinMain, is in code/win32/win_main.c. The main loop is really very simple. It updates the current time, accesses input, and then runs a frame. The actual frame logic starts from the Com_Frame function, which is at line 2635 of code/qcommon/common.c. There's a lot of misc stuff going on in this function, but if we just cut our all the extra and just keep the important things, it would look like this (pseudocode):

void Com_Frame( void )
    if( fps > max_fps )


    if( !dedicated_server )

    //performance analysis and stuff here
The client code is smeared between the "cgame" folder, which stands for client-game, and the "client" folder. The server code is entirely in the "server" folder. Everything that's used for making mods resides in the "game" folder.
Simple, yes? First we execute the server frame (there is always a server). That function is defined in code/server/sv_main.c, line 751, and it's also rather simple. Similarly, CL_Frame is called if we're not a dedicated server (i.e. a client side exists). That function is in code/cgame/cl_main.c, line 1997. Again, really well commented over here, and it's very straightforward. Now, I'm going to stop there to avoid recursing infinitely into the engine, but here's a hint -- use Find In Files. If you're finding too many calls to a function and not the actual function definition, try searching for "void Foo" instead of just "Foo". If you're finding too many uses of a struct and not the actual definition, try "struct Foo_s" or "} Foo_t". The Quake code is really consistent this way, so a few clever alterations of the Find In Files string will quickly hunt down what you need. But best of all, VS 2k3 will usually be able to very quickly and easily find the definition. Just right click and hit "Go to definition" in the menu. (VC6 users will need to enable Browse Info and do a complete rebuild.)

A few people mentioned the Q3 VM, and the odd presence of a C compiler, lcc, in the source code. This is for QuakeScript, and from what I can figure so far it's a replacement for normal game DLLs. In other words, I have almost no idea what it's for. Give me some days (actually, a week or so) to finish dissecting the parts of the engine I'm most interested in, and then we'll move on to other things. I understand that the VM is a bit looming, given that there are references to it all over the place, but I want to have a thorough understanding of what it's doing before I start trying to explain it.

Anyway, that's quite all for tonight. Sorry about the short entry, as I did spend most of today taking apart the rendering code and finding out that it's a bit more complex than I originally thought. Tomorrow you can expect a solid, non-code oriented explanation of how the Quake 3 rendering subsystem works. After that, we'll dive in and take a look at the implementation. (And maybe we'll sneak cvars in there somewhere. Who knows?)


  • Any knowledge or understanding shed onto the Quake 3 Source is goooood! Keep on rocking, and come join the crew over at http://quake3.quakesrc.org/ soon the site will be running, and all this goodness can go to good use. Again, thank you.

    By Anonymous Justin Walsh, at 8/25/2005 3:44 AM  

  • Carmack wrote a bit about his ideas for the Virtual Machine in has .plan files early on in Quake 3's development. You can read the original post HERE and HERE

    The most relavant part of it all, I think is this: "Most mods will be able to be
    implemented with just the interpreter, but some mods that want to do
    extensive file access or out of band network communications could still
    be implemented just as they are in Q2. I will not endorse any use of
    binary client modules, though."

    So yes, they are inteneded to be replacements for standard DLL code, mostly for security reasons. I rember doing some simple mod work afte Q3 first came out and it was highly encouraged that you run your mod using this virtual machine rather than compiling it into a DLL.

    By Anonymous Anonymous, at 8/25/2005 12:23 PM  

  • Your two blog posts on the Q3 source were good reads. Thanks.

    By Blogger Shedletsky, at 8/25/2005 1:35 PM  

  • Really enjoying it, dude! Keep on your work

    By Blogger wirth, at 8/25/2005 8:24 PM  

  • *Eagerly awaits next entry*

    By Anonymous Seth Willits, at 8/27/2005 2:52 AM  

  • Just thought I'd mention that I've enjoyed both write-ups you've done so far. There aren't any specific parts of the code that I'm looking to have explained, so I don't have any suggestions on what to do next, but I'll definitely be back to read whatever you decide to do. Keep up the good work.

    By Anonymous George, at 9/02/2005 9:04 AM  

    CL_Main() is in code/client/cl_main.c

    not code/cgame/cl_main.c

    keep up the good work

    By Anonymous anton, at 9/03/2005 12:35 AM  

  • ... I meant CL_Frame()

    By Anonymous anton, at 9/03/2005 12:38 AM  

Post a Comment

<< Home