edict_t

From Valve Developer Community
(Redirected from Edicts)
Jump to: navigation, search

edict_t ("entity dictionary") is an interface struct that allows entities to cross the client/server divide: with one attached, an entity has the same index at both ends. The edict also manages the state of the entity's DataTable and provides a common representation across all DLLs. It cannot be used on the client.

Note.pngNote:An edict is not reliable between frames, as it can be freed from one entity and and reallocated to another at any time. Use CHandle for long-term storage.
Warning.pngWarning:Never modify edict_t or CBaseEdict. If the memory footprint of either changes, engine DLLs will start accessing invalid addresses.

Limitations

Warning.pngWarning:In most games, Source Source can have up to 2048 edicts allocated at any one time. Going over will cause the engine to crash with an error message.
Tip.pngTip:GoldSrc GoldSrc has a maximum of 1200 edicts by default (900 prior to 25th-anniversary update), but this can be raised to 2048 in a mod by editing its liblist.gam to include the line edicts "2048".
Confirm:What about Sven Co-op Sven Co-op?

Avoiding

Server only entities

(only in Source) Edicts are assigned by CBaseEntity::PostConstructor(). If your entity won't ever need to be transmitted to the client, construct it like so:

CMyEntity() : CBaseEntity(true) { /* your constructor code */ }
Tip.pngTip:CServerOnlyEntity already does this. CLogicalEntity inherits, and as such none of Valve's logic entities or VPhysics constraints have edicts.

Edict-less entities count towards the non-networked entity limit, which is the same or higher than the edict limit.

Entities compiled into the map which are not recognized by the game code do not count towards any entity limit in-game as they are simply not spawned.

Client-only entities

Todo: If the game is not singleplayer, and the entity is non-solid and is not part of s_PreserveEnts, it can be removed server-side. See env_sprite_clientside source code in Alien Swarm for example implementation in Source. In GoldSrc, use MAKE_STATIC.

Getting

edict_t* CBaseEntity::edict()
Simple accessor. Returns null if there is no edict.
edict_t* INDEXENT( int iEdictNum )
int ENTINDEX( edict_t* pEdict )
Converts between an entity index and its attached edict.
int GetEntityCount()
Returns the current number of assigned edicts (not entities).

Setting

void CBaseEntity::NetworkProp()->AttachEdict(edict_t* pRequiredEdict);
Assigns an edict via the entity's CServerNetworkProperty object. Pass NULL unless a specific edict is required.
void CBaseEntity::NetworkProp()->DetachEdict()
Detaches the entity's assigned edict. It will go back into the edict pool for re-use.

Notable members

CBaseEntity* GetUnknown()->GetBaseEntity()
Pointer to the entity's local representation.
char* GetClassName()
The classname of the assigned entity.
bool IsFree()
Whether there is currently an entity assigned to this edict.
float freetime
The server timestamp at which the edict was last freed. Can be used to avoid reallocating the edict immediately.
bool HasStateChanged()
Whether anything in the DataTable needs transmission.
void StateChanged()
Tell the edict of a change to the entity's DataTable that needs transmission.
IServerEntity* GetIServerEntity()
IServerNetworkable* GetNetworkable()
ICollideable* GetCollideable()
Accessors to various interfaces.

See also