Works in studio but not in game

It looks like this is a much bigger bug

old post

Original Title: Ragdoll script works in studio but not in game

  1. What do you want to achieve?
    I want to have a player character ragdoll-mode that can be disabled or enabled for my game.

  2. What is the issue?
    If I publish the game and test it in the actual game, the character’s joints break apart, regardless of Humanoid.BreakJointsOnDeath being false.
    The code for ragdolls works fine in studio but not in game.
    I can’t figure out why!

  3. What solutions have you tried so far?

  • I’ve tried making sure the client side replicates Humanoid.BreakJointsOnDeath to false
  • I’ve tried testing using a local server and testing with simulation mode. It works fine on both methods. The only problem is when I play the published game.
    image
  • I’ve tried methods of both cloning premade constraint objects and making new constraint objects with code
  • I’ve searched for what’s causing this on the devforums and Google but I can’t find anything relevant.
  • I’ve tried a bunch of other stuff

I’m using a custom R15 character, but it has all the Motor6Ds and Attachments as a regular R15 character.

This is a server script.
Here’s the code:
https://pastebin.com/raw/ihh9bc9R

-- Ragdoll
-- dispeller 2020

Char = script.Parent
Player = game.Players:GetPlayerFromCharacter(Char)
Char.Humanoid.BreakJointsOnDeath = false

RagdollEnabled = false

local JOINT_CONFIGURATION = {
	LeftAnkle = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 15;
			LowerAngle = -45;
		};
	};
	
	RightAnkle = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 15;
			LowerAngle = -45;
		};
	};
	
	LeftKnee = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 0;
			LowerAngle = 45;
		};
	};
	
	RightKnee = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 0;
			LowerAngle = 45;
		};
	};
	
	LeftHip = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = -90;
			LowerAngle = 90;
		};
	};
	RightHip = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = -90;
			LowerAngle = 90;
		};
		
	};
--	Waist = {"BallSocket"};
	LeftShoulder = {
		"BallSocket";
		Properties = {
			TwistLimitsEnabled = true;
			TwistUpperAngle = -90;
			TwistLowerAngle = 90;
		};	
		
	};
	RightShoulder = {
		"BallSocket";
		Properties = {
			TwistLimitsEnabled = true;
			TwistUpperAngle = -90;
			TwistLowerAngle = 90;
		};
		
	};
	LeftElbow = {"Hinge"};
	RightElbow = {"Hinge"};
	
	LeftWrist = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 0;
			LowerAngle = 0;
		};
	};
	
	RightWrist = {
		"Hinge";
		Properties = {
			LimitsEnabled = true;
			UpperAngle = 0;
			LowerAngle = 0;
		};
	};
	
--	Neck = {"BallSocket"};
}

function giveCollisionBox(mBodyPart)
	local collisionBox = Instance.new('Part',mBodyPart)
	collisionBox.Size = mBodyPart.Size -- - Vector3.new(1,1,1)
	collisionBox.Transparency = 1
	collisionBox.CFrame = mBodyPart.CFrame
	local weld = Instance.new('Motor6D',collisionBox)
	weld.Part0 = collisionBox
	weld.Part1 = mBodyPart
end

function enableRagDoll()
	for i=1,3 do
		wait(.05)
		Char.Humanoid.PlatformStand = true
		Char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, true)
	end
	Char.HumanoidRootPart.CFrame = CFrame.new(Char.HumanoidRootPart.Position+Vector3.new(0,2,0))
--	Char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.PlatformStanding,true)
--	giveCollisionBox(Char.HumanoidRootPart)
	local d = Char:GetDescendants()
	for i=1,#d do
		local motor = d[i]
		if motor:IsA("Motor6D") then wait()
			if JOINT_CONFIGURATION[motor.Name] then
				
				local mBodyPart = motor.Parent
				if mBodyPart:IsA('BasePart') then
					giveCollisionBox(mBodyPart)
				end

				
				local socket = Instance.new(JOINT_CONFIGURATION[motor.Name][1].."Constraint")
				socket.Name = motor.Name
				local properties = JOINT_CONFIGURATION[motor.Name].Properties
				if properties then
					for ia,vb in pairs(properties) do
						socket[ia] =  vb
					end
				end
				
				local part0 = motor.Part0
				local joint_name = motor.Name
				local attachment0 = motor.Parent:FindFirstChild(joint_name.."Attachment") or motor.Parent:FindFirstChild(joint_name.."RigAttachment")
				local attachment1 = part0:FindFirstChild(joint_name.."Attachment") or part0:FindFirstChild(joint_name.."RigAttachment")
				if attachment0 and attachment1 then
					socket.Attachment0, socket.Attachment1 = attachment0, attachment1
					socket.Parent = motor
					--motor:Destroy()
					motor.Enabled = false
					motor.Part1 = nil
				else
					warn(motor.Parent.Name)
				end
			else
				print(motor.Name)
			end
		end
	end
end

function disableRagdoll()
	--Char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.PlatformStanding,false)
	for i,v in pairs(Char:GetDescendants()) do
		if v:IsA('BallSocketConstraint') or v:IsA('HingeConstraint') then
			v.Parent.Part1 = v.Parent.Parent
			v:Destroy()
		end
	end
	local hrp = Char.HumanoidRootPart
	hrp.CFrame = CFrame.new(hrp.Position+Vector3.new(0,2,0))*CFrame.Angles(0,math.rad(math.random(-360,360)),0)
	hrp.Velocity = Vector3.new(0,0,0)
	wait()
	Char.Humanoid.PlatformStand = false
	local stateType = Enum.HumanoidStateType
	Char.Humanoid:SetStateEnabled(stateType.FallingDown, false)
	Char.Humanoid:SetStateEnabled(stateType.Ragdoll, false)
end

Char.Humanoid.Died:Connect(function()
	print'DIED!'
	enableRagDoll()
end)

while wait() do
	wait(1.5)
	enableRagDoll()
	wait(1.5)
	disableRagdoll()
end

The code shouldn’t be too hard to understand but sorry for the lack of comments in advance.

Here’s a link to the game:
Whisperbit RPG - Roblox

Have you tried putting prints in and using the developer console (f9) in game?

Okay, it might not be the case at all, but worth a try. Have you tried enabling Studio Access to API Services?

Irrelevant. That option mostly pertains to DataStores (or is only for it, AFAIK). API access for virtually every instance is implicitly enabled.

2 Likes