Edict t: Difference between revisions
Jump to navigation
Jump to search
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
Warning:Never modify
Warning:In most games,
Source can have up to 2048 edicts allocated at any one time. Going over will cause the engine to crash with an error message.
Note:This limit is raised to 4096 in
Portal 2 and 8192 in
Garry's Mod and
Portal 2: Community Edition.
Counter-Strike: Global Offensive and
Team Fortress 2 have the default limit of 2048.
Tip:
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?
Tip:
SirYodaJedi (talk | contribs) |
mNo edit summary |
||
Line 7: | Line 7: | ||
{{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.}} | ||
== Limitations == | ==Limitations== | ||
{{warning|In most games, {{src|4.1}} can have [[entity limit|up to 2048]] edicts allocated at any one time. Going over will cause the engine to crash with an error message. | {{warning|In most games, {{src|4.1}} can have [[entity limit|up to 2048]] edicts allocated at any one time. Going over will cause the engine to crash with an error message. | ||
{{note|This limit is raised to 4096 in {{portal2|4.1}} and 8192 in {{gmod|4.1}} and {{p2ce|4.1}}.<br>{{csgo|4.1}} and {{tf2|4.1}} have the default limit of 2048.}} }} | {{note|This limit is raised to 4096 in {{portal2|4.1}} and 8192 in {{gmod|4.1}} and {{p2ce|4.1}}.<br>{{csgo|4.1}} and {{tf2|4.1}} have the default limit of 2048.}} }} | ||
{{tip|{{gldsrc|4.1}} 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 {{code|edicts{{nbsp}}"2048"}}.{{modernConfirm|What about {{sven|2}}?}} }} | {{tip|{{gldsrc|4.1}} 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 {{code|edicts{{nbsp}}"2048"}}.{{modernConfirm|What about {{sven|2}}?}} }} | ||
== Avoiding == | ==Avoiding== | ||
=== Server only entities === | ===Server only entities=== | ||
{{src|only}} | {{src|only}} | ||
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: | 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: | ||
Line 25: | Line 25: | ||
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. | 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 === | ===Client-only entities=== | ||
{{todo|If the game is not singleplayer, and the entity is non-solid and is not part of {{cmd|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]].}} | {{todo|If the game is not singleplayer, and the entity is non-solid and is not part of {{cmd|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 == | ==Getting== | ||
; <code>edict_t* CBaseEntity::edict()</code> | ; <code>edict_t* CBaseEntity::edict()</code> | ||
: Simple accessor. Returns null if there is no edict. | : Simple accessor. Returns null if there is no edict. | ||
Line 38: | Line 37: | ||
: Returns the current number of assigned edicts (''not'' entities). | : Returns the current number of assigned edicts (''not'' entities). | ||
== Setting == | ==Setting== | ||
; <code>void [[CBaseEntity]]::NetworkProp()->AttachEdict(edict_t* pRequiredEdict);</code> | ; <code>void [[CBaseEntity]]::NetworkProp()->AttachEdict(edict_t* pRequiredEdict);</code> | ||
: Assigns an edict via the entity's <code>[[CServerNetworkProperty]]</code> object. Pass NULL unless a specific edict is required. | : Assigns an edict via the entity's <code>[[CServerNetworkProperty]]</code> object. Pass NULL unless a specific edict is required. | ||
Line 45: | Line 43: | ||
: Detaches the entity's assigned edict. It will go back into the edict pool for re-use. | : Detaches the entity's assigned edict. It will go back into the edict pool for re-use. | ||
== Notable members == | ==Notable members== | ||
; <code>[[CBaseEntity]]* GetUnknown()->GetBaseEntity()</code> | ; <code>[[CBaseEntity]]* GetUnknown()->GetBaseEntity()</code> | ||
: Pointer to the entity's local representation. | : Pointer to the entity's local representation. | ||
Line 64: | Line 61: | ||
: Accessors to various interfaces. | : Accessors to various interfaces. | ||
== See also == | ==See also== | ||
* [[Entity index]] | * [[Entity index]] | ||
* [[Entity limit]] | * [[Entity limit]] |
Revision as of 00:06, 9 September 2024
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.

CHandle
for long-term storage.
edict_t
or CBaseEdict
. If the memory footprint of either changes, engine DLLs will start accessing invalid addresses.Limitations












Avoiding
Server only entities
(only in )
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 */ }

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.
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.