Basic ragdoll script isn't replicating to client

I have written a simple fading ragdoll function for when players die.
During play test the code works with no errors in output.
However in play test, when my character dies the ragdoll effect does not happen but the fading does.
I found two issues…

  1. One or both Attachments are nil within the BallSocketConstraints only on the Client in play test while both Part0 and Part1 Attachments are set properly when viewing Server Side in play test.

  2. Motor6D instances are not destroyed upon death.

I am not sure if it is a bug or my coding. This isn’t the first time I’ve experienced this when making a ragdoll script. The last time when I noticed this client side problem I just I called the function in a LocalScript added to StarterPlayerScripts too and it worked out. Although this time when I tried to apply the same fix the same issues persists on the client despite both local script and server script running the code.

game.ReplicatedStorage.ModuleScript

local m = {}
local TS = game:GetService("TweenService")
function m.FadingRagdoll(Character)
	for _, Descendant in pairs(Character:GetDescendants()) do
		if Descendant:IsA("Motor6D") then
			local socket = Character:FindFirstChild(Descendant.Name)
			if not socket then
				socket = Instance.new("BallSocketConstraint",Character)
				socket.Name = Descendant.Name
			end
			local A0 = Descendant.Part0[Descendant.Name.."RigAttachment"] or Descendant.Part0[Descendant.Name.."Attachment"]
			local A1 = Descendant.Part1[Descendant.Name.."RigAttachment"] or Descendant.Part1[Descendant.Name.."Attachment"]
			socket.Attachment0 = A0
			socket.Attachment1 = A1
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true
			Character.Humanoid.Died:Connect(function()
				Descendant:Destroy()
			end)
		end
		if Descendant:IsA("BasePart") or Descendant:IsA("Decal") and Descendant.Transparency ~= 1 then
			Character.Humanoid.Died:Connect(function()
				local fade = TS:Create(Descendant,TweenInfo.new(1),{Transparency = .9})
				fade:Play()
			end)
		end
	end
	local Humanoid = Character:FindFirstChild("Humanoid")
	if not Humanoid then
		Humanoid = Character:WaitForChild("Humanoid",10)
	end
	Humanoid.BreakJointsOnDeath = false
end
return m

game.ServerScriptService.ServerScript

local MS = require(game:GetService("ReplicatedStorage").ModuleScript)
game:GetService("Players").PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(MS.FadingRagdoll)
end)

game.StarterPlayer.StarterPlayerScripts.LocalScript

local MS = require(game:GetService("ReplicatedStorage").ModuleScript)
game:GetService("Players").LocalPlayer.CharacterAdded:Connect(MS.FadingRagdoll)

Why are scripted Part1 and Part0 Attachments not replicated to client when the character is added and Motor6D instance are not destroyed upon Humanoid.Died?
What is the problem exactly and how can I work around it or make it work for now?
I hope I do not need to completely rewrite the function as I’d like to keep it simple since I am still a newbie scripter. :woozy_face: Is being too simple the problem?!

I deleted the ModuleScript inserted the code directly into the LocalScript and ServerScript…
game.ServerScriptService.ServerScript

Code
local Players = game:GetService("Players")
local TS = game:GetService("TweenService")
Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		for _, Descendant in pairs(Character:GetDescendants()) do
			if Descendant:IsA("Motor6D") then
				local socket = Character:FindFirstChild(Descendant.Name)
				if not socket then
					socket = Instance.new("BallSocketConstraint",Character)
					socket.Name = Descendant.Name
				end
				local A0 = Descendant.Part0[Descendant.Name.."RigAttachment"] or Descendant.Part0[Descendant.Name.."Attachment"]
				local A1 = Descendant.Part1[Descendant.Name.."RigAttachment"] or Descendant.Part1[Descendant.Name.."Attachment"]
				socket.Attachment0 = A0
				socket.Attachment1 = A1
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true
				Character.Humanoid.Died:Connect(function()
					Descendant:Destroy()
				end)
			end
			if Descendant:IsA("BasePart") or Descendant:IsA("Decal") and Descendant.Transparency ~= 1 then
				Character.Humanoid.Died:Connect(function()
					local fade = TS:Create(Descendant,TweenInfo.new(1),{Transparency = .9})
					fade:Play()
				end)
			end
		end
		local Humanoid = Character:FindFirstChild("Humanoid")
		if not Humanoid then
			Humanoid = Character:WaitForChild("Humanoid",10)
		end
		Humanoid.BreakJointsOnDeath = false
	end)
