Fading Out NPC Ragdolls

From Valve Developer Community
Jump to: navigation, search

By default, the removal of NPC ragdolls is unreliable at best. Particular spawnflags can be used to try and accomplish this, however they don't always seem to work or often don't work when you might want them to, and any other map- or plugin-based solutions don't address the real problem. This is particularly an issue for Source modifications or maps that involve the constant spawning (and therefore presumably killing) of NPCs, because while traditional "lag" from NPC ragdolls alone is impossible since everything is handled client-side, players can still suffer from low frame rates (FPS) when too many are being drawn on their screen at once, especially if they're using lower-end machines.

One solution to this is to automatically fade out NPC ragdolls after a short period of time has elapsed. This retains the satisfying physics interactions players have grown used to (e.g. watching a zombie's corpse fall off a nearby cliff after relentlessly smacking it in the face with a crowbar) while providing a nice performance boost and keeping the world clean of dead bodies. It also happens to be very easy to implement with source code access.

Note:This will actually end up changing the behavior of all client-based ragdolls, not just NPC ragdolls.

Getting Started

The following files will be modified, so open them up now to save you some time:

  • c_baseanimating.cpp
  • c_baseanimating.h

By default, both of these files can be found in your relative game/client folder.

Implementation

Firstly, we'll need a variable for handling when to actually start fading out our NPC's ragdoll. To do this, we start by defining that variable, a float, in the C_ClientRagdoll class, so search for "class C_ClientRagdoll : public C_BaseAnimating, public IPVSNotify" (no quotes) in c_baseanimating.h and add the following at the end of the section denoted "private:", but before the terminating "};"

float m_flFadeOutDelay;


We're also going to want to define a default value for our float variable. This could be done using ConVars for customization purposes, but given the nature of this feature, declaring a constant works here too, so under where "RUN_SPEED_ESTIMATE_SQR" is defined in c_baseanimating.cpp, add the following:

const float RAGDOLL_FADE_OUT_DELAY = 3.0f;


Now that we have a basic framework, it's time to put it to use. The proposed solution involves counting down the moment an NPC dies and its ragdoll spawns, so at the end of the C_ClientRagdoll's constructor (search for "C_ClientRagdoll::C_ClientRagdoll( bool bRestoring )" in c_baseanimating.cpp, without the quotes), add the following:

m_flFadeOutDelay = gpGlobals->curtime + RAGDOLL_FADE_OUT_DELAY;


We're also going to need to define what happens when we're finished counting down, so search for "void C_ClientRagdoll::ClientThink( void )" in c_baseanimating.cpp and add the following right before "FadeOut();"

if ( gpGlobals->curtime >= m_flFadeOutDelay )
	SUB_Remove();


Believe it or not, that's all there is to it! You're done.

Conclusion

Assuming you've followed the implementation steps from start to finish, you may now go ahead and compile your modification. From now on, when NPCs die, their dead bodies should begin to fade away after the amount of time in seconds defined by RAGDOLL_FADE_OUT_DELAY in c_baseanimating.cpp has elapsed since the NPC's death. You may adjust this constant and change it to whatever you'd like to fit the needs of your project.


Tips:

  • When the super physgun (Blue Gravitygun) is used in npc-enabled servers, the resulting ragdoll is shared with the server and the client, causing lag. Ragdoll cleanup may combat this effect.