Generalities On Entities: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
 
(16 intermediate revisions by 12 users not shown)
Line 1: Line 1:
[[Category:Programming]]
{{LanguageBar|Generalities On Entities}}
 
== Introduction ==
== Introduction ==
{{note|This article assumes that the reader has at least basic experience in C++}}
{{note|This article assumes that the reader has at least basic experience in C++}}
Line 8: Line 7:
Every object, even the world, is an entity in the Source engine. All entities are derived from CBaseEntity.
Every object, even the world, is an entity in the Source engine. All entities are derived from CBaseEntity.


== Naming Conventions ==
== Naming conventions ==


Within the Source SDK, server classes begin with a capital C (<code>C</code>), while client classes begin with a capital C followed by an underscore (<code>C_</code>) - this helps differentiate between the two code bases.
Within the Source SDK, server classes begin with a capital C (<code>C</code>), while client classes begin with a capital C followed by an underscore (<code>C_</code>) - this helps differentiate between the two code bases.
Line 17: Line 16:
  Client: C_MyEntity
  Client: C_MyEntity


The style of naming convention followed through the SDK code base is known as [[Wikipedia:Hungarian Notation|Hungarian Notation]]. Beginners are recommended to maintain the same style as used throughout the code base to save confusion.
The style of naming convention followed through the SDK code base is known as [[Wikipedia:Hungarian notation|Hungarian notation]]. Beginners are recommended to maintain the same style as used throughout the code base to save confusion.


== Base Classes ==
== Base classes ==
Every entity is based on <code>CBaseEntity</code>, however there are many derived classes. The following is a list of the more common derived classes.
Every entity is based on <code>CBaseEntity</code>, however there are many derived classes. The following is a list of the more common derived classes.


=== CBaseAnimating ===
=== [[CBaseAnimating]] ===
Every entity that has a model uses CBaseAnimating. Classes derived from CBaseAnimating can set a model and animate.
Every entity that has a model uses CBaseAnimating. Classes derived from CBaseAnimating can set a model and animate.
{{note|Entities without models are not networked by default. A workaround is <code>AddEFlags( EFL_FORCE_CHECK_TRANSMIT );</code>}}
{{note|Entities without models are not networked by default. A workaround is <code>AddEFlags( EFL_FORCE_CHECK_TRANSMIT );</code>}}
{{note|To use animated models be sure to initialize the playback rate using SetPlaybackRate(1.0f); and call StudioFrameAdvance(); in the think function.}}


=== CBaseTrigger ===
=== [[CBaseTrigger]] ===
[[trigger|Triggers]] are brush based entities that are generally placed during the map creation process.
[[trigger|Triggers]] are brush based entities that are generally placed during the map creation process.


=== CBasePlayer ===
=== [[CBasePlayer]] ===
This entity is the player itself. Every player-entity in the game is CBasePlayer or is derived from this entity.
This entity is the player itself. Every player-entity in the game is CBasePlayer or is derived from this entity.


=== CGameRules ===
=== [[CGameRules]] ===
This entity regulates the rules of the current game. It's mainly the gameplay.
This entity regulates the rules of the current game. It's mainly the gameplay.


=== CBaseCombatCharacter ===
=== [[CBaseCombatCharacter]] ===
Every NPC & player are derived from this class.
Every NPC & player are derived from this class.


== Think Functions ==
== Think functions ==
Think functions are very important in the Source engine. Each entity "thinks", which is essentially just calling a function of that entity.
{{main|Think()}}
 
Think functions are a group of functions comprising the main way to have an entity act without input.  
=== Server side ===
An entity's Think() is run once after it spawns, and can be told when to call itself again using SetNextThink(). Using SetThink() can change between several Think() functions, and GetLastThink() returns the time of the last think function. See [[Think()]] for detailed description.
On the server, coders have the option to define multiple think-functions. However, only one think function can be called each time.
 
====SetThink() and SetNextThink()====
With the function <code>SetThink</code> it is possible to set the think-function. With the function <code>SetNextThink</code> the time is set when the function should be called.
 
For example:
<pre>SetThink(&CBasePlayer::DeathThink);
SetNextThink( gpGlobals->curtime + 0.1f );</pre>
 
This piece of code will make sure that the function <code>PlayerDeathThink</code> is called over 0.1 seconds. It the think-function needs to be called so fast as possible, setting the time to <code>gpGlobals->curtime + 0.01f</code> would be better. When it's set to the current time, it may not work and the Source engine doesn't ever tick faster then 0.01 seconds.
Please note that after this call, the think-function is not called anymore. To keep it being called, a <code>SetNextThink</code> call is needed in the function.
 
Every think-function needs to be defined in the datadesc of the entity. For example:
BEGIN_DATADESC( CBasePlayer)
DEFINE_THINKFUNC( DeathThink),
END_DATADESC()
 
===Client Side===
The client does not provide the same methods for entities to think. These Client Thinks are handled in <code>client_thinklist.cpp</code>. Multiple think functions cannot be defined here, as SetThink will not work properly on this side. Instead, <code>ClientThink</code> and <code>SetNextClientThink()</code> should be used.
 
====ClientThink() and SetNextClientThink()====
These are the equivalent of the server system, except only one function can be used. This will get called based on the SetNextClientThink() time set in the Spawn function, and in subsequent calls to ClientThink(). Two special time settings here: [[CLIENT_THINK_ALWAYS]] and [[CLIENT_THINK_NEVER]].
 
====Simulate()====
Here's the commentary in c_baseentity.cpp: ''"Once-per-frame stuff should go in Simulate()."'' That really sums it up. Generally Simulate() should be used for Particle effects and other such graphical effects. Beware of what is run in Simulate(), because it is run every frame checks should be made to ensure that nothing too intensive is being called continuously.