end)

game.StarterPlayer.StarterPlayerScripts.LocalScript

Code
local Players = game:GetService("Players")
local TS = game:GetService("TweenService")
Players.LocalPlayer.CharacterAdded:Connect(function(Character)
	for _, Descendant in pairs(Character:GetDescendants()) do
		if Descendant:IsA("Motor6D") then
			local socket = Character:FindFirstChild(Descendant.Name)
			if not socket then
				socket = Instance.new("BallSocketConstraint",Character)
				socket.Name = Descendant.Name
			end
			local A0 = Descendant.Part0[Descendant.Name.."RigAttachment"] or Descendant.Part0[Descendant.Name.."Attachment"]
			local A1 = Descendant.Part1[Descendant.Name.."RigAttachment"] or Descendant.Part1[Descendant.Name.."Attachment"]
			socket.Attachment0 = A0
			socket.Attachment1 = A1
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true
			Character.Humanoid.Died:Connect(function()
				Descendant:Destroy()
			end)
		end
		if Descendant:IsA("BasePart") or Descendant:IsA("Decal") and Descendant.Transparency ~= 1 then
			Character.Humanoid.Died:Connect(function()
				local fade = TS:Create(Descendant,TweenInfo.new(1),{Transparency = .9})
				fade:Play()
			end)
		end
	end
	local Humanoid = Character:FindFirstChild("Humanoid")
	if not Humanoid then
		Humanoid = Character:WaitForChild("Humanoid",10)
	end
	Humanoid.BreakJointsOnDeath = false
end)

Now in play test, I still have no errors in output but the fading effect no longer works either when my character dies in addition to the client side problems…:sob:

  1. Motor6D not Destroyed on neither client or server
    *Sometimes the neck Motor6D is destroyed and head falls off
  2. (Client Side) BallSocketConstraint either one or both Part1 and Part0 are nil
    *Only ones that sometimes have Attachment set are Neck or Root
  3. None of the baseparts or decals(face) fade
    *Sometimes the head will fade

I tested your scripts (the original one with the Module Script existing). They work fine. The only change I made was removing the Local Script as it is unnecessary (all changes to the Server will replicate to the Client unless told in the API that they will not).

The Local Script might be the problem.

I am not too familiar with API or what it is or what it means… so, I doubt I have fiddled around with it either for that to be a cause of the matter.
With that said, to test I opened a blank(new) place in studio and inserted the code into a ServerScript in ServerScriptService with no luck of seeing it work in play test.

Code
local Players = game:GetService("Players")
local TS = game:GetService("TweenService")
Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		for _, Descendant in pairs(Character:GetDescendants()) do
			if Descendant:IsA("Motor6D") then
				local socket = Character:FindFirstChild(Descendant.Name)
				if not socket then
					socket = Instance.new("BallSocketConstraint",Character)
					socket.Name = Descendant.Name
				end
				local A0 = Descendant.Part0[Descendant.Name.."RigAttachment"] or Descendant.Part0[Descendant.Name.."Attachment"]
				local A1 = Descendant.Part1[Descendant.Name.."RigAttachment"] or Descendant.Part1[Descendant.Name.."Attachment"]
				socket.Attachment0 = A0
				socket.Attachment1 = A1
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true
				Character.Humanoid.Died:Connect(function()
					Descendant:Destroy()
				end)
			end
			if Descendant:IsA("BasePart") or Descendant:IsA("Decal") and Descendant.Transparency ~= 1 then
				Character.Humanoid.Died:Connect(function()
					local fade = TS:Create(Descendant,TweenInfo.new(1),{Transparency = .9})
					fade:Play()
				end)
			end
		end
		local Humanoid = Character:FindFirstChild("Humanoid")
		if not Humanoid then
			Humanoid = Character:WaitForChild("Humanoid",10)
		end
		Humanoid.BreakJointsOnDeath = false
	end)
end)

I died and became a statue… the constraints part1 and part0 are nil on client side only still

I took a raw approach and scripted each and every BallSocketConstraint for my ragdoll effect…

