Q3A Immutable Structs


Description of the immutable structs, the structs in q_shared.h that may not be changed by a game module, and some of its related constants.



/* paste source text here */


Table of Contents

  1. Template
  2. struct cplane_t
  3. struct trace_t
  4. SURF_* constants
  5. CONTENTS_* constants
  6. struct playerState_t
  7. PM_* constants
  8. PMF_* constants
  9. STAT_* stats elements
  10. HI_* holdable items
  11. PERS_* persistant elements
  12. PW_* powerups elements
  13. WP_* weapons
  14. struct usercmd_t
  15. struct trajectory_t
  16. enum trType_t
  17. struct entityState_t
  18. enum entityType_t
  19. EF_* constants
  20. struct entityShared_t
  21. SVF_* constants
  22. Table of Contents

struct cplane_t

This data type is included in trace_t, representing information about a collision against/into a surface (such as a wall). Presumably the detection code is hand-written in assembly for maximum speed. The prefixing "c" reflects the "C version" of this datatype, whereas the "assembly version" may not have a similar definition (perhaps offsets are all hand-coded?).

// plane_t structure
// !!! if this is changed, it must be changed in asm code too !!!
typedef struct cplane_s {
    vec3_t  normal;
    float   dist;
    byte    type;           // for fast side tests: 0,1,2 = axial, 3 = nonaxial
    byte    signbits;       // signx + (signy<<1) + (signz<<2), used as lookup during collision
    byte    pad[2];
} cplane_t;

