Temporary Entity

Temporary entities are used by the server to create short-lived or one-off effects on clients. They are different to standard entities in that they are 'fire and forget'; once one has been created, the server has nothing more to do with it. TEs have no edict or entity index, and do not count toward the entity limit.
TEs are unreliable and get dropped if too many are created at once. The maximum per update is 32 in multiplayer and 255 in single player. 
== Implementation ==
On the server:
*Derive from CBaseTempEntity in basetempentity.h
*Create a constructor that accepts const char *name, and that constructs CBaseTempEntity with the same parameter (see the example below for syntax)
*Create a global 'singleton' instance to spawn further instances (see g_TEMyEffect in example)
*Create a global function that fills in any requisite data then calls Create( IRecipientFilter filter, float delay )
On the client:
*Derive from C_BaseTempEntity in c_basetempentity.h
*Create void PostDataUpdate( DataUpdateType_t updateType ), which is called whenever an instance spawns
== Shared/predicted TEs ==
Temp entities are used quite often, also in shared game code (same code that is compiled into server.dll and client.dll). For shared code we need a shared interface that allows creating temp entities the same way on the server as on the client. This common interface is ITempEntsSystem that provides member functions to create any temp entity. The ITempEntsSystem interface is implemented server-side by class CTempEntsSystem and class C_TempEntsSystem in client code. For new temp entity classes, this interface has to be extended as well as both implementations.
For shared predicted code these classes also handle effect suppression for clients that already spawned the effect in their own prediction code. E.g.: A client fires a predicted weapon and creates instantly a local, predicted impact effect. When the server runs the same weapon code again, this impact effect must be sent to all other clients, but not to the shooting client. Filtering these temp entities that are spawned by predicted code is handled by function SuppressTE().
== Example ==
===Server===
 #include "cbase.h"
 #include "basetempentity.h"
 
 class CTEMyEffect : public CBaseTempEntity
 {
 	DECLARE_CLASS( CTEMyEffect, CBaseTempEntity );
 	DECLARE_SERVERCLASS();
 
 	// Constructor
 	CTEMyEffect( const char *name ) : CBaseTempEntity( name ) {}
 
 	CNetworkVector( m_vecPosition );
 };
 
 // Declare server send table
 IMPLEMENT_SERVERCLASS_ST(CTEMyEffect, DT_TEMyEffect)
 	SendPropVector( SENDINFO(m_vecPosition), -1, SPROP_COORD),
 END_SEND_TABLE()
 
 // Singleton to fire TEMyEffect objects
 static CTEMyEffect g_TEMyEffect ( "MyEffect's name" );
 
 // global function to spawn an instance
 void TE_MyEffect( IRecipientFilter& filter, float delay, const Vector* position )
 {
 	// set effect data
 	g_TEMyEffect.m_vecPosition = *position;
 
 	// Send it over the wire
 	g_TEMyEffect.Create( filter, delay );
 }
===Client===
 #include "cbase.h"
 #include "c_basetempentity.h"
 
 class C_TEMyEffect : public C_BaseTempEntity
 {
 	DECLARE_CLASS( C_TEMyEffect, C_BaseTempEntity );
 	DECLARE_CLIENTCLASS();
 
 	void PostDataUpdate( DataUpdateType_t updateType )
 	{
 		// temp entity has been spawned, do something
 		Msg("Created effect at position %.1f,%.1f,%.1f\n", m_vecPosition[0], m_vecPosition[1], m_vecPosition[2] );
 	}
 
 	Vector	m_vecPosition;
 };
 
 
 // declare the client receive table
 IMPLEMENT_CLIENTCLASS_EVENT_DT(C_TEMyEffect, DT_TEMyEffect, CTEMyEffect)
 	RecvPropVector( RECVINFO(m_vecPosition)),
 END_RECV_TABLE()
== See also ==
* Networking Events & Messages
* Counter-Strike: Source teprops dump
* Half-Life Deathmatch: Source teprops dump
* Left 4 Dead teprops dump
* Left 4 Dead 2 teprops dump
Category:Networking
Category:Programming