Code
local Players = game:GetService("Players")
local TS = game:GetService("TweenService")
Players.LocalPlayer.CharacterAdded:Connect(function(Character)
	local LeftWrist = Instance.new("BallSocketConstraint",Character)
	LeftWrist.Name = "LeftWrist"
	LeftWrist.Attachment0 = Character.LeftLowerArm.LeftWristRigAttachment
	LeftWrist.Attachment1 = Character.LeftHand.LeftWristRigAttachment
	local LeftElbow = Instance.new("BallSocketConstraint",Character)
	LeftElbow.Name = "LeftElbow"
	LeftElbow.Attachment0 = Character.LeftUpperArm.LeftElbowRigAttachment
	LeftElbow.Attachment1 = Character.LeftLowerArm.LeftElbowRigAttachment
	local LeftShoulder = Instance.new("BallSocketConstraint",Character)
	LeftShoulder.Name = "LeftShoulder"
	LeftShoulder.Attachment0 = Character.UpperTorso.LeftShoulderRigAttachment
	LeftShoulder.Attachment1 = Character.LeftUpperArm.LeftShoulderRigAttachment
	local RightWrist = Instance.new("BallSocketConstraint",Character)
	RightWrist.Name = "RightWrist"
	RightWrist.Attachment0 = Character.RightLowerArm.RightWristRigAttachment
	RightWrist.Attachment1 = Character.RightHand.RightWristRigAttachment
	local RightElbow = Instance.new("BallSocketConstraint",Character)
	RightElbow.Name = "RightElbow"
	RightElbow.Attachment0 = Character.RightUpperArm.RightElbowRigAttachment
	RightElbow.Attachment1 = Character.RightLowerArm.RightElbowRigAttachment
	local RightShoulder = Instance.new("BallSocketConstraint",Character)
	RightShoulder.Name = "RightShoulder"
	RightShoulder.Attachment0 = Character.UpperTorso.RightShoulderRigAttachment
	RightShoulder.Attachment1 = Character.RightUpperArm.RightShoulderRigAttachment
	local Waist = Instance.new("BallSocketConstraint",Character)
	Waist.Name = "Waist"
	Waist.Attachment0 = Character.LowerTorso.WaistRigAttachment
	Waist.Attachment1 = Character.UpperTorso.WaistRigAttachment
	local LeftAnkle = Instance.new("BallSocketConstraint",Character)
	LeftAnkle.Name = "LeftAnkle"
	LeftAnkle.Attachment0 = Character.LeftLowerLeg.LeftAnkleRigAttachment
	LeftAnkle.Attachment1 = Character.LeftFoot.LeftAnkleRigAttachment
	local LeftKnee = Instance.new("BallSocketConstraint",Character)
	LeftKnee.Name = "LeftKnee"
	LeftKnee.Attachment0 = Character.LeftUpperLeg.LeftKneeRigAttachment
	LeftKnee.Attachment1 = Character.LeftLowerLeg.LeftKneeRigAttachment
	local LeftHip = Instance.new("BallSocketConstraint",Character)
	LeftHip.Name = "LeftHip"
	LeftHip.Attachment0 = Character.LowerTorso.LeftHipRigAttachment
	LeftHip.Attachment1 = Character.LeftUpperLeg.LeftHipRigAttachment
	local RightAnkle = Instance.new("BallSocketConstraint",Character)
	RightAnkle.Name = "RightAnkle"
	RightAnkle.Attachment0 = Character.RightLowerLeg.RightAnkleRigAttachment
	RightAnkle.Attachment1 = Character.RightFoot.RightAnkleRigAttachment
	local RightKnee = Instance.new("BallSocketConstraint",Character)
	RightKnee.Name = "RightKnee"
	RightKnee.Attachment0 = Character.RightUpperLeg.RightKneeRigAttachment
	RightKnee.Attachment1 = Character.RightLowerLeg.RightKneeRigAttachment
	local RightHip = Instance.new("BallSocketConstraint",Character)
	RightHip.Name = "RightHip"
	RightHip.Attachment0 = Character.LowerTorso.RightHipRigAttachment
	RightHip.Attachment1 = Character.RightUpperLeg.RightHipRigAttachment
	local Root = Instance.new("BallSocketConstraint",Character)
	Root.Name = "Root"
	Root.Attachment0 = Character.HumanoidRootPart.RootRigAttachment
	Root.Attachment1 = Character.LowerTorso.RootRigAttachment
	local Neck = Instance.new("BallSocketConstraint",Character)
	Neck.Name = "Neck"
	Neck.Attachment0 = Character.UpperTorso.NeckRigAttachment
	Neck.Attachment1 = Character.Head.NeckRigAttachment
end)

