Description of gentity_t and gclient_t, the game module structs for game entities and game clients.
blurb
/* paste source text here */
This struct describes the properties of an "entity" in the game module. An entity may also be known as a "game object" in other contexts.
The Q3 engine knows nothing about the contents of a gentity_t, though it knows how large the struct is, via trap_LocateGameData(). The fields are specific to the game module, and are utilized solely by the code in the game module. The game module may still copy values into the members that the Q3 engine recognizes.
The trap trap_LocateGameData notifies the Q3 engine of the location of the array of game entities. The Q3 engine requires the beginning of each game entity struct to be a specific form, but the rest is left to the game module.
typedef struct gentity_s gentity_t;
struct gentity_s {
    entityState_t   s;              // communicated by server to clients
    entityShared_t  r;              // shared by both the server system and game
    // DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER
    // EXPECTS THE FIELDS IN THAT ORDER!
    //================================
    struct gclient_s    *client;            // NULL if not a client
    qboolean    inuse;
    char        *classname;         // set in QuakeEd
    int         spawnflags;         // set in QuakeEd
    qboolean    neverFree;          // if true, FreeEntity will only unlink
                                    // bodyque uses this
    int         flags;              // FL_* variables
    char        *model;
    char        *model2;
    int         freetime;           // level.time when the object was freed
    int         eventTime;          // events will be cleared EVENT_VALID_MSEC after set
    qboolean    freeAfterEvent;
    qboolean    unlinkAfterEvent;
    qboolean    physicsObject;      // if true, it can be pushed by movers and fall off edges
                                    // all game items are physicsObjects,
    float       physicsBounce;      // 1.0 = continuous bounce, 0.0 = no bounce
    int         clipmask;           // brushes with this content value will be collided against
                                    // when moving.  items and corpses do not collide against
                                    // players, for instance
    // movers
    moverState_t moverState;
    int         soundPos1;
    int         sound1to2;
    int         sound2to1;
    int         soundPos2;
    int         soundLoop;
    gentity_t   *parent;
    gentity_t   *nextTrain;
    gentity_t   *prevTrain;
    vec3_t      pos1, pos2;
    char        *message;
    int         timestamp;      // body queue sinking, etc
    float       angle;          // set in editor, -1 = up, -2 = down
    char        *target;
    char        *targetname;
    char        *team;
    char        *targetShaderName;
    char        *targetShaderNewName;
    gentity_t   *target_ent;
    float       speed;
    vec3_t      movedir;
    int         nextthink;
    void        (*think)(gentity_t *self);
    void        (*reached)(gentity_t *self);    // movers call this when hitting endpoint
    void        (*blocked)(gentity_t *self, gentity_t *other);
    void        (*touch)(gentity_t *self, gentity_t *other, trace_t *trace);
    void        (*use)(gentity_t *self, gentity_t *other, gentity_t *activator);
    void        (*pain)(gentity_t *self, gentity_t *attacker, int damage);
    void        (*die)(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
    int         pain_debounce_time;
    int         fly_sound_debounce_time;    // wind tunnel
    int         last_move_time;
    int         health;
    qboolean    takedamage;
    int         damage;
    int         splashDamage;   // quad will increase this without increasing radius
    int         splashRadius;
    int         methodOfDeath;
    int         splashMethodOfDeath;
    int         count;
    gentity_t   *chain;
    gentity_t   *enemy;
    gentity_t   *activator;
    gentity_t   *teamchain;     // next entity in team
    gentity_t   *teammaster;    // master of the team
#ifdef MISSIONPACK
    int         kamikazeTime;
    int         kamikazeShockTime;
#endif
    int         watertype;
    int         waterlevel;
    int         noise_index;
    // timing variables
    float       wait;
    float       random;
    gitem_t     *item;          // for bonus items
};
This struct holds data particular to each client. A client is a (usually human) player, requiring a "feedback" mechanism (remote control).
typedef struct gclient_s gclient_t;
struct gclient_s {
    // ps MUST be the first element, because the server expects it
    playerState_t   ps;             // communicated by server to clients
    // the rest of the structure is private to game
    clientPersistant_t  pers;
    clientSession_t     sess;
    qboolean    readyToExit;        // wishes to leave the intermission
    qboolean    noclip;
    int         lastCmdTime;        // level.time of last usercmd_t, for EF_CONNECTION
                                    // we can't just use pers.lastCommand.time, because
                                    // of the g_sycronousclients case
    int         buttons;
    int         oldbuttons;
    int         latched_buttons;
    vec3_t      oldOrigin;
    // sum up damage over an entire frame, so
    // shotgun blasts give a single big kick
    int         damage_armor;       // damage absorbed by armor
    int         damage_blood;       // damage taken out of health
    int         damage_knockback;   // impact damage
    vec3_t      damage_from;        // origin for vector calculation
    qboolean    damage_fromWorld;   // if true, don't use the damage_from vector
    int         accurateCount;      // for "impressive" reward sound
    int         accuracy_shots;     // total number of shots
    int         accuracy_hits;      // total number of hits
    //
    int         lastkilled_client;  // last client that this client killed
    int         lasthurt_client;    // last client that damaged this client
    int         lasthurt_mod;       // type of damage the client did
    // timers
    int         respawnTime;        // can respawn when time > this, force after g_forcerespwan
    int         inactivityTime;     // kick players when time > this
    qboolean    inactivityWarning;  // qtrue if the five seoond warning has been given
    int         rewardTime;         // clear the EF_AWARD_IMPRESSIVE, etc when time > this
    int         airOutTime;
    int         lastKillTime;       // for multiple kill rewards
    qboolean    fireHeld;           // used for hook
    gentity_t   *hook;              // grapple hook if out
    int         switchTeamTime;     // time the player switched teams
    // timeResidual is used to handle events that happen every second
    // like health / armor countdowns and regeneration
    int         timeResidual;
#ifdef MISSIONPACK
    gentity_t   *persistantPowerup;
    int         portalID;
    int         ammoTimes[WP_NUM_WEAPONS];
    int         invulnerabilityTime;
#endif
    char        *areabits;
};
// client data that stays across multiple respawns, but is cleared
// on each level change or team change at ClientBegin()
typedef struct {
    clientConnected_t   connected;
    usercmd_t   cmd;                // we would lose angles if not persistant
    qboolean    localClient;        // true if "ip" info key is "localhost"
    qboolean    initialSpawn;       // the first spawn should be at a cool locat
ion
    qboolean    predictItemPickup;  // based on cg_predictItems userinfo
    qboolean    pmoveFixed;         //
    char        netname[MAX_NETNAME];
    int         maxHealth;          // for handicapping
    int         enterTime;          // level.time the client entered the game
    playerTeamState_t teamState;    // status in teamplay games
    int         voteCount;          // to prevent people from constantly calling
 votes
    int         teamVoteCount;      // to prevent people from constantly calling
 votes
    qboolean    teamInfo;           // send team overlay updates?
} clientPersistant_t;
A "session" for a client is the span of time and activity between the client's connect and the client's disconnect. A reconnect creates a new session (disconnect + connect). A session can span across multiple level (map) changes (connect, play, change map, play, change map, play, disconnect). Since the Q3VM and all memory within a .qvm are reset on map changes, the data in a clientSession_t (which is in the VM memory space) must be stored outside the VM to survive level changes. The most common form is cvars, although files are also feasible.
// client data that stays across multiple levels or tournament restarts
// this is achieved by writing all the data to cvar strings at game shutdown
// time and reading them back at connection time.  Anything added here
// MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData()
typedef struct {
    team_t      sessionTeam;
    int         spectatorTime;      // for determining next-in-line to play
    spectatorState_t    spectatorState;
    int         spectatorClient;    // for chasecam and follow mode
    int         wins, losses;       // tournament stats
    qboolean    teamLeader;         // true when this client is a team leader
} clientSession_t;
A player's team-related status in a team game.
typedef struct {
    playerTeamStateState_t  state;
    int         location;
    int         captures;
    int         basedefense;
    int         carrierdefense;
    int         flagrecovery;
    int         fragcarrier;
    int         assists;
    float       lasthurtcarrier;
    float       lastreturnedflag;
    float       flagsince;
    float       lastfraggedcarrier;
} playerTeamState_t;
Constants describing the connection state of a client in clientPersistant_t.connected.
typedef enum {
    CON_DISCONNECTED,
    CON_CONNECTING,
    CON_CONNECTED
} clientConnected_t;
For playerTeamState_t. These values indicate the player's relation to a team at (re)spawn time.
typedef enum {
    TEAM_BEGIN,     // Beginning a team game, spawn at base
    TEAM_ACTIVE     // Now actively playing
} playerTeamStateState_t;
Style of spectating for a spectator, clientSession_t.spectatorState. The field clientSession_t.spectatorClient may be used, depending on the particular handling of a spectator state.
typedef enum {
    SPECTATOR_NOT,
    SPECTATOR_FREE,
    SPECTATOR_FOLLOW,
    SPECTATOR_SCOREBOARD
} spectatorState_t;
Various level-wide variables.
typedef struct {
    struct gclient_s    *clients;       // [maxclients]
    struct gentity_s    *gentities;
    int         gentitySize;
    int         num_entities;       // current number, <= MAX_GENTITIES
    int         warmupTime;         // restart match at this time
    fileHandle_t    logFile;
    // store latched cvars here that we want to get at often
    int         maxclients;
    int         framenum;
    int         time;                   // in msec
    int         previousTime;           // so movers can back up when blocked
    int         startTime;              // level.time the map was started
    int         teamScores[TEAM_NUM_TEAMS];
    int         lastTeamLocationTime;       // last time of client team location update
    qboolean    newSession;             // don't use any old session data, because
                                        // we changed gametype
    qboolean    restarted;              // waiting for a map_restart to fire
    int         numConnectedClients;
    int         numNonSpectatorClients; // includes connecting clients
    int         numPlayingClients;      // connected, non-spectators
    int         sortedClients[MAX_CLIENTS];     // sorted by score
    int         follow1, follow2;       // clientNums for auto-follow spectators
    int         snd_fry;                // sound index for standing in lava
    int         warmupModificationCount;    // for detecting if g_warmup is changed
    // voting state
    char        voteString[MAX_STRING_CHARS];
    char        voteDisplayString[MAX_STRING_CHARS];
    int         voteTime;               // level.time vote was called
    int         voteExecuteTime;        // time the vote is executed
    int         voteYes;
    int         voteNo;
    int         numVotingClients;       // set by CalculateRanks
    // team voting state
    char        teamVoteString[2][MAX_STRING_CHARS];
    int         teamVoteTime[2];        // level.time vote was called
    int         teamVoteYes[2];
    int         teamVoteNo[2];
    int         numteamVotingClients[2];// set by CalculateRanks
    // spawn variables
    qboolean    spawning;               // the G_Spawn*() functions are valid
    int         numSpawnVars;
    char        *spawnVars[MAX_SPAWN_VARS][2];  // key / value pairs
    int         numSpawnVarChars;
    char        spawnVarChars[MAX_SPAWN_VARS_CHARS];
    // intermission state
    int         intermissionQueued;     // intermission was qualified, but
                                        // wait INTERMISSION_DELAY_TIME before
                                        // actually going there so the last
                                        // frag can be watched.  Disable future
                                        // kills during this delay
    int         intermissiontime;       // time the intermission was started
    char        *changemap;
    qboolean    readyToExit;            // at least one client wants to exit
    int         exitTime;
    vec3_t      intermission_origin;    // also used for spectator spawns
    vec3_t      intermission_angle;
    qboolean    locationLinked;         // target_locations get linked
    gentity_t   *locationHead;          // head of the location list
    int         bodyQueIndex;           // dead bodies
    gentity_t   *bodyQue[BODY_QUEUE_SIZE];
#ifdef MISSIONPACK
    int         portalSequence;
#endif
} level_locals_t;
Created 2002.09.21
Updated 2002.12.03
Updated 2003.11.10 - additions from cyrri.
Updated 2011.07.11 - change of contact e-mail.