i’m making a game with my friend, this piece of code completely bricks our replication on test dummies.
this a ragdoll setup function, when v:SetNetworkOwner(nil)
is not commented out, the network owner should in theory be set to the server. althought when we damage the dummies on our client, it replicates to the server. we are confident that it is this line messing with the replication, since when we had it commented out, the issue stopped.
here are two pov’s that show our issue accurately
please note that the replication of the health only happens when the client touches the dummy
this is the piece of code which handles hits on the client:
the ragdoll module is not made by me or my friend, i found it in #resources:community-resources
here’s the full ragdoll module code:
--!nonstrict
--[[
made 2/11/2024
]]
-- variables
local ragdoll = {}
ragdoll.__index = ragdoll
-- services
local players = game:GetService("Players")
local run = game:GetService("RunService")
local physics = game:GetService("PhysicsService")
-- types
type ragdollSettings = {
impulse: boolean, -- give initial impulse on :ragdoll()
makeRagdollValue: boolean, -- make a value in the character that when changed will ragdoll/unragdoll depending on the value
ragdollTimer: boolean | number, -- automatically undo ragdoll after x amount of time
}
-- creating ragdoll collisiongroup
if run:IsServer() then
physics:RegisterCollisionGroup("ragdoll")
physics:CollisionGroupSetCollidable("ragdoll", "ragdoll", true)
end
-- settings setup
function ragdoll.new(options: ragdollSettings)
local self = setmetatable({}, ragdoll)
-- type checking
self.options = options or {}
self.options.impulse = typeof(self.options.impulse) == "boolean" and self.options.impulse or false
self.options.makeRagdollValue = typeof(self.options.makeRagdollValue) == "boolean" and self.options.makeRagdollValue or false
self.options.ragdollTimer = typeof(self.options.ragdollTimer) == "number" and self.options.ragdollTimer or false
return self
end
function ragdoll:setup(character: Model)
-- references
local ragdollParts = script.RagdollParts:Clone()
-- fixing ragdollParts table
local newrdp = {}
for _, object in pairs(ragdollParts:GetChildren()) do
newrdp[object.Name] = object
end
-- variables
local isPlayer = players:GetPlayerFromCharacter(character)
-- references
local humanoid = character:FindFirstChild("Humanoid")
local head = character:FindFirstChild("Head")
-- checks
if not humanoid then return end
if tostring(humanoid.RigType.Name) ~= "R6" then error("ragdoll module: rig is not R6") return end
if not head then return end
-- humanoid
humanoid.BreakJointsOnDeath = false
humanoid.RequiresNeck = false
-- npc check
if not isPlayer then
-- folder
local socketsFolder = Instance.new("Folder")
socketsFolder.Name = "Sockets"
socketsFolder.Parent = character
-- unachoring baseparts (setnetworkowner is seperate to prevent welding errors)
for _, basePart in pairs(character:GetChildren()) do
if basePart:IsA("BasePart") then
basePart.Anchored = false
end
end
for _, basePart in pairs(character:GetChildren()) do
if basePart:IsA("BasePart") then
basePart:SetNetworkOwner(nil)
end
end
-- heads are not always 1x1x1, resize just in case
head.Size = Vector3.one
-- ragdoll parts
for _, instance in pairs(newrdp) do
if instance:IsA("Attachment") then
instance.Parent = character:FindFirstChild(instance:GetAttribute("Parent"))
elseif instance:IsA("BallSocketConstraint") then
instance.Attachment0 = newrdp[instance:GetAttribute("0")]
instance.Attachment1 = newrdp[instance:GetAttribute("1")]
instance.Parent = socketsFolder
end
end
end
-- ragdoll value
if self.options.makeRagdollValue then
-- value
local bool = Instance.new("BoolValue")
bool.Name = "Ragdolled"
bool.Parent = character
-- ragdoll value
bool:GetPropertyChangedSignal("Value"):Connect(function()
local value = bool.Value
if value then
self:ragdoll(character)
else
self:unragdoll(character)
end
end)
end
end
function ragdoll:ragdoll(character: Model, force: Vector3)
-- variables
local isPlayer = players:GetPlayerFromCharacter(character)
-- references
local humanoid = character:FindFirstChild("Humanoid")
local root = character:FindFirstChild("HumanoidRootPart")
local torso = character:FindFirstChild("Torso")
-- checks
if not humanoid then return end
if tostring(humanoid.RigType.Name) ~= "R6" then error("ragdoll module: rig is not R6") return end
if not root then return end
if not torso then return end
-- setup
humanoid:ChangeState(Enum.HumanoidStateType.Physics)
humanoid.AutoRotate = false
-- disabling motors
for _, motor in pairs(torso:GetChildren()) do
if motor:IsA("Motor6D") then
motor.Enabled = false
end
end
-- collision group
for _, basepart in pairs(character:GetChildren()) do
if basepart:IsA("BasePart") then
basepart.CollisionGroup = "ragdoll"
end
end
-- impulse
if self.options.impulse then
root:ApplyAngularImpulse(Vector3.new(-90, 0, 0))
end
-- force
if force and typeof(force) == "Vector3" then
root.Velocity += force
end
-- ragdoll timer
if self.options.ragdollTimer then
task.spawn(function()
-- wait
task.wait(self.options.ragdollTimer)
-- unragdoll
if character then
self:unragdoll(character)
end
end)
end
end
function ragdoll:unragdoll(character: Model)
-- variables
local player = players:GetPlayerFromCharacter(character)
-- references
local humanoid = character:FindFirstChild("Humanoid")
local root = character:FindFirstChild("HumanoidRootPart")
local torso = character:FindFirstChild("Torso")
-- checks
if not humanoid then return end
if tostring(humanoid.RigType.Name) ~= "R6" then error("ragdoll module: rig is not R6") return end
if not root then return end
if not torso then return end
-- setup
humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
humanoid.AutoRotate = true
-- enabling motors
for _, motor in pairs(torso:GetChildren()) do
if motor:IsA("Motor6D") then
motor.Enabled = true
end
end
-- collision group
for _, basepart in pairs(character:GetChildren()) do
if basepart:IsA("BasePart") then
basepart.CollisionGroup = "Default"
end
end
end
return ragdoll
for anyone wondering, the module:Ragdoll()
function is called from the server, not clients.
any help is greatly appreciated !