The Quake-C Language

This is a very crude manual of Quake-C. It is rather incomplete.

Basic constructs of Quake-C

Comments

Those comments are the same as in C++ (and many C languages).

Names

Names of variable, fields, or functions have a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.

Definition of types

You cannot define new types from the existing ones. In particular, you cannot define new structure, new objects, and you cannot affect a new name to a type (as does typedef in C).

These restrictions make Quake-C compare unfavourably even to Basic, and sure it's about time the id software guys hired someone that already wrote a compiler.

Definition of variables

    type variable1, variable2;
where type is one of the pre-defined simple types.

You can also affect default values to variables, for instance:

    type variable1 = value;

Scoping of variables: There are two levels of scoping. By default all variables are global: they can be accessed by any functions, and they are shared by all the functions (and all the clients of a given network server, of course).

But inside the functions, using the keyword local just before the declaration of a variable, you can make this variable visible only the the function itself (i.e. it will be allocated on the stack).

Note that parameters of a functions are treated like local variables, they are only visible to the function, but they can be modified.

Definitions of constants

Any global variable that is initialised by setting a value to it is actually assumed to be a constant.

Since a constant is in fact represented by immediate values, you should NEVER attempt to modify a constant by giving it anothe value. Otherwise the program might not function correctly.

The constants are not saved to game files. Only regular variables are.

Definitions of functions

The general structure of a function definition is:

    type (type param1, typeparam2, ... ) function =
    {
       ... code ...
    };
Don't forget the ; after the brackets.

Here are some examples:

    void()		think = {...};
    entity()	FindTarget = {...};
    void(vector destination, float speed, void() callback)	SUB_CalcMove = {...};

Function declaration

If you want to use a function before defining it, you must declare it, otherwise the Quake-C compiler will not be able to use it.

The general structure of a function declaration is:

    type (type param1, typeparam2, ... ) function;

Definition of a frame function

Frame functions (also called States) are special functions made for convenience. They are meant to facilitate the definition of animation frames, by making them more readable.

Here is an example:

    void() framename = [$framenum, nextthink] { ...code...};
It is strictly equivalent to:
    void() framename =
    {
       self.frame= $framenum;  // the model frame to displayed
       self.nextthink = time + 0.1;   // next frame happens in 1/10 of second
       self.think = nextthink; // the function to call at the next frame
       ...code...
    };

Controling the flow of execution in Quake-C

Conditional construct

    if( expression )
    {
      statements
    }
    else
    {
      statements
    }

Loop construct

    while( expression )
    {
      statements
    }
or
    do
    { 
      statements
    }while( expression )

Function calls

Call a function:

    function_name ( parameter1, parameter2,... )
The cannot be more than 8 parameters.

Return a value:

    return( expression )

Logical operations

     !   // logical not
     &&  // logical and
     ||  // logical or

Take care that in if() conditional expressions containing two or more logical clauses, all the clauses will be evaluated before the condition test (like in Basic, and unlike C).

That means that if one part of your condition is not always valid or defined, you had better decompose your if() into two successive if(). It should also make it faster.

Comparisons

     <=    <      >=     >  
     ==  // equal, beware at the double = like in C.
     !=  // not equal, like in C.

Operations on floats or integer

     *  /  -  +
Use parenthesis to remove ambiguities.

Those operators perform bitwise operations on integers:

    &   // bitwise and
    |   // bitwise or
These operators treat floats like integers, so they are usually meant to be used with values made of bit masks.