Run testing isn't the same as Play Testing

I was creating a small little ball bouncing simulation (using Roblox linevelocity), and I based my bug fixes and optimization on Run tests, then when I implemented a player joining the game the physics entirely changed, the ball now doesn’t reach the wall in time, and it stops for a second before continuing its path.

Before:

After:

Any advice?

Code:

local RunService = game:GetService("RunService")

local Ball = workspace.Balls.Ball

task.wait(5)

repeat
	task.wait()
until game.Players:FindFirstChildWhichIsA("Player") ~= nil or game:GetService("RunService"):IsStudio() == true

Ball.Anchored = false

local LastHitWall = Ball

local LastPosition = Ball.Position

Ball:SetNetworkOwner(nil)

while true do
	
	local RayOr = LastPosition
	local RayDir = Ball.CFrame.LookVector * 1000
	local RayPar = RaycastParams.new()
	RayPar.FilterType = Enum.RaycastFilterType.Exclude
	
	RayPar.FilterDescendantsInstances = {Ball, workspace.Players, LastHitWall}
	
	local RayCast : RaycastResult = workspace:Raycast(RayOr,RayDir,RayPar)
	
	local Hit = RayCast.Position
	local Normal = RayCast.Normal
	local Distance = RayCast.Distance
	
	local Speed = Ball.Movement.LinearVelocity.LineVelocity
	
	local CurrentPos = Ball.Position
	
	local Time = Distance/Speed
	
	LastHitWall = RayCast.Instance
	LastPosition = RayCast.Position
	
	task.wait(Time)

	local W
	
	local function NBounce()

		local X = Ball.Orientation.X
		local Z = Ball.Orientation.Z
		local zADD


		if math.abs(1-Hit.Y) <= 0.01 then
			W = "Floor"
		elseif Hit.Y >= 24 then
			W = "Top"
		elseif Hit.X < 0 then
			W = "Left"
		elseif Hit.X > 0 then
			W = "Right"
		end

		if W == "Top" or W == "Floor" then
			X *= -1
		else
			if (X >= 0 and W == "Right") or (X < 0 and W == "Left") then
				zADD = 180 + math.abs((X*2))
			else
				zADD = 180 - math.abs((X*2))
			end
		end

		if zADD then
			Ball.CFrame = Ball.CFrame * CFrame.Angles(math.rad(zADD),0,0)
		else
			Ball.Orientation = Vector3.new(X, Ball.Orientation.Y, Z)
		end
	end
	
	NBounce()
	
	Ball.Position = Hit
	
	if W == "Top" then
		Ball.Smok.a.Rotation = NumberRange.new(0)
	elseif W == "Floor" then
		Ball.Smok.a.Rotation = NumberRange.new(180)
	elseif W == "Left" then
		Ball.Smok.a.Rotation = NumberRange.new(90)
	else
		Ball.Smok.a.Rotation = NumberRange.new(-90)
	end
	
	Ball.Smok.a:Emit(1)
	
	task.spawn(function()
		local FX = Ball.Bounce:Clone()
		FX.Parent = workspace
		FX:Play()
		FX.Ended:Once(function()
			FX:Destroy()
		end)
	end)
	
	Ball.AssemblyLinearVelocity = Vector3.new(0,0,0)
end
2 Likes

Try setting the NetworkOwnership (with :SetNetworkOwner()) to nil on the ball (or a primarypart if it has one)

1 Like

probably because client and server work differently

I tried doing this (@yoshicoolTV too), I forgot to send the code, here it is:

local RunService = game:GetService("RunService")

local Ball = workspace.Balls.Ball

task.wait(5)

repeat
	task.wait()
until game.Players:FindFirstChildWhichIsA("Player") ~= nil or game:GetService("RunService"):IsStudio() == true

Ball.Anchored = false

local LastHitWall = Ball

local LastPosition = Ball.Position

Ball:SetNetworkOwner(nil)

while true do
	
	local RayOr = LastPosition
	local RayDir = Ball.CFrame.LookVector * 1000
	local RayPar = RaycastParams.new()
	RayPar.FilterType = Enum.RaycastFilterType.Exclude
	
	RayPar.FilterDescendantsInstances = {Ball, workspace.Players, LastHitWall}
	
	local RayCast : RaycastResult = workspace:Raycast(RayOr,RayDir,RayPar)
	
	local Hit = RayCast.Position
	local Normal = RayCast.Normal
	local Distance = RayCast.Distance
	
	local Speed = Ball.Movement.LinearVelocity.LineVelocity
	
	local CurrentPos = Ball.Position
	
	local Time = Distance/Speed
	
	LastHitWall = RayCast.Instance
	LastPosition = RayCast.Position
	
	task.wait(Time)

	local W
	
	local function NBounce()

		local X = Ball.Orientation.X
		local Z = Ball.Orientation.Z
		local zADD


		if math.abs(1-Hit.Y) <= 0.01 then
			W = "Floor"
		elseif Hit.Y >= 24 then
			W = "Top"
		elseif Hit.X < 0 then
			W = "Left"
		elseif Hit.X > 0 then
			W = "Right"
		end

		if W == "Top" or W == "Floor" then
			X *= -1
		else
			if (X >= 0 and W == "Right") or (X < 0 and W == "Left") then
				zADD = 180 + math.abs((X*2))
			else
				zADD = 180 - math.abs((X*2))
			end
		end

		if zADD then
			Ball.CFrame = Ball.CFrame * CFrame.Angles(math.rad(zADD),0,0)
		else
			Ball.Orientation = Vector3.new(X, Ball.Orientation.Y, Z)
		end
	end
	
	NBounce()
	
	Ball.Position = Hit
	
	if W == "Top" then
		Ball.Smok.a.Rotation = NumberRange.new(0)
	elseif W == "Floor" then
		Ball.Smok.a.Rotation = NumberRange.new(180)
	elseif W == "Left" then
		Ball.Smok.a.Rotation = NumberRange.new(90)
	else
		Ball.Smok.a.Rotation = NumberRange.new(-90)
	end
	
	Ball.Smok.a:Emit(1)
	
	task.spawn(function()
		local FX = Ball.Bounce:Clone()
		FX.Parent = workspace
		FX:Play()
		FX.Ended:Once(function()
			FX:Destroy()
		end)
	end)
	
	Ball.AssemblyLinearVelocity = Vector3.new(0,0,0)
end
1 Like

try clicking the button that says Current: Client to change your perspective to the server and see what happens

2 Likes

I totally forgot about this feature, it’s 2 entirely different worlds, the server is running as perfect as the first video I sent, it’s an issue with the client side, any ideas on how to fix this?

Can you try testing the game on Roblox and not Roblox Studio? Maybe there is a change too

1 Like

same thing occurs, it’s the same as the client side in studio

1 Like

I dont know how to fix it other than converting it to a local script but that comes with some cons. Ill try to fix it when I can because now I cant Im a little bit busy

2 Likes

I made the ball’s position update on the client, huge help, ty

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.