2. The Quake-C Basic Types

2.1 The simple Types

2.1.1 Void type

An empty result, mostly used for definition of procedures (i.e. functions that return no result at all).

2.1.2 Float type

A floating point value.

Floats are also used to store booleans (TRUE, FALSE) or integer values linke counters, or bit flags.

    Valid syntax: 12  1.6   0.5   -100  
    Invalid syntax: .5

A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error. Separate the - from the digits with a space "a - 5" to get the proper behavior.

2.1.3 Vector type

A vector, made of 3 float coordinates.
Used to represent positions or directions in 3D space.
Valid syntax: '0 0 0' or '20.5 -10 0.00001'

Note the simple quotes around the vector. Do not use double quotes, they are reserved for strings.

If you declare a vector foobar, then you can access it's x, y and z fields with: foobar_x, foobar_y,foobar_z.

2.1.4 String type

This is used to store character string.
Used to indicate file names, or messages to be broadcast to players.
Valid syntax: "maps/jrwiz1.bsp" or "ouch!\n"
Use \n for newline.

Note: that character strings cannot be modified, or concatenated. Because they are stored at fixed locations in memory, and if would be postentially troublesome to allow modification.

2.1.5 entity type

The reference of an entity in the game, like things, players, monsters.
For instance, this is the type of the entities self and other.

The entity type is a structured type, made of fields.
A description of each field is available.

2.2 The field types

2.2.1 What's a field?

Countrary to the other types, the entity type is a reference to an instance of a structured object, that contains many informations of totally different kinds.

To access all these informations conveniently, they are stored as fields of the entity object, and each field is given a name and a type, that makes it distinct of the others.

Some of the fields do not store value, but instead they store the function to be executed in certain conditions. They are called the methods that can be aplied to the object.

If Quake-C was an object oriented programming language, those method functions and would be distinguished from the other fields. And, above all, you would be able to create new object types, with their own fields.

As Quake-C stands currently, all the field definitions are definitions of entity fields. So anywhere in your code you could add definition of new fields, and the compiler would interpret them as an extension of the entity definition.

2.2.2 Creating new fields

The only way to extend the entity type is to add some fields at the end of the structures.

This is done via a field definitions, whose general structure is:

   .type field_name;

For instance, if you wanted to add a sling to the game, and needed to store the count of pellets for every player, you would add the following line in the source code:

   .float ammo_sling;
That will add a fields ammo_sling to every entity in the game, and in particular to the player entities.

Here are all the possible definitions of entity fields, with their types:

    .float field_name;
    .string field_name;
    .vector field_name;
    .entity field_name;

The strange bit is that you can add those type definitions almost anywhere in the source code. They are not supposed to be grouped in a single place, where the entity type would be defined.

2.2.3 Allowed modifications of types

In the first file read by the Quake-C compiler, defs.qc, there must be a definition for the entity fields, and world fields. This definition is hard coded. You had better not touch it, or you will have to recompile Quake itself.

The globals are defined before the special definition void end_sys_globals;
The entity fields are defined before the special definition void end_sys_fields;

It's not important if you don't understand the nonsense above. It's an ugly hack. Just don't modify defs.qc before those two tags, and you won't be in trouble.