Problem:
- I’ve been working on a ragdoll system and the progress has been good. However, I’ve encountered some problems with the communication between server and clients.
- For some reason when you ragdoll on high speed, it seems to freeze for a bit when viewed by another player. However this isn’t the case with the player being ragdolled.
- And for note, this problem also happens outside of studio.
POV of ragdolled player:
POV of viewer:

Attempts to fix:
- SetNetworkOwner(nil) - I’ve tried to set the network owner to nil, however all it did was make the player unable to ragdoll.
- Messed with Motor6D’s - I’ve tried to mess around with Motor6D’s by disabling some parts but it just made the ragdoll more clunky and messed up.
Script:
-- Setup the humanoid for it to work with the ragdoll.
local function setupHumanoid(character: Model)
local player = Players:GetPlayerFromCharacter(character)
local humanoid: Humanoid = character:FindFirstChildOfClass("Humanoid")
humanoid.RequiresNeck = false
humanoid.BreakJointsOnDeath = false
character:SetAttribute("Ragdoll", false)
end
-- Build the collision parts for the ragdoll.
local function buildCollisionParts(character: Model)
for _, v in pairs(character:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "HumanoidRootPart" then
local part: BasePart = v:Clone()
part.Name = "CollisionPart"
part.Parent = v
part.CanCollide = false
part.Massless = true
part.Transparency = 1
part.Color = Color3.fromRGB(255, 255, 255)
part:ClearAllChildren()
local weld = Instance.new("Weld")
weld.Parent = part
weld.Part0 = v
weld.Part1 = part
if v.Name == "Head" or v.Name == "Torso" then
part.Size = Vector3.one
else
part.Size = v.Size - Vector3.new(0.5, 0.25, 0.5)
part.Position = v.Position - Vector3.new(0, 0.125, 0)
end
end
end
end
-- Set the collision of the parts.
local function setCollisionParts(character: Model, boolean: boolean)
if boolean then
local Torso: BasePart = character:FindFirstChild("Torso")
if Torso then
Torso.CollisionGroup = collisionRagdollName
end
else
local Torso: BasePart = character:FindFirstChild("Torso")
if Torso then
Torso.CollisionGroup = collisionDefaultName
end
end
for _, v in pairs(character:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "HumanoidRootPart" then
v.CanCollide = not boolean
v.CollisionPart.CanCollide = boolean
end
end
end
-- Build the joints for the ragdoll.
local function buildJoints(character: Model)
local HRP = character:WaitForChild("HumanoidRootPart")
for _, v in pairs(character:GetDescendants()) do
if
not v:IsA("BasePart")
or v:FindFirstAncestorOfClass("Accessory")
or v.Name == "Handle"
or v.Name == "Torso"
or v.Name == "HumanoidRootPart"
then
continue
end
if not CFrameModule[v.Name] then
continue
end
local a0: Attachment, a1: Attachment = Instance.new("Attachment"), Instance.new("Attachment")
local joint: BallSocketConstraint = Instance.new("BallSocketConstraint")
-- Add limitations to the ragdoll.
joint.LimitsEnabled = true
joint.TwistLimitsEnabled = true
joint.MaxFrictionTorque = 10 -- This affects the stiffness.
if v.Name == "Left Arm" or v.Name == "Right Arm" then
joint.TwistLowerAngle = 140
joint.TwistUpperAngle = -140
end
a0.Name = "RAGDOLL_ATTACHMENT"
a0.Parent = v
a0.CFrame = CFrameModule[v.Name].CFrame[2]
a1.Name = "RAGDOLL_ATTACHMENT"
a1.Parent = HRP
a1.CFrame = CFrameModule[v.Name].CFrame[1]
joint.Name = "RAGDOLL_CONSTRAINT"
joint.Parent = v
joint.Attachment0 = a0
joint.Attachment1 = a1
v.Massless = true
end
end
-- Destroy the joints for the ragdoll.
local function destroyJoints(character: Model)
local HRP = character:WaitForChild("HumanoidRootPart")
HRP.Massless = false
for _, v in pairs(character:GetDescendants()) do
if v.Name == "RAGDOLL_ATTACHMENT" or v.Name == "RAGDOLL_CONSTRAINT" then
v:Destroy()
end
if
not v:IsA("BasePart")
or v:FindFirstAncestorOfClass("Accessory")
or v.Name == "Torso"
or v.Name == "Head"
then
continue
end
end
end
-- Set whether the Motor6D is enabled or not.
local function setMotor6D(character: Model, boolean: boolean)
for _, v in pairs(character:GetDescendants()) do
if v.Name == "Handle" or v.Name == "RootJoint" or v.Name == "Neck" then
continue
end
if v:IsA("Motor6D") then
v.Enabled = boolean
end
end
end
-- || MAIN MODULE || --
local RagdollService = Knit.CreateService({
Name = "RagdollService",
Client = {
Ragdoll = Knit.CreateSignal(),
Unragdoll = Knit.CreateSignal(),
},
})
function RagdollService.Client:RagdollSelf(player: Player)
self.Server:RagdollCharacter(player.Character)
end
function RagdollService.Client:UnragdollSelf(player: Player)
self.Server:UnragdollCharacter(player.Character)
end
-- Add cooldown for the RemoteEvent.
local currentTime = tick()
local ragdollCooldown = 1
local density = 7.5
function RagdollService:RagdollCharacter(character: Model)
if tick() - currentTime >= ragdollCooldown then
currentTime = tick()
local player = Players:GetPlayerFromCharacter(character)
local humanoid = character:FindFirstChildOfClass("Humanoid")
local HRP = character:FindFirstChild("HumanoidRootPart")
if not HRP then
return
end
setMotor6D(character, false)
buildJoints(character)
setCollisionParts(character, true)
character:SetAttribute("Ragdoll", true)
for _, collisionParts in pairs(character:GetDescendants()) do
if collisionParts.Name == "CollisionPart" then
collisionParts.Massless = false
local currentProperties: PhysicalProperties = collisionParts.CurrentPhysicalProperties
collisionParts.CustomPhysicalProperties = PhysicalProperties.new(density, currentProperties.Friction, currentProperties.Elasticity)
end
end
if player then
self.Client.Ragdoll:Fire(player)
else
HRP:SetNetworkOwner(nil)
humanoid.AutoRotate = false
humanoid.PlatformStand = true
end
end
end
Please tell me any ideas for solutions, or whether I should do my past attempts again. I will appreciate any help, thank you!