Hello, QWorld

„Booyakasha !“. Ok, now it’s a pre-requisite that you’re able to compile the qagamex86.dll – if you haven’t managed that, then have a look at the previous tutorials.

In this tutorial we’re not actually going to print „Hello, qworld!“ on the console (Boring!), we’re going to modify the speed of rockets (as suggested in the id readme file). We’re also going to learn a thing or two about rockets along the way. Now let’s get into it.


It’s good to always keep a pristine copy of the original codebase. Imagine if you fuck up one of your source files (delete crucial lines, whatever), you’ll need a backup right ? Rather than re-install Q3aGameSource.exe every time, let’s keep quake3\source as our ‚pristine‘ codebase. NEVER MAKE MODS in quake3\source !! We’ll make mods in individual mod directories… let’s start by creating quake3\mymod.

Ok then, we simply copy quake3\source to quake3\mymod. Double click on quake3\mymod\q3agame.dsw – from now on, follow all the tutorials using this codebase (I made a shortcut to this .dsw file on my desktop). If you modified the „Output file name“ setting correctly in the first tutorial, the .dll for mymod should compile to the quake3\mymod directory – compile the ‚game‘ project and check this.

Whenever we’ve finished messing around with a tutorial and want to refresh the codebase back to the original, simply copy quake3\source to quake3\mymod. You can have as many mod directories as you want… I often have more than one mod in progress at any one time… quake3\rail, quake3\cts, etc… your hard drive’s the limit!


Let’s load up the quake3\mymod\q3agame.dsw project in MSVC. Maximize MSVC – you’ll need all the real estate your desktop can give you. Make sure ‚game‘ is the active project. Select „File View“ on the left hand pane, and find the source file ‚g_missile.c‘ in the tree. Double click on ‚g_missile.c‘ – the source file should open up in the editor window.

Go to line 362 (hit Ctrl+G for an easy shortcut) and find the fire_rocket function :

fire_rocket blah
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir)
    gentity_t       *bolt;

    VectorNormalize (dir);

    bolt = G_Spawn();
    bolt->classname = "rocket";
    bolt->nextthink = level.time + 10000;
    bolt->think = G_ExplodeMissile;
    bolt->s.eType = ET_MISSILE;
    bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
    bolt->s.weapon = WP_ROCKET_LAUNCHER;
    bolt->r.ownerNum = self->s.number;
    bolt->parent = self;
    bolt->damage = 100;
    bolt->splashDamage = 100;
    bolt->splashRadius = 120;
    bolt->methodOfDeath = MOD_ROCKET;
    bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
    bolt->clipmask = MASK_SHOT;

    bolt->s.pos.trType = TR_LINEAR;
    bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME;   // move a bit
on the very first frame
    VectorCopy( start, bolt->s.pos.trBase );
    VectorScale( dir, 900, bolt->s.pos.trDelta );
    SnapVector( bolt->s.pos.trDelta );                       // save net bandwidth
    VectorCopy (start, bolt->r.currentOrigin);

    return bolt;

If you like, go and have a read thru our first article on quake entities

Back already ? Great ! Line 372 is creates a new entity (called bolt). The G_Spawn() function creates a ‚blank‘ entity… then next job is to flesh out all the details (what sort of entity is it ? what are the characteristics ? etc). The next 20 or so lines of code define all this stuff.

Line 373-375 define the bolt to be a „rocket“, and it will ‚think‘ again in 10 seconds (time is measured in 1000’ths of a second in the quake world, thus 10000 equates to 1 second). When the rocket ‚thinks‘ it will call the function G_ExplodeMissile. In other words, if it hasn’t touched anything already, our rocket will explode after 10 seconds. This prevents our rockets flying off into outer space forever.

Neat, we’ve discovered something about the game from looking thru the code! Let’s see what else we can figure out about rockets…

We can see that the rocket deals 100 damage (direct OR splash), and that the splash damage radius is 120 units. Line 391 tells us that the rocket moves at a speed of 900 units/second. There’s also a whole load of constants used in this function (constants are usually in CAPS)… we can guess what most of them mean. ‚ET_MISSILE‘ for example means ‚Entitry Type: Missile‘ (as opposed to an item or a player).


Let’s modify line 391 so that it looks like this :

    VectorScale( dir, 300, bolt->s.pos.trDelta );

Hit F7 to compile our .dll. Fire up quake (Run „quake3\quake3.exe +set fs_game mymod +map q3dm1“) and see if it worked – you rockets should be noticeably slower.

Done! That’s our first tutorial. Let’s keep blazing onwards…

by SumFuka