== Macros ==
== Macros ==
Badly set up macros will give cause errors messages, crash the game and cause erratic behavior. The following is a list of the more common macro definitions and some of the issues that surround them.
Badly set up macros will give error messages, crash the game and cause erratic behavior. The following is a list of the more common macro definitions and some of the issues that surround them.


===[[LINK_ENTITY_TO_CLASS]]()===
=== [[LINK_ENTITY_TO_CLASS]]() ===
This is one of the main macros. An entity cannot be created without this macro being used to define the entity's classname (as returned from <code>GetClassname()</code> on the server). However, on the client, an entity will not return it's classname unless there is a matching data description (<code>DATADESC</code>).
This is one of the main macros. An entity cannot be created without this macro being used to define the entity's classname (as returned from <code>GetClassname()</code> on the server). However, on the client, an entity will not return its classname unless there is a matching data description (<code>DATADESC</code>).


===[[PRECACHE_REGISTER]]()===
=== [[PRECACHE_REGISTER]]() ===
This is used to tell the engine that it needs to precache the entity when it loads. This is provided with the name of the entity (the same name as passed to [[LINK_ENTITY_TO_CLASS]]() ).
This is used to tell the engine that it needs to precache the entity when it loads. This is provided with the name of the entity (the same name as passed to [[LINK_ENTITY_TO_CLASS]]() ).


===[[DECLARE_CLASS]]()===
=== [[DECLARE_CLASS]]() ===
This should be placed in the public section of an entities Class definition. This provides access to the BaseClass Macro.
This should be placed in the public section of an entity's Class definition. This provides access to the BaseClass Macro.


===DECLARE_[[DATADESC]](), BEGIN_[[DATADESC]](), END_[[DATADESC]](), and DEFINE_XXX()===
=== DECLARE_[[DATADESC]](), BEGIN_[[DATADESC]](), END_[[DATADESC]](), and DEFINE_XXX() ===


The Data Description macros provide for a number of different features;
The Data Description macros provide for a number of different features;
Line 87: Line 62:
* Providing external variable inputs (such as setting a model or the health of an item)
* Providing external variable inputs (such as setting a model or the health of an item)


Further information is available on the [http://developer.valvesoftware.com/wiki/Data_Descriptions Data Descriptions] page.
Further information is available on the [[Data Descriptions]] page.


===Networking Entities===  
=== Networking entities ===


See the [[:Category:Programming#Networking|Networking]] section for more information on networking entities, as that is outside the scope of this article.
See the [[:Category:Programming#Networking|Networking]] section for more information on networking entities, as that is outside the scope of this article.
[[Category:Programming]]

Latest revision as of 16:01, 18 July 2025

English (en)Русский (ru)Translate (Translate)

Introduction

Note.pngNote:This article assumes that the reader has at least basic experience in C++

This article is mainly about entities in the Source engine and will try to explain everything about entities.

Every object, even the world, is an entity in the Source engine. All entities are derived from CBaseEntity.

Naming conventions

Within the Source SDK, server classes begin with a capital C (C), while client classes begin with a capital C followed by an underscore (C_) - this helps differentiate between the two code bases.

For example:

Server: CMyEntity
Client: C_MyEntity

The style of naming convention followed through the SDK code base is known as Hungarian notation. Beginners are recommended to maintain the same style as used throughout the code base to save confusion.

Base classes

Every entity is based on CBaseEntity, however there are many derived classes. The following is a list of the more common derived classes.

CBaseAnimating

Every entity that has a model uses CBaseAnimating. Classes derived from CBaseAnimating can set a model and animate.

Note.pngNote:Entities without models are not networked by default. A workaround is AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
Note.pngNote:To use animated models be sure to initialize the playback rate using SetPlaybackRate(1.0f); and call StudioFrameAdvance(); in the think function.

CBaseTrigger

Triggers are brush based entities that are generally placed during the map creation process.

CBasePlayer

This entity is the player itself. Every player-entity in the game is CBasePlayer or is derived from this entity.

CGameRules

This entity regulates the rules of the current game. It's mainly the gameplay.

CBaseCombatCharacter

Every NPC & player are derived from this class.

Think functions

Main article:  Think()

Think functions are a group of functions comprising the main way to have an entity act without input. An entity's Think() is run once after it spawns, and can be told when to call itself again using SetNextThink(). Using SetThink() can change between several Think() functions, and GetLastThink() returns the time of the last think function. See Think() for detailed description.

Macros

Badly set up macros will give error messages, crash the game and cause erratic behavior. The following is a list of the more common macro definitions and some of the issues that surround them.

LINK_ENTITY_TO_CLASS()

This is one of the main macros. An entity cannot be created without this macro being used to define the entity's classname (as returned from GetClassname() on the server). However, on the client, an entity will not return its classname unless there is a matching data description (DATADESC).

PRECACHE_REGISTER()

This is used to tell the engine that it needs to precache the entity when it loads. This is provided with the name of the entity (the same name as passed to LINK_ENTITY_TO_CLASS() ).

DECLARE_CLASS()

This should be placed in the public section of an entity's Class definition. This provides access to the BaseClass Macro.

DECLARE_DATADESC(), BEGIN_DATADESC(), END_DATADESC(), and DEFINE_XXX()

The Data Description macros provide for a number of different features;

  • Specifying Think and Touch functions
  • Providing Inputs and Outputs for mappers
  • Providing external variable inputs (such as setting a model or the health of an item)

Further information is available on the Data Descriptions page.

Networking entities

See the Networking section for more information on networking entities, as that is outside the scope of this article.