Skip to content

Engine Quick Start Guide

SiPlus edited this page May 17, 2015 · 3 revisions

Introduction

This document is aimed at people with at least a basic knowledge of C concepts who are getting ready to explore the game source-code. Most things said here will probably apply to other Quake 2 (and maybe 3) based games, since qfusion is based on the original Quake 2 engine.

The basics

Qfusion is a program built around 'frames'. First the program reads inputs, then it 'thinks', modifying the current gamestate, and then implements the current state.

This means, that there is 1 major loop handling all application logic. This called a 'state machine' design, which can be confusing when you used to straight-forward procedural or object-oriented programming.

This may sound pretty abstract, but this is due to the fact that qfusion is a client AND a server with exactly the same source code. This means that in the big lines, the same steps are taken for both the client and the server. Of course, once digging deeper into the code, things will start looking very different, since the server is the one who actually makes all decisions, sends state-changes and events to the client (or clients), who then alter their local state and implement it (as in: build the scene and render it).

Main loop

Since Qfusion can be run on Windows, Linux, Android and has some basic Mac OS X support, there are different platform-specific entry-points for each platform. They all do the same: first some basic initialization, followed by running the state-machine loop, which looks like this: (semi-pseudo-code)

while (true) {
	time = <the current time in milliseconds>
	Qcommon_Frame( time )
}

This loop never quits and is executed ever frame. The Qcommon_Frame function is a real function which can be found in the "qcommon/common.c" file. This is not a very interesting function on it's own, it does very little decision making and just calls a bunch of different other functions in a certain order. These functions are more interesting, they actually do things. However, for most changes in the code you will have to dig a bit deeper, but knowing this can be useful to understand the whole thing a bit better.

The modules

Basically the game is organized in different modules, which are mostly organized in directories. This is the 'main' list of the directories with their short descriptions:

  • cgame : Client Game module responible for the client-side handling of the gameplay.
  • client : Client module, containing generic client-specific code not responsible for gameplay.
  • game : Game module, running on serverside which performs all decisions about the game, depending on gametype. This also contains the AI (Artificial intelligence) code for the bots.
  • gameshared : Generic gamecode used by both the cgame and game module.
  • qcommon : Quake engine 'common' files, used by most modules
  • ref_gl : This contains the OpenGL render-code.
  • server : Contains code for specific for the server-logic
  • ui : Does the user-interface drawing and handling
  • irc : built-in IRC client module
  • null : Empty implementations of the client module and platform specific video initialisation for dedicated servers. Also contains an empty platform sys implementation (sys_null.c) to help porting.
  • angelwrap : Angelscript-wrapper module, exporting C++ API to the game module and C++ UI module. Also handles commonly present AS methods and classes.
  • cin : Video codecs module
  • matchmaker : Interface to remote matchmaking and statistics system
  • ftlib : Font rendering abstraction layer. Handles all actual file formats specifics.
  • tv_server : TV server

For the sound sub-system, 2 different backends exist at the moment, which are dynamicly loadable. These are:

  • snd_openal : Sound backend using the multiplatform OpenAL libraries
  • snd_qf : qfusion/SDL sound backend

Then we also have the 'platform' modules, which contain all platform specific functions, initialization, wrappers, like startup, keyboard input, graphics initialization, filesystem access, network access, generic library functions, sound, ...

Currently the following platforms are available for qfusion:

  • win32 : Windows
  • unix : Linux/BSD/*nix X11
  • mac : Mac OS X
  • android : Android
  • sdl : Cross-platform SDL backend

Naming conventions

Due to the fact that C does not have namespaces, strict naming-conventions are used for non-static functions to avoid problems with name-collisions.

Both the files and functions should have a module-specific prefix:

  • r_ : Render code (OpenGL)
  • cg_ : Client Game module
  • cl_ : Client module
  • g_ : Game module
  • ai_ : Artificial intelligence (bots) code
  • gs_ : Game Shared, code shared between the game and clientgame module.
  • irc_ : IRC Module
  • snd_ : Code for a sound module (qf or openal module)
  • ui_ : User interface code
  • tv_ : TV server code
  • tvm_ : TV game module code

Platform specific files also have their platform as a prefix.

Public functions of a certain library (except for the platform specific functions of course) use the same prefixes, but in capital. The "CL_NetFrame" function for example is part of the Client module. Function names are in camelcase.

The client

The server

Entities

Clone this wiki locally