Which revealed an error right away of:

LeftLowerArm is not a valid member of Model “Workspace.LeechBurger”
Stack Begin
Script ‘Players.LeechBurger.PlayerScripts.LocalScript’, Line 6
Stack End

So~ from this, can I assume this is a character loading client side issue? Thus, now I have to check if the character has actually loaded – or rather have the individual parts loaded where I need Attachments from…

maybe a local RigPart = Character:WaitForChild("RigPart") will do?

Your code worked for me like I have said before. But good luck.

Yes, thanks for your help! I determined the cause and solution now so it all works fine again!! :partying_face:

In the end I had to script :WaitForChild() for each BasePart and Motor6D in the Character Model. :roll_eyes::persevere:

As the client (Me) – parts in the character model were not loaded yet when the serverscript tried to get Motor6D Part0 and Part1 for their attachments.
Hence, to the server for whatever means had my character model loaded and ran code successfully but it could not replicate the changes to my client since my character model wasn’t loaded completely for me. As a failsafe a local script is still necessary in this case to wait for instances.

Working ModuleScript function
function m.FadingRagdoll(Character)
	local Humanoid = Character:WaitForChild("Humanoid",10)
	Humanoid.BreakJointsOnDeath = false

	local RightFoot = Character:WaitForChild("RightFoot",10)
	local RightUpperLeg = Character:WaitForChild("RightUpperLeg",10)
	local LeftFoot = Character:WaitForChild("LeftFoot",10)
	local LeftUpperLeg = Character:WaitForChild("LeftUpperLeg",10)
	local LeftUpperArm = Character:WaitForChild("LeftUpperArm",10)
	local RightUpperArm = Character:WaitForChild("RightUpperArm",10)
	local UpperTorso = Character:WaitForChild("UpperTorso",10)
	local LeftLowerLeg = Character:WaitForChild("LeftLowerLeg",10)
	local LowerTorso = Character:WaitForChild("LowerTorso",10)
	local RightLowerArm = Character:WaitForChild("RightLowerArm",10)
	local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart",10)
	local Head = Character:WaitForChild("Head",10)
	local RightHand = Character:WaitForChild("RightHand",10)
	local RightLowerLeg = Character:WaitForChild("RightLowerLeg",10)
	local LeftHand = Character:WaitForChild("LeftHand",10)
	local LeftLowerArm = Character:WaitForChild("LeftLowerArm",10)

	local MOTOR6D_RightAnkle = RightFoot:WaitForChild("RightAnkle",10)
	local PART0_RightAnkle = RightLowerLeg
	local PART1_RightAnkle = RightFoot
	local A0_RightAnkle = PART0_RightAnkle["RightAnkleRigAttachment"] or PART0_RightAnkle["RightAnkleAttachment"]
	local A1_RightAnkle = PART1_RightAnkle["RightAnkleRigAttachment"] or PART1_RightAnkle["RightAnkleAttachment"]
	local MOTOR6D_RightHip = RightUpperLeg:WaitForChild("RightHip",10)
	local PART0_RightHip = LowerTorso
	local PART1_RightHip = RightUpperLeg
	local A0_RightHip = PART0_RightHip["RightHipRigAttachment"] or PART0_RightHip["RightHipAttachment"]
	local A1_RightHip = PART1_RightHip["RightHipRigAttachment"] or PART1_RightHip["RightHipAttachment"]
	local MOTOR6D_LeftAnkle = LeftFoot:WaitForChild("LeftAnkle",10)
	local PART0_LeftAnkle = LeftLowerLeg
	local PART1_LeftAnkle = LeftFoot
	local A0_LeftAnkle = PART0_LeftAnkle["LeftAnkleRigAttachment"] or PART0_LeftAnkle["LeftAnkleAttachment"]
	local A1_LeftAnkle = PART1_LeftAnkle["LeftAnkleRigAttachment"] or PART1_LeftAnkle["LeftAnkleAttachment"]
	local MOTOR6D_LeftHip = LeftUpperLeg:WaitForChild("LeftHip",10)
	local PART0_LeftHip = LowerTorso
	local PART1_LeftHip = LeftUpperLeg
	local A0_LeftHip = PART0_LeftHip["LeftHipRigAttachment"] or PART0_LeftHip["LeftHipAttachment"]
	local A1_LeftHip = PART1_LeftHip["LeftHipRigAttachment"] or PART1_LeftHip["LeftHipAttachment"]
	local MOTOR6D_LeftShoulder = LeftUpperArm:WaitForChild("LeftShoulder",10)
	local PART0_LeftShoulder = UpperTorso
	local PART1_LeftShoulder = LeftUpperArm
	local A0_LeftShoulder = PART0_LeftShoulder["LeftShoulderRigAttachment"] or PART0_LeftShoulder["LeftShoulderAttachment"]
	local A1_LeftShoulder = PART1_LeftShoulder["LeftShoulderRigAttachment"] or PART1_LeftShoulder["LeftShoulderAttachment"]
	local MOTOR6D_RightShoulder = RightUpperArm:WaitForChild("RightShoulder",10)
	local PART0_RightShoulder = UpperTorso
	local PART1_RightShoulder = RightUpperArm
	local A0_RightShoulder = PART0_RightShoulder["RightShoulderRigAttachment"] or PART0_RightShoulder["RightShoulderAttachment"]
	local A1_RightShoulder = PART1_RightShoulder["RightShoulderRigAttachment"] or PART1_RightShoulder["RightShoulderAttachment"]
	local MOTOR6D_Waist = UpperTorso:WaitForChild("Waist",10)
	local PART0_Waist = LowerTorso
	local PART1_Waist = UpperTorso
	local A0_Waist = PART0_Waist["WaistRigAttachment"] or PART0_Waist["WaistAttachment"]
	local A1_Waist = PART1_Waist["WaistRigAttachment"] or PART1_Waist["WaistAttachment"]
	local MOTOR6D_LeftKnee = LeftLowerLeg:WaitForChild("LeftKnee",10)
	local PART0_LeftKnee = LeftUpperLeg
	local PART1_LeftKnee = LeftLowerLeg
	local A0_LeftKnee = PART0_LeftKnee["LeftKneeRigAttachment"] or PART0_LeftKnee["LeftKneeAttachment"]
	local A1_LeftKnee = PART1_LeftKnee["LeftKneeRigAttachment"] or PART1_LeftKnee["LeftKneeAttachment"]
	local MOTOR6D_Root = LowerTorso:WaitForChild("Root",10)
	local PART0_Root = HumanoidRootPart
	local PART1_Root = LowerTorso
	local A0_Root = PART0_Root["RootRigAttachment"] or PART0_Root["RootAttachment"]
	local A1_Root = PART1_Root["RootRigAttachment"] or PART1_Root["RootAttachment"]
	local MOTOR6D_RightElbow = RightLowerArm:WaitForChild("RightElbow",10)
	local PART0_RightElbow = RightUpperArm
	local PART1_RightElbow = RightLowerArm
	local A0_RightElbow = PART0_RightElbow["RightElbowRigAttachment"] or PART0_RightElbow["RightElbowAttachment"]
	local A1_RightElbow = PART1_RightElbow["RightElbowRigAttachment"] or PART1_RightElbow["RightElbowAttachment"]
	local MOTOR6D_Neck = Head:WaitForChild("Neck",10)
	local PART0_Neck = UpperTorso
	local PART1_Neck = Head
	local A0_Neck = PART0_Neck["NeckRigAttachment"] or PART0_Neck["NeckAttachment"]
	local A1_Neck = PART1_Neck["NeckRigAttachment"] or PART1_Neck["NeckAttachment"]
	local MOTOR6D_RightWrist = RightHand:WaitForChild("RightWrist",10)
	local PART0_RightWrist = RightLowerArm
	local PART1_RightWrist = RightHand
	local A0_RightWrist = PART0_RightWrist["RightWristRigAttachment"] or PART0_RightWrist["RightWristAttachment"]
	local A1_RightWrist = PART1_RightWrist["RightWristRigAttachment"] or PART1_RightWrist["RightWristAttachment"]
	local MOTOR6D_RightKnee = RightLowerLeg:WaitForChild("RightKnee",10)
	local PART0_RightKnee = RightUpperLeg
	local PART1_RightKnee = RightLowerLeg
	local A0_RightKnee = PART0_RightKnee["RightKneeRigAttachment"] or PART0_RightKnee["RightKneeAttachment"]
	local A1_RightKnee = PART1_RightKnee["RightKneeRigAttachment"] or PART1_RightKnee["RightKneeAttachment"]
	local MOTOR6D_LeftWrist = LeftHand:WaitForChild("LeftWrist",10)
	local PART0_LeftWrist = LeftLowerArm
	local PART1_LeftWrist = LeftHand
	local A0_LeftWrist = PART0_LeftWrist["LeftWristRigAttachment"] or PART0_LeftWrist["LeftWristAttachment"]
	local A1_LeftWrist = PART1_LeftWrist["LeftWristRigAttachment"] or PART1_LeftWrist["LeftWristAttachment"]
	local MOTOR6D_LeftElbow = LeftLowerArm:WaitForChild("LeftElbow",10)
	local PART0_LeftElbow = LeftUpperArm
	local PART1_LeftElbow = LeftLowerArm
	local A0_LeftElbow = PART0_LeftElbow["LeftElbowRigAttachment"] or PART0_LeftElbow["LeftElbowAttachment"]
	local A1_LeftElbow = PART1_LeftElbow["LeftElbowRigAttachment"] or PART1_LeftElbow["LeftElbowAttachment"]

	local SOCKET_RightAnkle = Character:FindFirstChild("RightAnkle")
	if not SOCKET_RightAnkle then
		SOCKET_RightAnkle = Instance.new("BallSocketConstraint",Character)
	SOCKET_RightAnkle.Name = "RightAnkle"
	end
	SOCKET_RightAnkle.Attachment0 = A0_RightAnkle
	SOCKET_RightAnkle.Attachment1 = A1_RightAnkle
	SOCKET_RightAnkle.LimitsEnabled = true
	SOCKET_RightAnkle.TwistLimitsEnabled = true
	local SOCKET_RightHip = Character:FindFirstChild("RightHip")
	if not SOCKET_RightHip then
		SOCKET_RightHip =Instance.new("BallSocketConstraint",Character)
	SOCKET_RightHip.Name = "RightHip"
	end
	SOCKET_RightHip.Attachment0 = A0_RightHip
	SOCKET_RightHip.Attachment1 = A1_RightHip
	SOCKET_RightHip.LimitsEnabled = true
	SOCKET_RightHip.TwistLimitsEnabled = true
	local SOCKET_LeftAnkle = Character:FindFirstChild("LeftAnkle")
	if not SOCKET_LeftAnkle then
		SOCKET_LeftAnkle = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftAnkle.Name = "LeftAnkle"
	end
	SOCKET_LeftAnkle.Attachment0 = A0_LeftAnkle
	SOCKET_LeftAnkle.Attachment1 = A1_LeftAnkle
	SOCKET_LeftAnkle.LimitsEnabled = true
	SOCKET_LeftAnkle.TwistLimitsEnabled = true
	local SOCKET_LeftHip = Character:FindFirstChild("LeftHip")
	if not SOCKET_LeftHip then
		SOCKET_LeftHip = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftHip.Name = "LeftHip"
	end
	SOCKET_LeftHip.Attachment0 = A0_LeftHip
	SOCKET_LeftHip.Attachment1 = A1_LeftHip
	SOCKET_LeftHip.LimitsEnabled = true
	SOCKET_LeftHip.TwistLimitsEnabled = true
	local SOCKET_LeftShoulder = Character:FindFirstChild("LeftShoulder")
	if not SOCKET_LeftShoulder then
		SOCKET_LeftShoulder = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftShoulder.Name = "LeftShoulder"
	end
	SOCKET_LeftShoulder.Attachment0 = A0_LeftShoulder
	SOCKET_LeftShoulder.Attachment1 = A1_LeftShoulder
	SOCKET_LeftShoulder.LimitsEnabled = true
	SOCKET_LeftShoulder.TwistLimitsEnabled = true
	local SOCKET_RightShoulder = Character:FindFirstChild("RightShoulder")
	if not SOCKET_RightShoulder then
		SOCKET_RightShoulder = Instance.new("BallSocketConstraint",Character)
	SOCKET_RightShoulder.Name = "RightShoulder"
	end
	SOCKET_RightShoulder.Attachment0 = A0_RightShoulder
	SOCKET_RightShoulder.Attachment1 = A1_RightShoulder
	SOCKET_RightShoulder.LimitsEnabled = true
	SOCKET_RightShoulder.TwistLimitsEnabled = true
	local SOCKET_Waist = Character:FindFirstChild("Waist")
	if not SOCKET_Waist then
		SOCKET_Waist = Instance.new("BallSocketConstraint",Character)
	SOCKET_Waist.Name = "Waist"
	end
	SOCKET_Waist.Attachment0 = A0_Waist
	SOCKET_Waist.Attachment1 = A1_Waist
	SOCKET_Waist.LimitsEnabled = true
	SOCKET_Waist.TwistLimitsEnabled = true
	local SOCKET_LeftKnee = Character:FindFirstChild("LeftKnee")
	if not SOCKET_LeftKnee then
		SOCKET_LeftKnee = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftKnee.Name = "LeftKnee"
	end
	SOCKET_LeftKnee.Attachment0 = A0_LeftKnee
	SOCKET_LeftKnee.Attachment1 = A1_LeftKnee
	SOCKET_LeftKnee.LimitsEnabled = true
	SOCKET_LeftKnee.TwistLimitsEnabled = true
	local SOCKET_Root = Character:FindFirstChild("Root")
	if not SOCKET_Root then
		SOCKET_Root = Instance.new("BallSocketConstraint",Character)
	SOCKET_Root.Name = "Root"
	end
	SOCKET_Root.Attachment0 = A0_Root
	SOCKET_Root.Attachment1 = A1_Root
	SOCKET_Root.LimitsEnabled = true
	SOCKET_Root.TwistLimitsEnabled = true
	local SOCKET_RightElbow = Character:FindFirstChild("RightElbow")
	if not SOCKET_RightElbow then
		SOCKET_RightElbow = Instance.new("BallSocketConstraint",Character)
	SOCKET_RightElbow.Name = "RightElbow"
	end
	SOCKET_RightElbow.Attachment0 = A0_RightElbow
	SOCKET_RightElbow.Attachment1 = A1_RightElbow
	SOCKET_RightElbow.LimitsEnabled = true
	SOCKET_RightElbow.TwistLimitsEnabled = true
	local SOCKET_Neck = Character:FindFirstChild("Neck")
	if not SOCKET_Neck then
		SOCKET_Neck = Instance.new("BallSocketConstraint",Character)
	SOCKET_Neck.Name = "Neck"
	end
	SOCKET_Neck.Attachment0 = A0_Neck
	SOCKET_Neck.Attachment1 = A1_Neck
	SOCKET_Neck.LimitsEnabled = true
	SOCKET_Neck.TwistLimitsEnabled = true
	local SOCKET_RightWrist = Character:FindFirstChild("RightWrist")
	if not SOCKET_RightWrist then
		SOCKET_RightWrist = Instance.new("BallSocketConstraint",Character)
	SOCKET_RightWrist.Name = "RightWrist"
	end
	SOCKET_RightWrist.Attachment0 = A0_RightWrist
	SOCKET_RightWrist.Attachment1 = A1_RightWrist
	SOCKET_RightWrist.LimitsEnabled = true
	SOCKET_RightWrist.TwistLimitsEnabled = true
	local SOCKET_RightKnee = Character:FindFirstChild("RightKnee")
	if not SOCKET_RightKnee then
		SOCKET_RightKnee = Instance.new("BallSocketConstraint",Character)
	SOCKET_RightKnee.Name = "RightKnee"
	end
	SOCKET_RightKnee.Attachment0 = A0_RightKnee
	SOCKET_RightKnee.Attachment1 = A1_RightKnee
	SOCKET_RightKnee.LimitsEnabled = true
	SOCKET_RightKnee.TwistLimitsEnabled = true
	local SOCKET_LeftWrist = Character:FindFirstChild("LeftWrist")
	if not SOCKET_LeftWrist then
		SOCKET_LeftWrist = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftWrist.Name = "LeftWrist"
	end
	SOCKET_LeftWrist.Attachment0 = A0_LeftWrist
	SOCKET_LeftWrist.Attachment1 = A1_LeftWrist
	SOCKET_LeftWrist.LimitsEnabled = true
	SOCKET_LeftWrist.TwistLimitsEnabled = true
	local SOCKET_LeftElbow = Character:FindFirstChild("LeftElbow")
	if not SOCKET_LeftElbow then
		SOCKET_LeftElbow = Instance.new("BallSocketConstraint",Character)
	SOCKET_LeftElbow.Name = "LeftElbow"
	end
	SOCKET_LeftElbow.Attachment0 = A0_LeftElbow
	SOCKET_LeftElbow.Attachment1 = A1_LeftElbow
	SOCKET_LeftElbow.LimitsEnabled = true
	SOCKET_LeftElbow.TwistLimitsEnabled = true

	Humanoid.Died:Connect(function()
		MOTOR6D_RightAnkle:Destroy()
		MOTOR6D_RightHip:Destroy()
		MOTOR6D_LeftAnkle:Destroy()
		MOTOR6D_LeftHip:Destroy()
		MOTOR6D_LeftShoulder:Destroy()
		MOTOR6D_RightShoulder:Destroy()
		MOTOR6D_Waist:Destroy()
		MOTOR6D_LeftKnee:Destroy()
		MOTOR6D_Root:Destroy()
		MOTOR6D_RightElbow:Destroy()
		MOTOR6D_Neck:Destroy()
		MOTOR6D_RightWrist:Destroy()
		MOTOR6D_RightKnee:Destroy()
		MOTOR6D_LeftWrist:Destroy()
		MOTOR6D_LeftElbow:Destroy()
	end)
	for _, Descendant in pairs(Character:GetDescendants()) do
		if (Descendant:IsA("BasePart") or Descendant:IsA("Decal")) and Descendant.Transparency ~= 1 then
			Humanoid.Died:Connect(function()
				local fade = TS:Create(Descendant,TweenInfo.new(1),{Transparency = .9})
				fade:Play()
			end)
		end
	end
