Modder's Code Overview
Rating: 3
TODO:
- CGAME
- GAME
- UI
This article gives an overview of the Tremulous codebase. If you have a great mod idea in mind but aren’t sure which part of the code to start hacking at, this is the place to go. It is assumed that the reader is a competent programmer and already has a development environment setup and ready for use.
Installation
First, you need a copy of the source code. The procedure for obtaining and compiling the code depends on your operating system. Currently, Tremulous is developed primarily on Unix systems and the simplest procedure for Windows compilation is to essentially setup a Unix environment. Risujin wrote a guide on how to compile Tremulous on Windows.
Obtaining the source is very easy on Unix. You will need svn (subversion). The Tremulous source is hosted on http://www.icculus.org, so use the svn checkout command to fetch it:
svn co svn://svn.icculus.org/tremulous/trunk tremulous
This will download the latest version of the source to the ‘tremulous’ directory.
Compiling Tremulous
Tremulous does not come with a portable compilation mechanism and instead relies on a Makefile. You do not need to modify the Makefile normally. You can control what is built by creating an input file to it called Makefile.local.
Makefile.local contains switches to enable and disable the various portions of the compile process. Here is an example Makefile.local to compile the QVMs only:
BUILD_CLIENT = 0 BUILD_CLIENT_SMP = 0 BUILD_SERVER = 0 BUILD_GAME_SO = 0 BUILD_GAME_QVM = 1
The following switches are supported:
BUILD_CLIENTcompiles the client binary (tremulous.x86).BUILD_CLIENT_SMPcompiles the multi-processor binary.BUILD_SERVERcompiles the dedicated servertremdedon Unix.BUILD_GAME_SOcompiles the game binaries as dynamic libraries, useful primarily for debugging withgdb.BUILD_GAME_QVMcompiles the distributable virtual machine bytecode files.
Directory structure
Tremulous is based on the ioquake3 and inherits its directory structure. Unless you are interested in distributing your own client, you will not be at liberty to modify most of these folders. The top level directories are as follows.
buildis where the compiled binaries will end up when you runmake. Inside a directory for the release and platform will be created (e.g.release-linux-x86for a non-debug build on Linux). Depending on your settings, you will find your QVMs and compiled program binaries here.misccontains miscellaneous files distributed with Tremulous.srccontains the source code (details below).uicontains shell scripts and input files for creating the menu definition scripts.
The source code
Most of the directories within the source code pertain to specific functions of the client or server and aren’t easily modifiable. The src directory contains the following:
cgamecontains the client game VM code.clientcontains the portable client program code.gamecontains the server game VM code.jpeg-6contains the source of the JPEG 6 library, enabling JPEG image support.libcurlcontains thecurllibrary headers.curlis used for HTTP file transfers.libscontains library binaries for various operating systems.mastercontains the master server source and has its ownMakefile.nullcontains empty function bodies to give the portable client and server code something to link to in case Tremulous is compiled without some functionality (when compiling the dedicated server for example).qcommoncontains common code that is shared across the server/client and VM boundary.renderercontains the added Tremulous renderer functionality.SDL12contains the Simple DirectMedia Layer library headers.servercontains code for the dedicated server.toolscontains the source for the Quake VM compiler tools, these are called by theMakefilefor you.uicontains code for the user interface virtual machine.unixcontains Unix platform-specific client/server code.win32contains Windows platform-specific client/server code.
As long as you contain your changes to the virtual machine, scripts, and other distributable data files you will not have to distribute your own client or server and clients will be able to download your mod automatically by connecting to a server that is running it. The rest of this article assumes that this is your intention.
Common
The common code contains tools to make basic tasks easier. You will find basic types, vector, and math functions here. You cannot modify the files here.
surfaceflags.h
This header defines the various flags used by the engine BSP tree. CONTENTS flags define how the contents of a bounding box are treated.
Of particular interest the following flags will result in trace hits for player collision, hitscan, and missile detection:
CONTENTS_SOLIDCONTENTS_PLAYERCLIPCONTENTS_BODY
q_shared.h
If you find yourself aching for a standard library function, chances are it is prototyped here, with an added Q_ to the function name. You will also find length limits, various flags, and basic structure definitions here.
Various math and vector functions are prototyped here. The vector type used by the engine is deceiving:
typedef float vec_t; typedef vec_t vec2_t[2]; typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; typedef vec_t vec5_t[5];
The vector type is not a structure but a pointer to an array of three floating point values. When a function is passed a vector type, it can modify it.
Many of the various vector functions are simply macros to make the code more compact, do not be confused:
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
You will also find functions here to convert between angles (in degrees) and axis (vectors pointing at an angle).
The engine provides convenience functions to parse string tokens:
char *COM_Parse( char **data_p );
The structures defining the cvar system are defined here. The actual cvars are defined within the VMs they are used in.
The BSP trace functions and structures and their flags are defined here. The CONTENTS flags are used with the trace system.
Most importantly, the entity structures that are passed over the network between clients and servers is defined here. Pay careful attention to playerState_s and entityState_s. Any changes made to these structures are automatically detected and transmitted to clients. The only other channel of communication is to send console commands from the server.
Game
The src/game directory contains the code that will be compiled into the server game virtual machine. This is the game.qvm file that you see distributed. If you only modify this, connecting clients will not need to download anything at all.
Warning: When distributing a game.qvm there are two important compatibility considerations. The first is which client is it compatible with:
- SVN 880 and later is naturally only compatible with SVN protocol 70 clients.
- SVN 879 and before use protocol 69 and are naturally compatible with the stock 1.1.0 client.
Think that’s bad enough? The game.qvm must also be compatible with the server! There are three server versions:
- Stock 1.1.0 dedicated server is protocol 69 with 1.1.0 syscalls. This kind of server is not in common use.
- TJW’s backported
tremdeduses protocol 69 but SVN syscalls. This is the most common kind of server. - SVN server uses protocol 70 and SVN syscalls.
If you distribute a client PK3, you can start with a fresh SVN and apply a backport patch to make a 1.1.0-client compatible build. You can find backport patches on the patch tracker: http://www.mercenariesguild.net/patches/
g_active.c
timed events
like running out of stamina if you are moving
g_admin.c
Contains definitions and implementations of all admin commands (those that start with !).
g_buildable.c
g_client.c
g_cmds.c
g_combat.c
g_local.h
g_main.c
g_maprotation.c
g_mem.c
g_misc.c
g_missile.c
g_mover.c
g_physics.c
g_ptr.c
g_public.h
this defines the functions imported from the main executable and the functions exported to the main executable this is used while building main executable The enum gameImport_t should match the g_syscalls.asm in case of building qvm for example if something in enum has value i it should have the calue i+1 in the g_syscalls.asm
g_session.c
g_spawn.c
g_svcmds.c
g_syscalls.c/.asm
This is how game interfaces with the client (ie the functions that are already available in the client) .c is for dynamic library .asm is for qvm be careful with these files
g_target.c
g_team.c
g_trigger.c
g_utils.c
g_weapon.c
tremulous.h
Damage/HP values, charge times, etc. It is quite understandable (you don’t need to know coding).
Both Games
The client and server game virtual machines have a lot of functionality in common. Rather than replicating code in both directories, the bg_ files in src/game are included when compiling both virtual machines.
bg_lib.c/.h
The virtual machines are not linked to any library and so must provide replacements for common standard library functions. These are prototyped in bg_lib.h and defined in bg_lib.c.
bg_local.h
Prototypes internal to the bg_ files.
bg_misc.c
This file serves as the database for the engine. You will notice struct arrays holding statistics for various kinds of entities here.
You also will find the definitions for the various BG_ functions that search the struct arrays here. Their names are fairly self-explanatory.
Note: Keep in mind that these are the hardcoded values and that there is a system for overriding them through the override scripts in the data PK3. Do not be frustrated if your changes are not showing up, you should edit the override cfg file instead.
The first of these is the buildables array, buildableAttributes_t. The values here define some general attributes of all of the buildables. Note that if you set health to 0, the buildable will never finish spawning.
Next is the class array. The game classes and their abilities are defined here. Note that the battlesuit is not a class, it is only present in the array to force the model to load. When adding an alien class, make sure you modify one of the existing classes’ child lists so that it is possible to somehow evolve to your new class.
After that is the weapon array. Notice that there is a system for weapon slots, SLOT_. While currently all weapons use the main weapon slot, it is possible to create new sidearms.
The last array here is the upgrades array. Aliens have no upgrades.
If you plan on adding a new entry to any of these arrays, be sure to declare a new BA_, PCL_, WP_, UP_ constant in bg_public.h.
Warning: Near the bottom of this file is the eventnames array. This array contains the string names of all events. If you add an event, you must also add its name here or the game will crash when trying to print the debug name of your event!
bg_pmove.c
The code in this file is responsible for player pouncing (PM_CheckPounce), wall-jump (PM_CheckWallJump), jetpack flight (PM_JetPackMove), and walking/swimming. Entity animations are also started here.
Any events generated within bg_ files are called predictable events. These events can be predicted by the client without waiting for the server to generate them. Footstep events are generated in PM_Footsteps, weapon events in PM_Weapon.
bg_public.h
This file contains function prototypes, definitions, enumerations used in both virtual machines.
The first thing to do in this file is to give your mod its own name. Modify this line:
#define GAME_VERSION "base"
This file defines many kinds of flags. Here are some of their uses:
CS_constants control the meaning and order of the values that appear in the server configuration string periodically sent to the clients.PMF_bit flags control entity movement type.SCA_flags control what abilities a class has and are used in thebg_misc.cclass array.SS_flags control special game-specific entity states.PS_flags are used inplayerState_t.EF_flags are used inentityState_teFlagsfield.- Weapons can have up to three firing modes, defined in
weaponMode_t. - The game weapon ids are defined in
weapon_t. There must be a matching entry in thebg_misc.cweapons array. - Likewise upgrade (
upgrade_t) and buildable (buildable_t) ids are defined here. - Teams are defined three (!) times (
WUTeam_t,buildableTeam_t,pTeam_t). Note thatteam_tis the session team and is the only one not equivalent to the others. SLOT_define weapon and item slots.EV_events emitted by the server and received incg_events.care defined inentity_event_t.- The
MN_constants defined indynMenu_tdefine menu messages found incg_servercmds.c. - All possible segmented (humans; head, torso, legs) model animations are defined in
playerAnimNumber_t. - Non-segmented (aliens; single object) animations are defined in
nonSegPlayerAnimNumber_t. - Buildable animations are defined in
buildableAnimNumber_t. - Class ids are defined in
pClass_t. - Methods of death used in
cg_event.cnotifications are defined inmeansOfDeath_t. Warning: A newMOD_here must be accompanied by a new debug string array entry ing_combat.cor the game will crash! - Stages are defined in
stage_t. - The array types used in
bg_misc.care defined here (*Attributes_t). - The various
MASK_constants here are merely combinations of the entityCONTENTS_flags fromsurfaceflags.h. - Entity types are defined in
entityType_t.
You will notice there are some left-over code fragments from Quake 3 referring to quad-damage and red/blue flags. Ignore these, they are not used in Tremulous.
The B_ flags communicate buildable specific information to the client:
#define B_HEALTH_BITS 12 #define B_HEALTH_MASK ((1<<B_HEALTH_BITS)-1) #define B_MARKED_TOGGLEBIT 0x00001000 #define B_SPAWNED_TOGGLEBIT 0x00002000 #define B_POWERED_TOGGLEBIT 0x00004000 #define B_DCCED_TOGGLEBIT 0x00008000
These can have special uses as well. The Domination mod hijacks these bits and health to communicate domination point state.
bg_slidemove.c
Additional functions used in bg_pmove.c.
Client Game
This is how you view the game as a player; server sends you info about entity(players/buildables etc) locations and client sends them to cgame, cgame communicates with renderer to draw stuff (particles, trails, player models)
for example when someone buys jetpack, server tells this to client, client passes it to cgame, cgame passes to renderer
cg_animation.c
I went there ... boring and nothing
cg_animmapobj.c
animated map objects like models, doors, movers
anim.firstFrame = es->powerups; anim.numFrames = es->weapon; anim.reversed = qfalse; anim.flipflop = qfalse;''
interesting code
cg_attachment.c
cg_attachment.c – an abstract attachment system
if( CG_IsParticleSystemValid( ¢->jetPackPS ) )
{
CG_SetAttachmentTag( ¢->jetPackPS->attachment,
jetpack, jetpack.hModel, "tag_flash" );
CG_SetAttachmentCent( ¢->jetPackPS->attachment, cent );
CG_AttachToTag( ¢->jetPackPS->attachment );
}
?
fukafukafuka
cg_buildable.c
this defines how the clients see buildables: models particle systems(smoking bleeding etc) status display for builder
cg_consolecmds.c
cg_draw.c
draw function like text printing adding pics to hud etc
cg_drawtools.c
basic drawing functions CG_DrawPic: draw a 2d pic CG_DrawPlane: draw a pic in 3d space (can be used to draw wall marks)
cg_ents.c
cg_event.c
cg_local.h
cg_main.c
cg_marks.c
cg_mem.c
cg_particles.c
cg_players.c
cg_playerstate.c
cg_predict.c
cg_ptr.c
cg_public.h
this defines the functions imported from the main executable and the functions exported to the main executable this is used while building main executable The enum cgameImport_t should match the cg_syscalls.asm in case of building qvm for example if something in enum has value i it should have the calue i+1 in the cg_syscalls.asm
cg_scanner.c
cg_servercmds.c
cg_snapshot.c
cg_syscalls.c/.asm
This is how cgame interfaces with the client (ie the functions that are already available in the client) .c is for dynamic library .asm is for qvm be careful with these files
cg_trails.c
Trails ... ex: pulse rifle has red trails
cg_tutorial.c
Tremulous tutorial is hard coded in this file. It shows a good way to display text on certain conditions. (but no one would see it since experienced players tend to disable it)
cg_view.c
CG_DrawActiveFrame is the most important function in this file. It draws a game scene. So any function call in CG_DrawActiveFrame is called per frame. There are also model test functions( CG_TestGun_f CG_TestModel_f ) that maybe useful for creating new test function
cg_weapons.c
weapon models(flash barrel weapon)
User Interface
ui_atoms.c
ui_gameinfo.c
ui_local.h
ui_main.c
ui_players.c
ui_public.h
this defines the functions imported from the main executable and the functions exported to the main executable this is used while building main executable The enum uiImport_t should match the ui_syscalls.asm in case of building qvm for example if something in enum has value i it should have the calue i+1 in the ui_syscalls.asm
ui_shared.c
ui_shared.h
ui_syscalls.c/.asm
This is how ui interfaces with the client (ie the functions that are already available in the client) .c is for dynamic library .asm is for qvm be careful with these files
Authors
If you edit this page, please add your name and contribution here.
- This page was created by Risujin <risujin@risujin.org>, creator of the Balance and Domination mods.
- Kevlarman reminds Risujin to keep a closer eye on changelogs and version numbers.