Unexpected script behaviour when run in Play mode

I am trying to create a simple fishing rod mechanic where a simple rod swing throws the hook (a little red sphere) in the water. I used a hinge constraint, a rope constraint some parts and a server script for the whole functionality.

While I was working on it trying to figure out the perfect movement to throw the hook as far as possible I kept testing in the “Run” Testing Mode (The green arrow icon) as it was faster and didn’t require any character loading. After I was finished and satisfied by my result I ended up with this:

My problem was that when I tried running them using the usual Test mode, the script wouldn’t behave as expected. The ball gets kind of bugged midair for some reason. Here is a video that shows the difference:

At first I thought it might have been a client/server difference, but soon enough I realized that made no sense since both cases are running on server side (I activate the BoolValue by going on the server side in the second video) . Shouldn’t the script have the same functionality in both cases?

Something else I wanted to include was the fact that in the Output you can see I am printing the HingeConstraint CurrentAngle, and next to it I am printing the Rod.Orientation. When I first noticed the problem (about 3 hours ago) I noticed that in the second case (Play Mode) the CurrentAngle and the Rod.Orientation would vary from the 1st to the 2nd time I threw the rod, even if the rod had the exact same rotation both times.
For some reason when I wanted to record that was not the case anymore, and that was what motivated me to start this topic, but there still is unexpected behaviour that can be seen, and that is the ball’s weird movement.

A snip that shows all of the components used:

image

and the script’s code:

runService = game:GetService("RunService")
tweenService = game:GetService("TweenService")

model = script.Parent

onOff = model.OnOffBool
hingeMotor = model.HingeConstraint
rope = model.RopeConstraint
rod = model.Rod

lowSpeed = 2
highSpeed = 7

currRunService = nil

midair = false

model.HighSpeed.Changed:Connect(function(newVal)
	highSpeed = newVal
end)

model.Hook.Touched:Connect(function(other)
	print(other.Name)
	if other.Name == "Terrain" or other.Name == "Rod" then
		return
	end
	
	--onOff.Value = not onOff.Value
end)

function ropeLength(newLength,deltaTime)
	local ropeTweenInfo = TweenInfo.new(
		deltaTime, -- Time
		Enum.EasingStyle.Linear, -- EasingStyle
		Enum.EasingDirection.Out, -- EasingDirection
		0, -- RepeatCount (when less than zero the tween will loop indefinitely)
		false, -- Reverses (tween will reverse once reaching it's goal)
		0 -- DelayTime
	)
	
	local tween = tweenService:Create(rope, ropeTweenInfo, {Length = newLength})
	tween:Play()
end

nonLongings = 0
longinged = nil
prevLonginged = nil

onOff.Changed:Connect(function(newBool)
	if currRunService ~= nil then
		currRunService:Disconnect()
	end
	if newBool then -- throw the rod
		hingeMotor.AngularSpeed = highSpeed*1.2
		hingeMotor.TargetAngle = 180
		
		currRunService = runService.Heartbeat:Connect(function()
			
			print(hingeMotor.CurrentAngle, rod.Orientation)
			
			if midair then
				prevLonginged = longinged
				
				if rope.CurrentDistance > rope.Length * 80/100 then
					longinged = true
					rope.Length = rope.Length + 0.2* highSpeed
				else
					longinged = false
				end
				
			end
			
			if prevLonginged ~= nil then
				if prevLonginged == false and longinged == false then
					nonLongings = nonLongings + 1
				else
					nonLongings = 0
				end
			end
			--print(nonLongings)
			if hingeMotor.CurrentAngle > 120 and hingeMotor.CurrentAngle < 140 then
				hingeMotor.TargetAngle = -120
				midair = true
				hingeMotor.AngularSpeed = highSpeed + 2
			elseif hingeMotor.CurrentAngle > -170 and hingeMotor.CurrentAngle < -150 then
				hingeMotor.AngularSpeed = highSpeed
			elseif hingeMotor.CurrentAngle > -125 and hingeMotor.CurrentAngle < -120 then
				wait(0.1)
				hingeMotor.AngularSpeed = lowSpeed/2
				hingeMotor.TargetAngle = -150
			end
			
			if nonLongings > 25 then
				currRunService:Disconnect()
				
				local errorPercent = 98
				if rope.Length > 80 then
					errorPercent = 99.7
				elseif rope.Length > 40 then
					errorPercent = 99
				end
				
				currRunService = runService.Heartbeat:Connect(function()
					print("err".. errorPercent)
					if rope.CurrentDistance < rope.Length * (errorPercent)/100 then
						rope.Length = rope.Length - 0.7
					else
						currRunService:Disconnect()
					end
				end)
			end
		end)
	else	-- reel in
		midair = false
		nonLongings = 0
		ropeLength(0.2, 1)
		wait(1)
		hingeMotor.AngularSpeed = lowSpeed
		hingeMotor.TargetAngle = 180
		wait(0.2)
		hingeMotor.TargetAngle = 60
		
		wait(0.5)
		ropeLength(1, 1)
	end
end)

Sorry for the ugly code.

This belongs in #development-support:scripting-support, please transfer it to that area of the Developer Forums (it should be in edit).