end

Now if there’s a less lengthy simplified way to check from server if all descendants have loaded in Character Model on clients that would be great. Anyways, I was under the assumption that when CharacterAdded fires that meant the character model had loaded but in truth it seems it means the character is loading:sweat_smile:

*Edit -

simplified

modulescript

m = {}
function m.FadingRagdoll(Character)
	local Humanoid = Character:WaitForChild("Humanoid",10)
	Humanoid.BreakJointsOnDeath = false
	local parts = {
		"RightFoot",
		"RightUpperLeg",
		"LeftFoot",
		"LeftUpperLeg",
		"LeftUpperArm",
		"RightUpperArm",
		"UpperTorso",
		"LeftLowerLeg",
		"LowerTorso",
		"RightLowerArm",
		"HumanoidRootPart",
		"Head",
		"RightHand",
		"RightLowerLeg",
		"LeftHand",
		"LeftLowerArm"
	}
	for _,part in pairs(parts) do
		Character:WaitForChild(part,10)
	end
	for _, D in pairs(Character:GetDescendants())do
		if (D:IsA("BasePart") or D:IsA("Decal")) and D.Transparency ~= 1 then
			Humanoid.Died:Connect(function()
				local fade = TS:Create(D,TweenInfo.new(1),{Transparency = .9})
				fade:Play()
			end)
		end
		if D:IsA("Motor6D") then
			local socket = Character:FindFirstChild(D.Name)
			if not socket then
				socket = Instance.new("BallSocketConstraint",Character)
				socket.Name = D.Name
			end
			socket.Attachment0 = D.Part0[D.Name.."RigAttachment"] or D.Part0[D.Name.."Attachment"]
			socket.Attachment1 = D.Part1[D.Name.."RigAttachment"] or D.Part1[D.Name.."Attachment"]
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true
			Humanoid.Died:Connect(function()
				D:Destroy()
			end)
		end
	end
end
return m

serverscript (players can see players ragdoll)

local MS = require(game:GetService("ReplicatedStorage").ModuleScript)
game:GetService("Players").PlayerAdded:Connect(function(Player)
     Player.CharacterAdded:Connect(MS.FadingRagdoll)
end)

localscript (client/player see their char ragdoll)

local MS = require(game:GetService("ReplicatedStorage").ModuleScript)
game:GetService("Players").LocalPlayer.CharacterAdded:Connect(MS.FadingRagdoll)
2 Likes