I need help with my Client-Sided ragdoll system!

I created a ragdoll system that is only client sided because I want to avoid server lag. I did not set the humanoid states yet because I want to fix the problem before hand.

The issue is that the ragdoll physics don’t run on the client whenever the server owner is the sever/nil but whenever the owner of the objects is the player it works just fine.
I want to figure out a way to just fix this myself or a way for me to make the physics run even when the network owner isn’t the player

  • I’ve tried to make a clone of the NPC/player and welded it, but that made it not move the ragdoll around whenever I move the ragdoll on the server.
  • Seeing the welding bug I unwelded it and used run service to just set the position but it was very glitchy with the physics so I scrapped that.

I know I can just set the ragdoll on the server but I’d rather not as I don’t want server lag and I want the game to run as smooth as possible to please refrain from suggesting just doing it on the server.

After that, you should include more details if you have any. Try to make your topic as descriptive as

Here is the script I’m using locally

module.ActivateClientRagdoll = function(char)
	local player = game:GetService("Players").LocalPlayer
	local Humanoid :Humanoid = char:FindFirstChild("Humanoid")
	if char.Name == player.Name then
		if char:FindFirstChild("Head"):FindFirstChild("Headragdoll") then
			return
		else
			Humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.Physics,true)
			Humanoid.AutoRotate = false
		end
	else
		if char:FindFirstChild("Head"):FindFirstChild("Headragdoll") then
			return
		end
	end
	Humanoid.AutomaticScalingEnabled = false
	local attachmentCFrames = {
		["Neck"] = {CFrame.new(0, 1, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1), CFrame.new(0, -0.5, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1)},
		["Left Shoulder"] = {CFrame.new(-1.3, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1), CFrame.new(0.2, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1)},
		["Right Shoulder"] = {CFrame.new(1.3, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1), CFrame.new(-0.2, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)},
		["Left Hip"] = {CFrame.new(-0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
		["Right Hip"] = {CFrame.new(0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
	}
	--[[local function createClone ()
		if char.Name ~= player.Name then
			local oldChar = char
			char = char:Clone()
			for _,v in pairs(oldChar:GetChildren()) do
				if v:IsA("Part") then
					v.Transparency = 1
					v.CanCollide = false
					v.CanTouch = false
					v.Massless = true
				end
				if v:IsA("Model") then
					for _,v in pairs(v:GetChildren()) do
						if v:IsA("MeshPart") then
							v.Transparency = 1
							v.CanCollide = false
							v.CanTouch = false
						end
					end
				end
			end
			for _,v in pairs(oldChar:GetDescendants()) do
				if v:IsA("Decal") or v:IsA("Texture") then
					v.Transparency = 1
				end
			end
			char.Name = char.Name.."ragdoll"
			char.Parent = workspace
			Humanoid = char:FindFirstChild("Humanoid")
			runservice:BindToRenderStep("ragdoll"..char.Name,500,function()
				--char.PrimaryPart.Position = oldChar.PrimaryPart.Position
				for _,part in pairs(char:GetChildren()) do
					if part:IsA("Part") then
						part.Position = oldChar:FindFirstChild(part.Name).Position
					end
				end
			end)
		end
	end]]
	local function createParts ()
		for _,part in pairs(char:GetChildren()) do
			if part:IsA("Part") then
				if part.Name ~= "HumanoidRootPart" then
					local newPart = part:Clone()
					local weld = Instance.new("WeldConstraint")
					weld.Name = "Weld"
					newPart.Name = part.Name.."ragdoll"
					newPart.CanCollide = true
					newPart.Size /= 1.7
					newPart.Transparency = 1
					for _,v in pairs(newPart:GetChildren()) do
						v:Destroy()
					end
					weld.Part0 = newPart
					weld.Part1 = part
					weld.Parent = newPart
					newPart.Parent = part
					part.CanCollide = false
					part.CanTouch = false
					part.Massless = true
					newPart.CanCollide = true
					newPart.CanTouch = true
				end
			end
		end
	end
	local function replaceJoints ()
		for _, motor in pairs(char:GetDescendants()) do
			if motor:IsA("Motor6D") then
				if (motor.Name == "Left Hip" or motor.Name == "Right Hip" or motor.Name == "Left Shoulder" or motor.Name == "Right Shoulder" or motor.Name == "Neck") then
					motor.Enabled = false
					motor.CurrentAngle = 0

					local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					a0.CFrame = attachmentCFrames[motor.Name][1]
					a1.CFrame = attachmentCFrames[motor.Name][2]

					a0.Name = "RagdollAttachment"
					a1.Name = "RagdollAttachment"

					local BallSocketConstraint = Instance.new("BallSocketConstraint")
					BallSocketConstraint.Attachment0 = a0
					BallSocketConstraint.Attachment1 = a1
					BallSocketConstraint.Name = "RagdollBallsocket"

					BallSocketConstraint.Radius = 0.15
					BallSocketConstraint.LimitsEnabled = true
					BallSocketConstraint.TwistLimitsEnabled = false
					BallSocketConstraint.MaxFrictionTorque = 0
					BallSocketConstraint.Restitution = 0
					BallSocketConstraint.UpperAngle = 90
					BallSocketConstraint.TwistLowerAngle = -45
					BallSocketConstraint.TwistUpperAngle = 45

					if motor.Name == "Neck" then
						BallSocketConstraint.TwistLimitsEnabled = true
						BallSocketConstraint.UpperAngle = 45
						BallSocketConstraint.TwistLowerAngle = -70
						BallSocketConstraint.TwistUpperAngle = 70
					end

					a0.Parent = motor.Part0
					a1.Parent = motor.Part1
					BallSocketConstraint.Parent = motor.Parent
				end
			end
		end
	end
	createParts()
	replaceJoints()
end

Credit to this model that I used for most of this script: Credit

I also have 2 clips of it working fine and not working:


1 Like

Unrelated, but I see that you have no walk animations, by any chance do you have the sanatized animation ID error?

1 Like

thats on purpose i disabled the roblox animate script that is inside local players

1 Like

:sob: I guess im the only one that has the issue

1 Like

sanatized animation ID is an error whenever your using animations that aren’t owned by you
if that error is happening from the default roblox animate script delete it in startercharacter and press play in studio then just copy the one from there
If it keeps happening just search it up

1 Like

It looks like you ran the ragdoll function while the humanoid’s networkowner still the server.
You cant change a humanoid’s state when its owned by the server. So once the humanoid’s outlines turn green, that’s when you need to run your humanoid state code. Otherwise it will just be ignored.

Have you tried disabling platformstanding while they are ragdolled?