The normal vector of the plane. One use is to calculate the bouncing vector (direction). Another is to calculate how "straight-on" a collision against a wall is. The spatial position of this vector is indicated by the endpos field of trace_t.
With the normal vector passing through the spatial origin (0, 0, 0), the distance of the plane from the origin along the normal vector. This is the d component of the general plane equation ax + by + cz = d (or is it ax + by + cz + d = 0?). Refer to mathematical textbooks on 3D geometry for further information about equations describing planes.
0 = plane('s normal vector) is axially aligned on X axis. 1 = plane('s normal vector) is axially aligned on Y axis. 2 = plane('s normal vector) is axially aligned on Z axis. 3 = not aligned with an axis. This only makes sense for quick "level/even surface" tests (like walls and floors of a square room).
Bitmask indicating the signs (positive/negative) of the normal vector elements. (XXX: what bit value means negative?)
padding space for word alignment purposes. With this padding space, the size of this struct is the same in a "packed" and "unpacked" form.

struct trace_t

This is the data type returned by trap_Trace(). The contained information assists in determining collisions.

// a trace is returned when a box is swept through the world
typedef struct {
    qboolean    allsolid;   // if true, plane is not valid
    qboolean    startsolid; // if true, the initial point was in a solid area
    float       fraction;   // time completed, 1.0 = didn't hit anything
    vec3_t      endpos;     // final position
    cplane_t    plane;      // surface normal at impact, transformed to world space 
    int         surfaceFlags;   // surface hit
    int         contents;   // contents on other side of surface hit
    int         entityNum;  // entity the contacted sirface is a part of
} trace_t;

If true, means both the start and end (and everything in between) of the trace reside within a solid region. This situation essentially means the trace turned up nothing useful (no collision, or "collision with self").
(If true, means the start of the trace resides in a solid region, but the end of the trace does not... or that there is a spot in between that isn't solid... not sure.
Indicates what fraction of the trace line was consumed to reach this collision. A value of 1.0 means the complete trace was consumed without turning up a collision. Values less than 1.0 indicate a collision at a point proportional along the line of trace, with values towards 0.0 meaning near the start, values towards 0.5 meaning near the middle of the trace, and values towards 1.0 meaning near the end of the trace.
The position of the collision point. The desired/estimated start and end position of the trace are passed to trap_Trace(); this field indicates the exact point of collision.
(not expanding on comments). See also cplane_t.
Bit flags of SURF_* constants.
Bit flags of CONTENTS_* constants.
Value ranges from 0 through MAX_GENTITIES-3 (1021) to indicate collision against a game entity. The value may also be ENTITYNUM_NONE (1023) to indicate collision against nothing, or ENTITYNUM_WORLD (1022) to indicate collision against something that doesn't belong to a game entity (such as a door)

SURF_* constants

These sets of values are bitmasks indicating a distinct game surface attribute. Trace collisions detected by trap_Trace() determine the surface attributes where the collision ends. The game module may respond to each distinct surface type. XXX: don't know about adding new SURF constants

#define SURF_NODAMAGE      0x1      // never give falling damage
#define SURF_SLICK         0x2      // effects game physics
#define SURF_SKY           0x4      // lighting from environment map
#define SURF_LADDER        0x8
#define SURF_NOIMPACT      0x10     // don't make missile explosions
#define SURF_NOMARKS       0x20     // don't leave missile marks
#define SURF_FLESH         0x40     // make flesh sounds and effects
#define SURF_NODRAW        0x80     // don't generate a drawsurface at all
#define SURF_HINT          0x100    // make a primary bsp splitter
#define SURF_SKIP          0x200    // completely ignore, allowing non-closed brushes
#define SURF_NOLIGHTMAP    0x400    // surface doesn't need a lightmap
#define SURF_POINTLIGHT    0x800    // generate lighting info at vertexes
#define SURF_METALSTEPS    0x1000   // clanking footsteps
#define SURF_NOSTEPS       0x2000   // no footstep sounds
#define SURF_NONSOLID      0x4000   // don't collide against curves with this set
#define SURF_LIGHTFILTER   0x8000   // act as a light filter during q3map -light
#define SURF_ALPHASHADOW   0x10000  // do per-pixel light shadow casting in q3map
#define SURF_NODLIGHT      0x20000  // don't dlight even if solid (solid lava, skies)
#define SURF_DUST          0x40000  // leave a dust trail when walking on this surface

CONTENTS_* constants

These constants indicate attributes for the "insides" or "volume" of a model (map, player, entity), such as a trigger. In contrast, the SURF_* constants describe the faces (surface) of a model. XXX: significance in bounding boxes?

#define CONTENTS_SOLID          1       // an eye is never valid in a solid
#define CONTENTS_LAVA           8
#define CONTENTS_SLIME          16
#define CONTENTS_WATER          32
#define CONTENTS_FOG            64

#define CONTENTS_AREAPORTAL     0x8000

#define CONTENTS_PLAYERCLIP     0x10000
#define CONTENTS_MONSTERCLIP    0x20000
//bot specific contents types
#define CONTENTS_TELEPORTER     0x40000
#define CONTENTS_JUMPPAD        0x80000
#define CONTENTS_DONOTENTER     0x200000
#define CONTENTS_BOTCLIP        0x400000
#define CONTENTS_MOVER          0x800000

#define CONTENTS_ORIGIN         0x1000000   // removed before bsping an entity

#define CONTENTS_BODY           0x2000000   // should never be on a brush, only in game
#define CONTENTS_CORPSE         0x4000000
#define CONTENTS_DETAIL         0x8000000   // brushes not used for the bsp
#define CONTENTS_STRUCTURAL     0x10000000  // brushes used for the bsp
#define CONTENTS_TRANSLUCENT    0x20000000  // don't consume surface fragments inside
#define CONTENTS_TRIGGER        0x40000000
#define CONTENTS_NODROP         0x80000000  // don't leave bodies or items (death fog, lava)

struct playerState_t

One copy of this data type resides on the client side for client purposes, and another copy resides on the server for the "true" data. This data type is transmitted over network to a player describing his/her/its state according to the server, that is, the player's "actual state". No other player receives the playerState_t of another player. The server constantly sends these playerState_t packets to their respective players. In a network multiplayer game, the nature of the network introduces delays (ping lag) in the packets. As a result, the client side may utilize movement prediction upon its local copy of the playerState_t information to present a smoother view to the gamer, while waiting for the "true" server's information to arrive. When the server's packet arrives, the client game then attempts to resolve the predicted playerState_t information with the received server's playerState_t information.

typedef struct playerState_s {
    int         commandTime;    // cmd->serverTime of last executed command
    int         pm_type;
    int         bobCycle;       // for view bobbing and footstep generation
    int         pm_flags;       // ducked, jump_held, etc
    int         pm_time;

    vec3_t      origin;
    vec3_t      velocity;
    int         weaponTime;
    int         gravity;
    int         speed;
    int         delta_angles[3];    // add to command angles to get view direction
                                    // changed by spawns, rotating objects, and teleporters

    int         groundEntityNum;// ENTITYNUM_NONE = in air

    int         legsTimer;      // don't change low priority animations until this runs out
    int         legsAnim;       // mask off ANIM_TOGGLEBIT

    int         torsoTimer;     // don't change low priority animations until this runs out
    int         torsoAnim;      // mask off ANIM_TOGGLEBIT

    int         movementDir;    // a number 0 to 7 that represents the reletive angle
                                // of movement to the view angle (axial and diagonals)
                                // when at rest, the value will remain unchanged
                                // used to twist the legs during strafing

    vec3_t      grapplePoint;   // location of grapple to pull towards if PMF_GRAPPLE_PULL

    int         eFlags;         // copied to entityState_t->eFlags

    int         eventSequence;  // pmove generated events
    int         events[MAX_PS_EVENTS];
    int         eventParms[MAX_PS_EVENTS];

    int         externalEvent;  // events set on player from another source
    int         externalEventParm;
    int         externalEventTime;

    int         clientNum;      // ranges from 0 to MAX_CLIENTS-1
    int         weapon;         // copied to entityState_t->weapon
    int         weaponstate;

    vec3_t      viewangles;     // for fixed views
    int         viewheight;

    // damage feedback
    int         damageEvent;    // when it changes, latch the other parms
    int         damageYaw;
    int         damagePitch;
    int         damageCount;

    int         stats[MAX_STATS];
    int         persistant[MAX_PERSISTANT]; // stats that aren't cleared on deat
    int         powerups[MAX_POWERUPS]; // level.time that the powerup runs out
    int         ammo[MAX_WEAPONS];

    int         generic1;
    int         loopSound;
    int         jumppad_ent;    // jumppad entity hit this frame

    // not communicated over the net at all
    int         ping;           // server to game info for scoreboard
    int         pmove_framecount;   // FIXME: don't transmit over the network
    int         jumppad_frame;
    int         entityEventSequence;
} playerState_t;

Server timestamp. Due to the nature of UDP/IP (network protocol used by Q3A), packets may arrive out of order. Timestamping assists in sorting out the packets. Also, it gives the client a very good idea of how much game time has passed. (XXX: what is the epoch? Server start? Game start? OS time?)
A predictable movement type. This helps the client predict what kind of motions would be allowed; on the server side, this dictates what kinds of motions are allowed. See also PM_*.
Used for timing footsteps sounds.
Bitmask flags for movement calculations (predictions on client-side). See also PMF_*.
An associated time value for movement calculations (predictions on client-side).
Vector describing the player's position in the game world.
Vector describing the player's instant velocity in the game world.
Number of milliseconds to pass before weaponstate may change. Reduced per game frame, weaponstate changes when weaponTime reaches 0. (XXX: mention the state-transitioning function)
Gravity effect upon the player. While the initial value is retrieved from cvar g_gravity, this field can be assigned a different value for some kind of "individual gravity force" effect. On the client side, this is used to predict gravity-induced acceleration.
Player's running speed. XXX: that was helpful...
If the server had to force a change in viewing angle for some reason (teleporter, respawning, etc.), this field indicates the amount of adjustment to the client's reported viewangle. This means, should the server not require adjusting the view angle, this field remains zeroed out as < 0, 0, 0 >.
Entity number of whatever the player is standing upon. ENTITY_NONE if not standing (airborne, swimming).
Time remaining in current leg animation frame.
Current leg animation frame number.
Time remaining in current torso animation frame.
Current torso animation frame number.
Something about rotating the legs relative to the face for the strafe motions. (PM_SetMovementDir())
Vector describing the position of the latched grappling hook pulling the player.
Entity flags. The EF_* constants.
Offset into events[MAX_PS_EVENTS] and eventParms[MAX_PS_EVENTS]... (XXX: next to be used, just used?)
Array of MAX_PS_EVENTS (2) elements to hold predictable events generated by the player (???).
Array of MAX_PS_EVENTS (2) elements to hold parameters to the events in events[MAX_PS_EVENTS].
Client number of the player. Ranges from 0 to MAX_CLIENTS (63).
Currently wielded weapon. Server uses this field to tell the client what weapon is actually in use. The client requests a change of weapon with the weapon field of a usercmd_t packet.
Incremented each time player takes damage. (XXX: seems silly to track this. Maybe more significance in cgame?)
Viewing direction (left/right component) from which the player got hit.
Viewing direction (up/down component) from which the player got hit.
Damage amount (hitpoints).
Array of MAX_STATS (16) elements of STAT_* fields. See also STAT_*.
Array of MAX_PERSISTANT (16) elemets of PERS_* fields. See also PERS_*.
Array of MAX_POWERUPS (16) elements of PW_* fields. See also PW_*.
Array of MAX_WEAPONS (16) elements of ammo counts. Each element corresponds to one ammo type: (undefined), gauntlet, bullets, shells, grenades, rockets, lightning, railslugs, cells, bfg. Each ammo type corresponds to one weapon type in baesq3. See also WP_*.
For Q3TA harvester game, number of thingies (cubes?) you're carrying?
Sound index into CS_SOUNDS configstring to play in a loop. XXX
ping value? Is this even sent over the network?

PM_* constants

Predictable movement types. Determines what types of movements are allowed and how to react to user movement input. Constants listed for context for playerState_t.pm_type.

typedef enum {
    PM_NORMAL,      // can accelerate and turn
    PM_NOCLIP,      // noclip movement
    PM_SPECTATOR,   // still run into walls
    PM_DEAD,        // no acceleration or turning, but free falling
    PM_FREEZE,      // stuck in place with no control
    PM_INTERMISSION,    // no movement or status bar
    PM_SPINTERMISSION   // no movement or status bar
} pmtype_t;

PMF_* constants

Predictable movement flags. Various bitmasks to indicate additional movement prediction parameters. Listed here for context for playerState_t.pm_flags.

// pmove->pm_flags
#define PMF_DUCKED          0x0001 //1
#define PMF_JUMP_HELD       0x0002 //2
//                            0x0004 //4
#define PMF_BACKWARDS_JUMP  0x0008 //8      // go into backwards land
#define PMF_BACKWARDS_RUN   0x0010 //16     // coast down to backwards run
#define PMF_TIME_LAND       0x0020 //32     // pm_time is time before rejump
#define PMF_TIME_KNOCKBACK  0x0040 //64     // pm_time is an air-accelerate only time
//                            0x0080 //128
#define PMF_TIME_WATERJUMP  0x0100 //256        // pm_time is waterjump
#define PMF_RESPAWNED       0x0200 //512        // clear after attack and jump buttons come up
#define PMF_USE_ITEM_HELD   0x0400 //1024
#define PMF_GRAPPLE_PULL    0x0800 //2048   // pull towards grapple location
#define PMF_FOLLOW          0x1000 //4096   // spectate following another player
#define PMF_SCOREBOARD      0x2000 //8192   // spectate as a scoreboard
#define PMF_INVULEXPAND     0x4000 //16384  // invulnerability sphere set to full size


STAT_* stats elements

Array of 16 elements. Each array element has a unique game module-defined meaning. Also, only the low 16 bits of each element is transmitted over network. (XXX: expanded to 32 bits since 1.31?)

Elements typically hold values the pertain to one particular life (i.e. until player is fragged). The game module zeroes out the entire stats[] array at each respawn (this action can be modified in the game module).

// player_state->stats[] indexes
// NOTE: may not have more than 16
typedef enum {
    STAT_WEAPONS,                   // 16 bit fields
    STAT_DEAD_YAW,                  // look this direction when dead (FIXME: get
 rid of?)
    STAT_CLIENTS_READY,             // bit mask of clients wishing to exit the i
ntermission (FIXME: configstring?)
    STAT_MAX_HEALTH                 // health / armor limit, changable by handic
} statIndex_t;

0 - the player's health value.
1 - the holdable item (if any) that the player possesses. See also HI_*.
2 - bitmask of weapons the player is carrying.
3 - player's armor value.
4 - um. this is kinda weird.
5 - Bitmask of clients that are "READY", at intermission. (XXX: obsoleted by a configstring?)
6 - Maximum health value.

HI_* holdable items

Values for holdable items for STAT_HOLDABLE_ITEM element of playerState_t.stats[MAX_STATS] field of playerState_t. Holdable items are items a player may carry and optionally use (baseq3 uses +button2 to indicate item use).

typedef enum {


} holdable_t;

0 - Dummy item, indicates no item.
1 - Personal teleporter; upon use, player is transported to a random spawn location.
2 - Medkit; upon use, player receives an instant health boost of 60, if at less than 100 health. The actual boost value is determined by the "count" field of the medkit's item description in bg_itemlist[].
3 - Kamikaze; upon use, the item creates a huge explosion (not a huge wind, despite the name), killing the carrier and surrounding players. If the player is fragged, the item automatically detonates of its own accord after 5 seconds, unless the player's body is gibbed.
4 - ???
5 - Invulnerability; upon use, an invulnerability sphere surrounds the player, protecting the player from all damages, while the player may continue shooting at everyone else, but unable to move in any direction at all. The invulnerabilty is limited by a timer in the PW_INVULNERABILITY field of playerState_t.powerups[MAX_POWERUPS].

PERS_* persistant elements

Array of 16 elements holding data that persists across deaths. Of particular note, baseq3 already uses 15 elements, leaving only one unused element for a mod. Still, the mod may change the purpose of any element except the first.

// player_state->persistant[] indexes
// these fields are the only part of player_state that isn't
// cleared on respawn
// NOTE: may not have more than 16
typedef enum {
    PERS_HITS,                      // total points damage inflicted so damage beeps can sound on change
    PERS_RANK,                      // player rank or team rank
    PERS_TEAM,                      // player team
    PERS_SPAWN_COUNT,               // incremented every respawn
    PERS_PLAYEREVENTS,              // 16 bits that can be flipped for events
    PERS_ATTACKER,                  // clientnum of last damage inflicter
    PERS_ATTACKEE_ARMOR,            // health/armor of last person we attacked
    PERS_KILLED,                    // count of the number of times you died
    // player awards tracking
    PERS_IMPRESSIVE_COUNT,          // two railgun hits in a row
    PERS_EXCELLENT_COUNT,           // two successive kills in a short amount of time
    PERS_DEFEND_COUNT,              // defend awards
    PERS_ASSIST_COUNT,              // assist awards
    PERS_GAUNTLET_FRAG_COUNT,       // kills with the guantlet
    PERS_CAPTURES                   // captures
} persEnum_t;

0 - Player score. The Q3 engine also expects the first element to be the player score, thus the game module should not try to change the meaning of this element. This field is transmitted in server queries, for the "score" fields of players.
5 XXX: what are the bits?

PW_* powerups elements

Values for powerup items for playerState_t.powerups[MAX_POWERUPS] field of playerState_t. Powerups are effective for a limited time, and may be dropped (such as due to fragging) with a partial timer value left.

// NOTE: may not have more than 16
typedef enum {





} powerup_t;

0 - Dummy powerup, indicating no powerup.
1 - Quad damage; player weapons do extra damage according to cvar g_quaddamage (default 3).
2 - Battle/Environment suit; protects player against splash and environment (lava, acid, drowning) damage.
3 - Haste; player moves and fires 30% faster. If also Scout, Scout takes precedence (i.e. no speeding to 80%).
4 - Invisibility; player appears almost invisible.
5 - Regeneration; player continually regains health.
6 - Flight; gravity does not affect player, who can in fact freely move up or down.
7 - The red flag; player is carrying the red flag.
8 - The blue flag; player is carrying the blue flag.
9 - The white flag; player is carrying the white flag (one-flag CTF)
10 - Scout (persistant powerup, Team Arena only); player moves and fires 50% faster. If player also has Haste, Scout takes precedence (i.e. no speeding to +80%).
11 - Guard (non-expiring powerup, Team Arena only); player receives half damage.
12 - Doubler (non-expiring powerup, Team Arena only); player weapons do double damage.
13 - Ammo Regen (non-expiring powerup, Team Arena only); player ammo counts slowly increment.
14 - Invulnerability (Team Arena only); expiration time for invulnerability sphere. Invulnerability is a holdable item; using the item sets this field as the invulnerability timer.

WP_* weapons

These values indicate a weapon. The same values are also used as the index into playerState_t.ammo[MAX_WEAPONS] for the weapon's corresponding ammo count.

typedef enum {


} weapon_t;

0 - Dummy weapon, used to indicate no weapon.
1 - Gauntlet.
2 - Machine gun.
3 - Shotgun.
4 - Grenade Launcher.
5 - Rocket Launcher.
6 - Lightning Gun.
7 - Railgun.
8 - Plasma Gun.
9 - BFG10000 (BFG10K).
10 - Grappling hook.
11 - Nail Gun (Team Arena only).
12 - Proximity Mine Launcher (Team Arena only).
13 - Chaingun (Team Arena only).

struct usercmd_t

If you can imagine trying to compress the gamer's input into a simplified arcade joystick interface, you would have a good idea what usercmd_t is about. The usercmd_t packets travel only from client to server, and is the means by which the server determines the will of the player's avatar in the server's notion of the world. The size of usercmd_t is notably small. This helps to reduce the impact of ping lag, and also helps reduces the total amount of incoming network traffic for the server (all connected clients are sending a usercmd_t).

The construction and transmission of the usercmd_t data occurs inside the client-side Q3 engine, meaning the cgame module cannot directly fabricate the data. The cgame module may still indirectly alter the usercmd_t data by using the various game commands (e.g. "+forward", "+attack", "-gesture"), via trap_SendConsoleCommand().

// usercmd_t is sent to the server each client frame
typedef struct usercmd_s {
    int             serverTime;
    int             angles[3];
    int             buttons;
    byte            weapon;           // weapon
    signed char forwardmove, rightmove, upmove;
} usercmd_t;

A timestamp. The nature of UDP/IP (the network protocol used by Q3) may wind up sending "later" packets sooner than "earlier" packets. Timestamping helps sort out this potential temporal mixup. The value written here by the client is based on the timestamp value the client last received in a playerState_t packet. To prevent "time-shifting" cheats, the server-side runs some primitive sanity checking on the timestamp (+/-500ms).
Network-transmitted: 32 bits.
The view (and thus aiming) direction of the client. Since this value is reported as an absolute (rather than relative change with a rate cap, as with running), a client may snap towards any (other) direction instantly.
Network-transmitted: 32*3 bits?
Bitmask of 16 bits reflectiong the BUTTON_* constants. These correspond to +buttonN commands. The lowest bit (bit 0) corresponds to "+button0" (alias "+attack"). With 16 bits, this relationship goes up to "+button15". A bit value of 1 indicates button is held (+button), and 0 indicates button is released (-button).
Network-transmitted: 16 bits.
Indicates the weapon the client wishes to wield. This is the method by which the client informs the server of a weapon switch. If the new weapon choice is invalid for some reason (not in possession, value out of range, player is dead), the server can force a switch to another weapon (on the server side) and report back this change in a playerState_t packet.
Network-transmitted: 8 bits.
??? Related to +forward and +back.
Network-transmitted: 8? bits.
??? Related to +moveleft and +moveright.
Network-transmitted: 8? bits.
??? Related to +moveup and +movedown.
Network-transmitted: 8? bits.

struct trajectory_t

This data type holds information related to recording the movement of an entity as well as calculating the near-future position (prediction) of the entity. A "trajectory model" is selected, and the parameters to the model recorded in the struct.

typedef struct {
    trType_t    trType;
    int     trTime;
    int     trDuration;         // if non 0, trTime + trDuration = stop time
    vec3_t  trBase;
    vec3_t  trDelta;            // velocity, etc
} trajectory_t;

Trajectory path model. See also trType_t
Network-transmitted: 8 bits.
Start time of this path model, in gametime milliseconds (ms). (tip: on server side, gametime milliseconds is stored in level.time)
Network-transmitted: 32 bits.
How much elapsed time to spend in this path model, in milliseconds. Stop time is derived by adding trTime and trDuration.
Network-transmitted: 32 bits.
Initial position at start time.
Network-transmitted: 32*3 bits.
Vector describing the next frame of movement.
Network-transmitted: 32*3 bits.

enum trType_t

Set of constants describing a trajectory model (predictable path). Most entities follow a movement pattern that is mostly predictable, until it collides with another entity. Even then, the effects of the collision tends to remain predictable (it explodes, it bounces, it stops, etc.). The server tells the client what movement pattern, or "trajectory model", an entity is using, so that the client can make educated predictions.

typedef enum {
    TR_INTERPOLATE,             // non-parametric, but interpolate between snapshots
    TR_SINE,                    // value = base + sin( time / duration ) * delta
} trType_t;

No movement. The entity does not move, client-side prediction does not change position.
Interpolated movement. Non-predictable, but client still figures out intermediate positions (interpolates) for smoother movement.
Linear movement, as with rockets, plasma gun, and BFG10K.
Linear movement with predictable stop time?
Sinusoidal movement (sine wave). Movement occurs along trDelta; scalar multiplication of vector trDelta with sine values.
Gravity-influenced movement, as with grenades. Acceleration force is always straight down, with magnitude DEFAULT_GRAVITY (800) (defined in bg_public.h).

struct entityState_t

All entities in the game has an associated entityState_t data. While the game may have up to MAX_GENTITIES (1024) of such data records, each client only receives the entityState_t information of entities within its PVS (Potential Visibility Set), as determined by the Q3 engine. Any client may receive the entityState_t information of any entity, including itself. This receiving is in contrast to playerState_t information, which is only sent to its respective client.

While the comments in the source say structure size does not matter, any changes to this struct in the game module source will have no effect unless the same changes are made in the Q3 engine source. As of the time of this writing, only a select few in the world have such access.

// entityState_t is the information conveyed from the server
// in an update message about entities that the client will
// need to render in some way
// Different eTypes may use the information in different ways
// The messages are delta compressed, so it doesn't really matter if
// the structure size is fairly large

typedef struct entityState_s {
    int     number;         // entity index
    int     eType;          // entityType_t
    int     eFlags;

    trajectory_t    pos;    // for calculating position
    trajectory_t    apos;   // for calculating angles

    int     time;
    int     time2;

    vec3_t  origin;
    vec3_t  origin2;

    vec3_t  angles;
    vec3_t  angles2;

    int     otherEntityNum; // shotgun sources, etc
    int     otherEntityNum2;

    int     groundEntityNum;    // -1 = in air

    int     constantLight;  // r + (g<<8) + (b<<16) + (intensity<<24)
    int     loopSound;      // constantly loop this sound

    int     modelindex;
    int     modelindex2;
    int     clientNum;      // 0 to (MAX_CLIENTS - 1), for players and corpses
    int     frame;

    int     solid;          // for client side prediction, trap_linkentity sets this properly

    int     event;          // impulse events -- muzzle flashes, footsteps, etc
    int     eventParm;

    // for players
    int     powerups;       // bit flags
    int     weapon;         // determines weapon and flash model, etc
    int     legsAnim;       // mask off ANIM_TOGGLEBIT
    int     torsoAnim;      // mask off ANIM_TOGGLEBIT

    int     generic1;
} entityState_t;

Entity number. Value ranges from 0 through MAX_GENTITIES-1 (1023).
Network-transmitted: 10? bits.
Entity type. See also entityType_t
Network-transmitted: ? bits.
Entity flags, the EF_* constants.
Network-transmitted: 19 bits.
Entity positional trajectory. Used to predict movement.
Network-transmitted: See trajectory_t bits.
Entity angular trajectory. Used to predict rotation.
Network-transmitted: See trajectory_t bits.
For score plums, the number (score) to display.
Network-transmitted: 32 bits.
Network-transmitted: 32 bits.
New calculated position? Current location?
Network-transmitted: 32*3 bits.
Used by jumppads (XXX: for what?). For railtrail and laser(!), location of the gun-side of the beam (where the shooter was). For movers, the push velocity (for pushing around players). For shotgun blasts, used to create the scattered shots effect (deriving normal vector of impact).
Network-transmitted: 32*3 bits.
Current orientation/angle/view direction.
Network-transmitted: 32*3 bits.
For players, the movement direction.
Network-transmitted: 32*3 bits.
For missile impacts, indicates the victim (XXX: what's it used for afterwards?). For railtrails, whomever fired (XXX: what about clientNum?) For grappling hook... indicates owner? For some hit/explosion entities, the client that owns/caused the event (XXX: ???). For obituary events/entities, entity number of the killer.
Network-transmitted: 10 bits.
For obituary events/entities, entity number of the the dead player. The killer is recorded in otherEntityNum.
Network-transmitted: 10 bits.
Entity number that this entity is standing on. ENTITY_NONE (1023) if airborne or swimming. ENITITY_WORLD (1022) if standing on a map component (floor).
Network-transmitted: 10 bits.
For movers, a constantLight color, RGBA components encoded into 4 8-bit fields mashed into a 32-bit int.
Network-transmitted: 32 bits.
Sound index into CS_SOUNDS configstring to play in a loop. Used by movers (grinding or motor noise), missiles (rocket sound, BFG noise, proxmine ticking), speaker entities (which is supposed to play sound in a loop), and players unfortunate enough to have a very attached proxmine.
Network-transmitted: 8 bits.
For items, item type code. Teleport-effect models, model index number. Model (misc_model) entities, model index number. Also used in single player to indicate the victory podium model at end of round.
Network-transmitted: 8 bits.
This field is a little whacky. For CTF flags, a non-zero value means a flag that was dropped (after fragging), whereas zero means the flag sitting at its flagstand. For items, non-zero value indicates an item dropped by a player (such as a hypothetical "drop" command), whereas zero means a world-spawned item (such as those placed by the mapper). For movers, specifies the model (XXX: by index into configstrings?) to draw/render, but clip brushes are still preserved (XXX: is modelindex used?). For obelisks (something to do with a Team Arena game mode, but wtf is it?), the obelisk's health value.
Network-transmitted: 8 bits.
Associated client number. XXX: and if not cliented?
Network-transmitted: 8 bits.
For portals, rotating speed (???). For obelisks, something about whether it's dying or something.
Network-transmitted: 16 bits.
Automagically set by Q3 engine upon a call to trap_LinkEntity(). Of special note: the special value SOLID_BMODEL (0xffffff) indicates a special inline model number (I have no idea what this means).
Network-transmitted: 24 bits.
For temporary-event entities, the event type code. XXX: describe/list events.
Network-transmitted: 10 bits.
For temporary-event entities, a parameter for the event (such as type of explosion or a sound index number).
Network-transmitted: 8 bits.
Bitmask of powerups?
Network-transmitted: 16 bits.
Associated weapon. For players, this is the weapon in hand. For obituaries, this is the weapon that inflicted death.
Network-transmitted: 8 bits.
Animation frame counter for legs. The high bit (ANIM_TOGGLEBIT) is toggled each time leg animation has changed, thus needs to be masked out (giving you 7 bits with which to play).
Network-transmitted: 8 bits.
Animation frame counter for torso. The high bit (ANIM_TOGGLEBIT) is toggled each time torso animation has changed, thus needs to be masked out (gives you 7 bits with which to play).
Network-transmitted: 8 bits.
For persistant powerups, bitmask flag for teams allowed to pick up this item. For proximity mines, something about not being triggered by teammates (same bitmasks as for persistant powerups?)? For players, in harvester mode, the number of thingies (cubes?) the player is carrying; while this is the same value as in playerState_t.generic1, a playerState_t is transmitted only to its associated client, and an entityState_t is transmitted to anyone else; this replication permits other players to see how many whatitcalleds any other player has harvested.
Network-transmitted: 8 bits.

enum entityType_t

Entity type code. By using such a code, the server assists the client to prepare for rendering. Also, the various fields of entityState_t may take on different meanings for each entity type, which allows for a very hackish form of inherited objects. Or a very complicated union.

These constants are actually defined in bg_public.h, and so the game module may redefine these constants without restriction. The values from baseq3 are presented here to provide a context to entityState_t.eType.

typedef enum {
    ET_GRAPPLE,             // grapple hooked on wall

    ET_EVENTS               // any of the EV_* events can be added freestanding
                            // by setting eType to ET_EVENTS + eventNum
                            // this avoids having to set eFlags and eventNum
} entityType_t;

EF_* constants

Entity Flags -- various bitmask flags for an entity. As with entityType_t, these constants are also defined in bg_public.h, and are as redefinable. Placed here for contextual reference to entityState_t.eFlags.

#define EF_DEAD             0x00000001      // don't draw a foe marker over players with EF_DEAD
#define EF_TICKING          0x00000002      // used to make players play the prox mine ticking sound
#define EF_TELEPORT_BIT     0x00000004      // toggled every time the origin abruptly changes
#define EF_AWARD_EXCELLENT  0x00000008      // draw an excellent sprite
#define EF_BOUNCE           0x00000010      // for missiles
#define EF_BOUNCE_HALF      0x00000020      // for missiles
#define EF_AWARD_GAUNTLET   0x00000040      // draw a gauntlet sprite
#define EF_NODRAW           0x00000080      // may have an event, but no model (unspawned items)
#define EF_FIRING           0x00000100      // for lightning gun
#define EF_KAMIKAZE         0x00000200
#define EF_MOVER_STOP       0x00000400      // will push otherwise
#define EF_AWARD_CAP        0x00000800      // draw the capture sprite
#define EF_TALK             0x00001000      // draw a talk balloon
#define EF_CONNECTION       0x00002000      // draw a connection trouble sprite
#define EF_VOTED            0x00004000      // already cast a vote
#define EF_AWARD_IMPRESSIVE 0x00008000      // draw an impressive sprite
#define EF_AWARD_DEFEND     0x00010000      // draw a defend sprite
#define EF_AWARD_ASSIST     0x00020000      // draw a assist sprite
#define EF_AWARD_DENIED     0x00040000      // denied
#define EF_TEAMVOTED        0x00080000      // already cast a team vote

struct entityShared_t

The entityShared_t struct is not transmitted over network. Still, it is memory space shared by the Q3 engine and game module for certain non-network activity that both the engine and the game module need simultaneous access. One such example is collision detection with trap_Trace(). While the trap's code/contents/meat resides in the Q3 engine, information such as location and sizes of entities need to be available for reading and writing to both the Q3 engine (to detect collisions) and the game module (to move entities around). The entityShared_t struct fills this role of shared memory, while not being network-active.

Though the struct exists in VM memory, the Q3 engine has free reign of reading and writing these fields. Put another way, the values of these fields may at times appear to change "magically". A suitable analogy is I/O ports in systems programming.

typedef struct {
    entityState_t   s;              // communicated by server to clients

    qboolean    linked;             // qfalse if not in any good cluster
    int         linkcount;

    int         svFlags;            // SVF_NOCLIENT, SVF_BROADCAST, etc
    int         singleClient;       // only send to this client when SVF_SINGLECLIENT is set

    qboolean    bmodel;             // if false, assume an explicit mins / maxs bounding box
                                    // only set by trap_SetBrushModel
    vec3_t      mins, maxs;
    int         contents;           // CONTENTS_TRIGGER, CONTENTS_SOLID, CONTENTS_BODY, etc
                                    // a non-solid entity should set to 0

    vec3_t      absmin, absmax;     // derived from mins/maxs and origin + rotation

    // currentOrigin will be used for all collision detection and world linking.
    // it will not necessarily be the same as the trajectory evaluation for the current
    // time, because each entity must be moved one at a time after time is advanced
    // to avoid simultanious collision issues
    vec3_t      currentOrigin;
    vec3_t      currentAngles;

    // when a trace call is made and passEntityNum != ENTITYNUM_NONE,
    // an ent will be excluded from testing if:
    // ent->s.number == passEntityNum   (don't interact with self)
    // ent->s.ownerNum = passEntityNum  (don't interact with your own missiles)
    // entity[ent->s.ownerNum].ownerNum = passEntityNum (don't interact with other missiles from owner)
    int         ownerNum;
} entityShared_t;

Copy of entityState_t data?
true or false, depending on whether entity is linked into the world or not (trap_LinkEntity()/trap_UnlinkEntity()).
Bitmask flags of special note to the Q3 engine server. The Q3 engine does not (and should not!) know the purpose of the other structs used by the game module. This field allows for the game module to specify special server/network actions on this entity. See also SVF_*.
If svFlags has the SVF_SINGLECLIENT bit set, this field indicates the sole recipient of update information for this entity.
And if true, means the entity is part of the map (BSP Model).
One corner of the "regular" bounding box.
The other corner of the "regular" bounding box.
Bitmask flags of CONTENTS_* constants.
Adjusted bounding box to compensate for box rotations.
Adjusted bounding box to compensate for box rotations.
The position used by trap_Trace() to calculate collisions. Trajectory calculations are still based on entityState_t.pos.
The view/aim direction used by traps. Trajectory still based on entityState_t.apos.
Owner number for this entity.

SVF_* constants

The PVS (Potential Visibility Set) of a location can be thought of as the set of entityState_t updates to properly predict events and entities within view from that location. The server flags fiddle with the set of entityState_t update information.

/ entity->svFlags
// the server does not know how to interpret most of the values
// in entityStates (level eType), so the game must explicitly flag
// special server behaviors
#define SVF_NOCLIENT            0x00000001  // don't send entity to clients, even if it has effects
#define SVF_BOT                 0x00000008  // set if the entity is a bot
#define SVF_BROADCAST           0x00000020  // send to all connected clients
#define SVF_PORTAL              0x00000040  // merge a second pvs at origin2 into snapshots
#define SVF_USE_CURRENT_ORIGIN  0x00000080  // entity->r.currentOrigin instead of entity->s.origin
                                            // for link position (missiles and movers)
#define SVF_SINGLECLIENT        0x00000100  // only send to a single client

The entity update information is not sent to anyone (entityState_t content remains network-inactive).
Marks this entity as a bot AI.
Send entity update information to all clients; insert into PVS of all clients.
Takes the PVS calculated from entityState_t.origin2 and send that PVS information to this client, along with the original PVS. (I think.) In other words, the client can also see what the portal is seeing (remote camera effect).
Normally the PVS is calculated from entityState_t.origin, but this flag changes the PVS calculation to use entityShared_t.currentOrigin instead.
Send this entity's update information to only one client, removing from the PVS of all other clients. The sole recipient of such information is indicated by entityShared_t.singleClient.

TODO: table of structs, their fields, and modability.

Created 2002.09.14.
Updated 2002.09.20 - plane information (djbob).
Updated 2003.11.10 - massive inject from cyrri.
Updated 2004.07.24 - spelling corrections, fixed syntax errors, grammar adjustments, more cross-reference links, added TOC.

PhaethonH < phaethon@linux.ucla.edu >