Edict t: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(destubbed)
(edicts are specifically for networking)
Line 1: Line 1:
{{toc-right}} {{DISPLAYTITLE:edict_t}}
{{toc-right}} {{DISPLAYTITLE:edict_t}}


'''<code>edict_t</code>''' ("entity dictionary") is an [[interface]] [[struct]] used to refer to [[entity|entities]] across DLL boundaries, including the client/server divide. In each location it provides a pointer to the local representation of its assigned entity.
'''<code>edict_t</code>''' ("entity dictionary") is an [[interface]] [[struct]] that allows [[entity|entities]] to cross the client/server divide: with one attached, an entity has the same [[entity index|index]] at both ends. The edict also manages the state of the entity's [[DataTable]] and provides a common representation across all DLLs.


{{note|An edict is not reliable between frames, as it can be freed from one entity and and reallocated to another at any time. Use <code>[[CHandle]]</code> for long-term storage.}}
{{note|An edict is not reliable between frames, as it can be freed from one entity and and reallocated to another at any time. Use <code>[[CHandle]]</code> for long-term storage.}}


{{warning|Never modify <code>edict_t</code> or <code>CBaseEdict</code>. If the memory footprint of either changes, engine DLLs will start accessing invalid addresses.}}
{{warning|Never modify <code>edict_t</code> or <code>CBaseEdict</code>. If the memory footprint of either changes, engine DLLs will start accessing invalid addresses.}}
{{todo|Is the dictionary synced between client and server even for non-networked ents?}}


== Edict limit ==
== Edict limit ==


Source can have up to 2048 edicts allocated at any one time, and going over that will cause the engine to exit with an error message. This is commonly referred to as the [[entity limit]], which is inaccurate; there is an entity limit, but it is 4096 and hitting it will cause only console errors.
Source can have [[entity limit|up to 2048]] edicts allocated at any one time. Going over will cause the engine to exit with an error message.


== Avoiding ==
== Avoiding ==


Edicts are automatically assigned by <code>[[CBaseEntity]]::PostConstructor()</code>. To prevent this, [[Constructor|construct]] your entity like so:
Edicts are assigned by <code>[[CBaseEntity]]::PostConstructor()</code>. If your entity won't ever need to be transmitted to the client, [[Constructor|construct]] it like so:


<source lang=cpp>CMyEntity() : CBaseEntity(true) { /*...*/ }</source>
<source lang=cpp>CMyEntity() : CBaseEntity(true) { /*...*/ }</source>
Line 21: Line 19:
{{tip|<code>CServerOnlyEntity</code> already does this. <code>[[CLogicalEntity]]</code> inherits, and as such none of Valve's [[Special:PrefixIndex/logic_|logic entities]] or [[:Category:Constraints|VPhysics constraints]] have edicts.}}
{{tip|<code>CServerOnlyEntity</code> already does this. <code>[[CLogicalEntity]]</code> inherits, and as such none of Valve's [[Special:PrefixIndex/logic_|logic entities]] or [[:Category:Constraints|VPhysics constraints]] have edicts.}}


Edict-less entities still count toward the overall entity limit, which is 4096.
Edict-less entities count toward non-networked entity limit, which is also 2048.


== Getting ==
== Getting ==
Line 49: Line 47:
; <code>[[float]] freetime</code>
; <code>[[float]] freetime</code>
: The server timestamp at which the edict was last freed. Can be used to avoid reallocating the edict immediately.
: The server timestamp at which the edict was last freed. Can be used to avoid reallocating the edict immediately.
; <code>bool HasStateChanged()</code>
: Whether anything in the [[DataTable]] needs transmission.
; <code>void StateChanged()</code>
: Tell the edict of a change to the entity's DataTable that needs transmission.
; <code>[[IServerEntity]]* GetIServerEntity()</code>
; <code>[[IServerEntity]]* GetIServerEntity()</code>
; <code>[[IServerNetworkable]]* GetNetworkable()</code>
; <code>[[IServerNetworkable]]* GetNetworkable()</code>
Line 60: Line 62:
* <code>[[CHandle]]</code>
* <code>[[CHandle]]</code>
* [http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg01215.html Discussion on GoldSrc edicts]
* [http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg01215.html Discussion on GoldSrc edicts]
* [http://www.quake2.com/dll/doc/ent_atr.html Quake 2's edict_t.] Storing so many disparate variables in an engine interface was a bad idea!
* [http://www.quake2.com/dll/doc/ent_atr.html Quake 2's edict_t]


[[Category:Interfaces]]
[[Category:Interfaces]]

Revision as of 05:47, 16 September 2009

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.

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.

Edict limit

Source can have up to 2048 edicts allocated at any one time. Going over will cause the engine to exit with an error message.

Avoiding

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) { /*...*/ }
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 toward non-networked entity limit, which is also 2048.

Getting

edict_t* CBaseEntity::edict()
Simple accessor. Returns null if there is no edict.
edict_t* PEntityOfEntIndex(int iEntIndex)
Given an entity index, returns a pointer to the corresponding 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