My death script lags the game out no matter what I do

I want to have, when the player or enemy npc dies, a ragdoll, then followed by a fade out in transparency + smoke particle emitter, in addition to any other functions to be done.

Whenever I have more than 50+ npcs at once with maybe 10-20 or more dying, the game lags like crazy.

I’m using this ragdoll module

-- kills the character by ragdolling, then fading the body away then destroying all the parts
function Health.Die(character: Model, killer: Model)
	ReplicatedStorage.Events.World.ChangeState:Fire(character, State.Dead)
	
	character.Stats.Combat.HealthBar.RemainingHP.Value = 0
	character.Stats.Combat.HP.Value = 0

	-- reward killer
	local player = nil
	pcall(function()
		player = players:GetPlayerFromCharacter(killer)
	end)
	if player then
		ReplicatedStorage.Events.Combat.RewardKill:Fire(player, character)
	end
	
	-- ragdoll

	character.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	AnimationHandler.StopAnim(character, "ALL", nil, true, 0)
	
	if character.Parent.Name == "Dummies" then
		Ragdoll.Bot(character)
	elseif character.Parent.Name == "Players" then
		Ragdoll.Ragdoll(character)
	end

	-- turn off collision and lower knockback
	for _, d in pairs(character:GetDescendants()) do
		if d:IsA("BasePart") then
			d.CollisionGroup = "PlayerNoCollide"
			pcall(function() d:SetNetworkOwner(nil) end)
			d.CanCollide = true
			d.CustomPhysicalProperties = PhysicalProperties.new(2, 0.5, 0.5)

		-- fade out
			task.delay(deathStillDuration, function()
				if d.Transparency ~= 1 then
					local tween = TweenService:Create(d, deathTweenInfo, {Transparency = 1})
					tween:Play()
				end
			end)

		elseif d:IsA("GuiObject") then
			task.delay(deathStillDuration, function()
				pcall(function()
					local tween = TweenService:Create(d, deathTweenInfo, {BackgroundTransparency = 1})
					tween:Play()
				end)
				pcall(function()
					local tween = TweenService:Create(d, deathTweenInfo, {TextTransparency = 1})
					tween:Play()
				end)
			end)

		elseif d:IsA("UIStroke") then
			task.delay(deathStillDuration, function()
				pcall(function()
					local tween = TweenService:Create(d, deathTweenInfo, {Transparency = 1})
					tween:Play()
				end)
			end)
		end
	end
	
	task.wait(deathStillDuration)
	
	-- add smoke
	local smoke = ServerStorage.Particles.DeathSmoke:Clone()
	smoke.Parent = character.HumanoidRootPart
	
	task.delay(deathTweenDuration * 0.75, function()
		smoke.Enabled = false
		game.Debris:AddItem(character, smoke.Lifetime.Max)
	end)
end

The issue with this is that the majority of the time it’s going to be an NPC that is dying so I don’t really know if I should be putting so much onto the client at once. I’m considering making a module that handles whether or not the death animation should be rendered and to whom based on how far away they are but I wanna know if there are any other more general solutions that I can do

1 Like

The client can handle lots of what you give it. Your right in thinking of rendering only close NPCs to the client. Good luck!