Player doesn't move with a weld on the server

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I want to make a chair that will rock back and forth when you sit on it.

  1. What is the issue? Include screenshots / videos if possible!

It works fine on the client but on the server, the player doesn’t rock with the chair, they just sit still.

Client:
https://gyazo.com/42eb48dd657231a9838137a9423c35bd

Server:
https://gyazo.com/68ba59616447a5e9a3b4cec745bc3182

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve tried using a heartbeat function and setting the player’s position to the seat, but I’d have to anchor them for it to work, and I can’t do that because they wouldn’t be able to stop sitting by pressing space. Also, I couldn’t find anything on the dev forum related to my issue.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Here is my script, its a server script in ServerScriptService

-- Services
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
-- Instances

-- Variables
local seats = workspace:FindFirstChild("RockingChairs") -- Grabs the rocking chair folder in workspace

local returnTime = 0.5
local rotate = 15
local rockTime = 1
local cooldownTime = 1
-- Functions

local function rockingChair(chair)
	local seat = chair:FindFirstChild("Seat") -- Finds a part named seat in the chair
	local normalOrientation = chair.Orientation -- Grabs the default Orientation of the chair
	print(seat)
	print(chair)
	print(normalOrientation)
	if seat then -- Checks if the seat exists
		local seatOrientation = seat.Orientation -- Grabs the default orientation of the seat
		local cooldowned = {} -- Makes a table for cooldowned people for this chair
		seat.Touched:Connect(function(hit) -- Makes a touched event for the seat
			if hit and hit.Parent then -- Checks if hit exists and if they have a parent
				local char = hit.Parent -- Put the hit.Parent in a variable
				if char:FindFirstChild("Humanoid") ~= nil then -- Checks if the target has a humanoid, thus checking if it is a player/npc
					if cooldowned[char] ~= true then -- Checks if they arent cooldowned
						cooldowned[char] = true -- Cooldowns them
						local Humanoid = char.Humanoid -- Variable stuff for orginization
						local Root = char.PrimaryPart -- Grabs the players HumanoidRootPart
						local refSize = char:GetExtentsSize() -- Grabs the extents of the player
						local RootCFrame = seat.CFrame + seat.CFrame.upVector * (refSize.Y/4 -seat.Size.Y/2) -- Sets the cframe at which the player will be
						local stop = false -- Holder variable to check if the script should stop
						Humanoid.Sit = true -- Makes the player sit
						print(char)
						Root.CFrame = RootCFrame -- Sets the players cframe to the previous cframe
						local weld = Instance.new("Weld") -- Makes a weld
						weld.Part0 = seat -- Sets the weld's first part to the seat
						weld.Part1 = Root -- Sets the weld's second part to the HumanoidRootPart
						weld.C0 = seat.CFrame:Inverse() -- CFrame stuff
						weld.C1 = RootCFrame:Inverse() -- CFrame stuff
						weld.Parent = seat -- Sets the welds parent to the seat
						
						changedFunc = Humanoid.Changed:Connect(function() -- Sets up a changed function on the humanoid
							if Humanoid.Health <= 0 or not Humanoid.Sit	then -- Checks if the player is dead or is no longer sitting
								changedFunc:Disconnect() -- Disconnects the changed function
								weld:Destroy() -- Destroys the weld
								stop = true -- Sets the stop variable to true
								
								local function reset(item,value)
									local tween = TweenService:Create(item,TweenInfo.new(rockTime),{Orientation = value}) -- Sets up a tween for the given object to tween to the given value
									tween:Play() -- Plays the tween
								end
								reset(chair,normalOrientation) -- Runs the function for the chair
								reset(seat,seatOrientation) -- Runs the function for the seat
								delay(cooldownTime,function() -- Sets up a delay for the cooldown time
									cooldowned[char] = false -- Sets the player in the cooldown array to false, allowing them to sit down again
									print(tostring(char.Name) .. " can now sit down again.") 
								end)
							end
						end)
						local function rock(item,value)
							local tween = TweenService:Create(item,TweenInfo.new(rockTime,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,true,0),{Orientation = item.Orientation + Vector3.new(value,0,0)}) -- Rocks the given object to a certain degree using the values back and then returns the object back to the previous position
							tween:Play() -- Plays the tween
						end
						while not stop do -- Makes a loop that will stop when the stop variable is true
							rock(chair,rotate) -- Runs the function for the chair
							rock(seat,-rotate) -- Runs the function for the seat
							wait(rockTime*2) -- Waits for the given time
							if stop then break end -- Checks if stop is true, if it is then it breaks the loop
							rock(chair,-rotate) -- Runs the function for the seat
							rock(seat,rotate) -- Runs the function for the seat
							wait(rockTime*2) -- Waits for the given time
						end
					end
				end
			end
		end)
	end
end

for i,v in pairs(CollectionService:GetTagged("rockingChair")) do -- Grabs everything with the "rockingChair" tag
	if v:IsA("BasePart") then -- Checks if the item is a part
		rockingChair(v) -- Runs the function for rocking chairs
	end
end

if seats then -- Checks if the folder exists
	for i,v in pairs(seats:GetChildren()) do -- Loops through every item in the folder
		if v:IsA("BasePart") then -- Checks if the item is a part
			CollectionService:AddTag(v,"rockingChair") -- Adds the tag to the item
			rockingChair(v) -- Runs the function for rocking chairs
		end
	end
end

Any help would be appreciated, thanks in advance!