Clientside SENT Creation


I’m struggling with creating a client-side scripted entity. In all of the examples that I can find, an existing entity type is used such as prop_dynamic and the like. I’d like to make my own with a custom draw function.

I’ve tried just moving my ENT:Initialize() function to the shared file but I always get the error “Can’t find factory for entity”.

Any ideas as to what I can try ? Can custom SENTs only be created on the server ?


Only thing I know is: When you want to draw it by yourself SENT:Draw() is what you need. And for the Entities Clientside… I really dunno!

Try using this:

That never worked for me, I always have the “Can’t find entity factory” error. Would be great if someone could get this to work properly.


In most cases, an effect will do nicely. It has a custom render hook which will certainly do whatever you want to.

Have a look at the base and sandbox gamemode if you want to see how Garry defines and uses them.

Thanks for your replies.

I just tried ENT:InitializeAsClientEntity() in case it has been fixed and it seemed to do nothing of any use. :frowning:

It looks like using an effect with a client-side prop_dynamic will be the best option for me, thanks for the suggestion on that I had forgotten about effects.

Regarding the error it’s self, I believe entity factories are created when you (In C++.) use the macro LINK_ENTITY_TO_CLASS(), which I assume isn’t getting called on the client. (I don’t know if there’s a specific client-side version of that macro or if you use the same one.) I’d guess that was what ENT:InitializeAsClientEntity() was meant to fix, but as ENT:Initilize() never gets called due to the entity not having a factory, it never gets linked. As such I tried running ENT:InitializeAsClientEntity() outside of the function but I guess I was calling it wrong or it doesn’t work how I expected.


Taken from the Orange Box SDK:
Client: c_gib.cpp

bool C_Gib::InitializeGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime )
	if ( InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
		return false;

	SetAbsOrigin( vecOrigin );

	solid_t tmpSolid;
	PhysModelParseSolid( tmpSolid, this, GetModelIndex() );
	m_pPhysicsObject = VPhysicsInitNormal( SOLID_VPHYSICS, 0, false, &tmpSolid );
	if ( m_pPhysicsObject )
		float flForce = m_pPhysicsObject->GetMass();
		vecForceDir *= flForce;	

		m_pPhysicsObject->ApplyForceOffset( vecForceDir, GetAbsOrigin() );
		m_pPhysicsObject->SetCallbackFlags( m_pPhysicsObject->GetCallbackFlags() | CALLBACK_GLOBAL_TOUCH | CALLBACK_GLOBAL_TOUCH_STATIC );
		// failed to create a physics object
		return false;

	SetNextClientThink( gpGlobals->curtime + flLifetime );

	return true;

Notice their call to InitializeAsClientEntity() has two parameters. Regardless I don’t think it would fix the factory issue, I’ll look for the factory now.

The static method CreateClientsideGib() seems to be their “factory”, but there is no way that I know of to create a method like this from Lua.

Client: c_gib.cpp

C_Gib *C_Gib::CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float flLifetime )
	C_Gib *pGib = new C_Gib;

	if ( pGib == NULL )
		return NULL;

	if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, flLifetime ) == false )
		return NULL;

	return pGib;

It’s been awhile, but I’m pretty sure effects are source entities too. You should be able to call Entity library functions on EFFECT.Entity.

I don’t think it has the same hooks though. :frowning:


Check out garry’s gib effect from gmdm to see what I mean.

Did you return true in InitializeAsClientEntity?

Ah I see, it seems effects will do the job perfectly. Thanks. I wonder if you can use ‘self’ in place of ‘self.Entity’ inside of an effect like you can in entities - Will have to try it.

No I called it as a function, I didn’t create the hook. I did this due to the Wiki’s description:

I think I’ll leave it and not look in to it more as effects seem to replace client-side entities entirely.

Well my experience with the wiki is, that it is usually wrong. Looking at the C++ code it calls the function which returns a boolean so I figured have it return true. Not sure.