Technical Documentation

From Unvanquished
Jump to: navigation, search
Elderly Man chasing a granger.svg

Page out of date
Some of this content is out of date.

If you have a question that is not answered here, you can always hop on IRC.

Getting Started

If you have not already, go get the code, read up on your options for development environments, and compile it. Instructions are available for a variety of platforms. If your platform of choice is not listed, you are welcome to add instructions for it.

From there, play the game! The Running the game page contains documentation on all the most commonly used and user-accessible commands and console variables. If you have trouble, see the troubleshooting page for possible solutions.

There are also very detailed instructions on testing the game, which includes information on using sophisticated profiling tools such as apitrace, GPUPerfStudio, gDEBugger, valgrind, and clang-analyzer.

Need something to work on?

There are all sorts of existing tasks listed on our issues reported on the bug tracker you are free to fix. Please drop in on IRC and tell us what you're up to.

Giving Back

You are welcome to contribute in any way possible! We have guidelines for contributing code as well as documentation on coding conventions.

Language Oddities

  • You must use the INLINE macro instead of inline.
  • You must cast integers that are being used as enum values to an enum type. For example:
    BG_Class ( ( class_t ) self->client->ps.stats[ STAT_CLASS ] )

Source Code & Data Structure

  • main/ Data associated with the game.
    • def/ Entity definitions for Radiant.
    • fonts/
    • gfx/
    • glsl/ OpenGL shader code.
    • lights/
    • models/
    • scripts/
    • sound/
    • translation/
    • ui/
  • src/
    • engine/ Engine source code.
      • asm/
      • client/
      • null/
      • qcommon/ Common code: utility functions, typedefs, macros, and the like.
      • renderer/ Vanilla (fixed-function pipeline) renderer
      • rendererGL/ Modern XReal-based renderer
      • server/
      • sys/
    • gamelogic/ Code that falls outside the scope of the core engine. These are all run in separate virtual machines.
      • cgame/ Client-side game code.
      • game/ Server-side game code.
      • ui/ User interface code.

Program Entry Point

The main function may be found at around line 591 of src/engine/sys/sys_main.c. Note that some magic happens on the Mac in src/engine/sys/SDLMain.m.

Lag Compensation

Daemon uses Neil "haste" Toronto's Unlagged mod.

Data Files

Daemon uses a variety of file formats. Many of these formats are custom.

Game Logic

Game logic is split into three areas: user interface, server-side, and client-side. Each runs in its own virtual machine.


Buildable information is encapsulated in the cg_buildables array (declared in src/gamelogic/cgame/cg_main.c)

Constants used to define gamelogic variables are in src/gamelogic/game/tremulous.h.


  • buildableInfo_t — Encapsulates data associated with buildables (sounds, animations, etc.).
  • buildable_t — An enumeration of all buildable types.
  • buildableAttributes_t — Encapsulates gameplay information associated with buildables. There is an array of these called bg_buildableList.


Server game state initialization occurs in G_InitGame() in src/gamelogic/game/g_main.c.

Particle & Trail System

For now, please see the Tremulous documentation.

GL3 Renderer

Source code for the modern OpenGL renderer is located in src/engine/rendererGL. This renderer is often referred to as the "GL3" renderer, whereas the legacy renderer (found in src/engine/renderer) is often referred to as the "vanilla" renderer.


  • There is some incomplete disabled Direct3D code mixed in the modern OpenGL renderer code.
  • Shaders are implemented as subclasses of the GLShader class. All are defined in src/engine/rendererGL/gl_shader.h.
  • Each GLSL shader has their compilation and loading controlled by the single GLShaderManager class
  • Compiled shaders are cached to disk when possible to speed up load times
  • Shader compilation may be done up front before the game loads, or delayed till the main menu depending on the value of r_lazyShaders
  • All possible parameters (what OpenGL calls "uniform variables") that may be passed to a shader are enumerated through multiple inheritance.

E.g., gl_genericShader is of type GLShader_generic* which derives from the following classes:

    • GLShader
    • u_ColorMap
    • u_ColorTextureMatrix
    • u_ViewOrigin
    • u_AlphaTest
    • u_ModelMatrix
    • u_ModelViewProjectionMatrix
    • u_ColorModulate
    • u_Color
    • u_BoneMatrix
    • u_VertexInterpolation
    • u_PortalPlane
    • GLDeformStage
    • GLCompileMacro_USE_ALPHA_TESTING
  • The u_* parent classes provide functions that allow external code to set shader uniforms. e.g gl_genericShader->SetUniform_ColorTextureMatrix()
  • GLSL shaders may be found in main/glsl/. Please see the full article for a complete listing.

Helper Classes

As mentioned above, shader classes make use of multiple inheritance to give them the relevant methods for controlling their behavior.

Compile Macros

Compile macros are used to reduce the number of uniforms needed, and speed up execution by eliminating useless if ( ) statements.

They also allow for easy code reuse when turning off some features like e.g Normal Mapping.

Compile macros are set when rendering before the call to shader->BindProgram().

  • GLCompileMacro_EYE_OUTSIDE
  • GLCompileMacro_USE_SHADOWING
  • GLCompileMacro_USE_GBUFFER


Mac OS X users with XCode installed can access OpenGL man pages via the terminal.

Alternatively, OpenGL API reference documentation is available online:

Valgrind and fglrx

fglrx drivers cause Valgrind to spew out a lot of false errors. You can suppress these by using the --suppressions=/path/to/file.supp flag. You must pass the full path (no use of the tilde symbol). The following file can be used as a template for your suppression file. Keep in mind that the location of the fglrx library may need to be changed.



General Game Development