local Players = game:GetService("Players") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local SEEK_SPEED = 220 local SPREAD_STRENGTH = 70 local SPAM_REPEAT_COUNT = 6 local SPAM_INTERVAL = 0.08 local MAX_TARGETS = 3 local GROUND_VELOCITY_THRESHOLD = 3 local GROUND_SETTLE_TIME = 0.05 local MAX_SETTLE_WAIT = 1.0 local FALL_SAFETY_DROP = 50 local function findClosestPlayerRoots(fromPosition, maxCount) local candidates = {} for _, other in ipairs(Players:GetPlayers()) do if other ~= player and other.Character then local otherRoot = other.Character:FindFirstChild("HumanoidRootPart") if otherRoot then table.insert(candidates, { root = otherRoot, dist = (otherRoot.Position - fromPosition).Magnitude }) end end end table.sort(candidates, function(a, b) return a.dist < b.dist end) local result = {} for i = 1, math.min(maxCount, #candidates) do table.insert(result, candidates[i].root) end return result end local function assignTargets(partsData, targetRoots) for i, data in ipairs(partsData) do if #targetRoots > 0 then data.targetRoot = targetRoots[((i - 1) % #targetRoots) + 1] else data.targetRoot = nil end end end local function scatterImpulse(partsData) for _, data in ipairs(partsData) do local part = data.part if part and part.Parent then part.Anchored = false part.CanCollide = true part.AssemblyLinearVelocity = Vector3.new( math.random(-SPREAD_STRENGTH, SPREAD_STRENGTH), math.random(15, SPREAD_STRENGTH), math.random(-SPREAD_STRENGTH, SPREAD_STRENGTH) ) end end end local function homeTowardTargets(partsData, fallbackPosition, maxTime) local startTime = os.clock() local settledSince = nil while os.clock() - startTime < maxTime do local allSlow = true for _, data in ipairs(partsData) do local part = data.part if part and part.Parent then local targetPosition = data.targetRoot and data.targetRoot.Position or fallbackPosition local toTarget = targetPosition - part.Position local horizontal = Vector3.new(toTarget.X, 0, toTarget.Z) local direction = horizontal.Magnitude > 0.1 and horizontal.Unit or Vector3.new(0, 0, 0) local vel = part.AssemblyLinearVelocity local desiredHorizontal = direction * SEEK_SPEED local smoothedX = vel.X + (desiredHorizontal.X - vel.X) * 0.35 local smoothedZ = vel.Z + (desiredHorizontal.Z - vel.Z) * 0.35 part.AssemblyLinearVelocity = Vector3.new(smoothedX, vel.Y, smoothedZ) if math.abs(vel.Y) > GROUND_VELOCITY_THRESHOLD then allSlow = false end end end if allSlow then settledSince = settledSince or os.clock() if os.clock() - settledSince >= GROUND_SETTLE_TIME then break end else settledSince = nil end RunService.Heartbeat:Wait() end end local function guardAgainstFalling(partsData, deathCFrame, stopFlag) for _, data in ipairs(partsData) do task.spawn(function() local part = data.part while part and part.Parent and not stopFlag.stopped do if part.Position.Y < deathCFrame.Position.Y - FALL_SAFETY_DROP then part.AssemblyLinearVelocity = Vector3.zero part.AssemblyAngularVelocity = Vector3.zero part.CFrame = deathCFrame * data.offset end task.wait(0.1) end end) end end local function onCharacterAdded(character) local humanoid = character:WaitForChild("Humanoid") local rootPart = character:WaitForChild("HumanoidRootPart") humanoid.Died:Connect(function() for _, stateType in ipairs(Enum.HumanoidStateType:GetEnumItems()) do if stateType ~= Enum.HumanoidStateType.Physics then pcall(function() humanoid:SetStateEnabled(stateType, false) end) end end humanoid:ChangeState(Enum.HumanoidStateType.Physics) local deathCFrame = rootPart.CFrame local partsData = {} for _, part in ipairs(character:GetDescendants()) do if part:IsA("BasePart") then table.insert(partsData, { part = part, offset = deathCFrame:ToObjectSpace(part.CFrame), }) end end local stopFlag = { stopped = false } guardAgainstFalling(partsData, deathCFrame, stopFlag) local ok, err = pcall(function() for burst = 1, SPAM_REPEAT_COUNT do local currentPos = rootPart and rootPart.Parent and rootPart.Position or deathCFrame.Position local targetRoots = findClosestPlayerRoots(currentPos, MAX_TARGETS) assignTargets(partsData, targetRoots) scatterImpulse(partsData) homeTowardTargets(partsData, deathCFrame.Position, MAX_SETTLE_WAIT) task.wait(SPAM_INTERVAL) end end) if not ok then warn("[RagdollRebuild] error during scatter, recovering safely: " .. tostring(err)) end stopFlag.stopped = true humanoid.Health = humanoid.MaxHealth for _, stateType in ipairs(Enum.HumanoidStateType:GetEnumItems()) do pcall(function() humanoid:SetStateEnabled(stateType, true) end) end end) end if player.Character then onCharacterAdded(player.Character) end player.CharacterAdded:Connect(onCharacterAdded)