3. Quake-C Model definitions

(Derived from information published by Steve Tietze)

The Quake-C code files are used to define entity behavior, but they are also used to define the animation of models (.MDL files) used for monsters, players, and some objects.

The model informations are stored on special lines of code that all begin with a $. They cannot be placed inside a function definition. Some of this information is not even interpreted by the Quake-C compiler, but it's useful for the program modelgen that generates the models.

Model name

$modelname name
name is the name of the model file defining the object. For instance:
$name armor

directory

$cd dir
Specify the directory where your model file (.MDL) is located. For instance:
$cd  /evil/models/armor.

Special animation flags

$flags  flag_value
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
Rotation of the object.

Possible values for the flag:

Origin

$origin x y z
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
Location of the object within the bounding box, in the quake editor.
ex: $origin 0 0 8

Scale factor

$scale number
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
number comes from the texmake number that is generated.
You can use different values if you want.
ex: $scale 4

Base

$base  object
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
object is the name of a model file, that will be used as a kind of starting position, for animation.

Skin file

$skin  skinfile
This field is not interpreted by Quake-C, but it's useful for the program modelgen that generates the models.
skinfile is the name (without extension) of the .lbm file that defines the skin of the object, as generated by the program texmake.

Frame definitions

$frame  frame1 frame2 ...
This defines several animation frames of the object.
For every animation frame defined, you must also define a Quake-C nextthink).

Most of these functions do nothing special, but some can be very complex (for instance, the functions that are called when the monster tries to see a player).


4. Using Quake-C

4.1 Compilation of Quake-C

Compiling the source files

In order to use a Quake-C program, you must compile it into a file named PROGS.DAT. This is done by using the tool named qcc in the directory where all the Quake-C sources are. qcc is the Quake-C Compiler made by John Carmack of id software, it can be found on their ftp site, or on any mirror.

You must declare all the .QC source files in the file named PROGS.SRC. Note that all the .QC files will be compiled at the same time, and they be read in the same order as they are declared in PROGS.SRC.

Countrary to most language compilers, qcc behaves just as if all the .QC files were concatenated into a single big file. If you use an identifier (a name) that is already used somewhere in another .QC file, that will cause a conflict and compilation will fail.

So the best is to place your function declarations at the end of the first file, defs.h (so that they can be seen in all the code) but place your new .QC files (with function definitions) at the end of the list, so as to be sure that if a conflict happen, it will happen in your own files.

Note that qcc is not very user friendly, and does limited checks on the code. So you might wish to look for a better tool to compile your .QC code.

Note from John Carmack:
Error recovery during compilation is minimal. It will skip to the next global definition, so you will never see more than one error at a time in a given function. All compilation aborts after ten error messages.

Using the compiled PROGS.DAT

To use a custom PROGS.DAT that you just compiled, you only need to put it at the right place amoung the Quake game directory, and then Quake will find it automatically at startup.

The default PROGS.DAT can be found in the main pack file, pak0.pak in the directory id1. You could store your custom PROGS.DAT into that same directory id1.

Preferably, put PROGS.DAT in a special directory created for your own modified game, and that you will indicate to Quake with the option -game.

Beware of the Quake-C compiler

Here are some remarks by Adnan Zafar (zafar@hal-pc.org)

The compiler only catches syntax and other language-style errors. It will not warn you of things that generate run-time errors.. and definitely doesn't guarantee that things will work the way you want. It's been my experience that I have to compile and test something 6 or 8 times; the first few times it doesn't work at all, and the last few it doesn't work exactly right. [...] I just don't want you to think that all the code that compiles will have a good chance of working. In all likelihood, it won't.


4.1 Running Quake-C code

Here are some more remarks from John Carmack:
Code execution is initiated by C code in quake from two main places: the timed think routines for periodic control, and the touch function when two objects impact each other.

Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.

There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.

It is acceptable to change the system set global variables. This is usually done to pose as another entity by changing self and calling a function.

The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code. All time consuming operations should be made into built in functions.

A profile counter is kept for each function, and incremented for each interpreted instruction inside that function. The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters. The "profile all" command will dump sorted stats for every function that has been executed.