Problems with network ownership lag

heya! I’m using this dragging system i found in the toolbox and found that it works great! one problem is that the items lag when i drop them. I believe the culprit is when the item drops, it switches it’s network owner. how can i combat the little bit of lag?
https://i.gyazo.com/e5eb0e4023a7b379cfbb79d466888e9c

I’m going to assume the part’s network ownership was not set.

Given this, network ownership doesn’t change to the server unless you set the part’s network ownership to nil.

To visualise and test this, you can go to File>Studio Settings>Network and inside the Network tab, find the Display section and tick the following:

  • Are Owners Shown
  • Are Regions Shown

Then play test the game, if the color does not change back to white color(server) when you drop the part then you still have full control over the part.

If this is true then that means the root cause is probably elsewhere. (Most likely the local script you took from the toolbox)

Or it could be because it is recalculating the physics for the part since you are positioning it at a different place.

However you should take this with a grain of salt as I’m not sure if it’s due to the script, the physics calculation or the network ownership.

In the case it does revert back to server network ownership then you should probably just leave it. The reason is because of exploiters.

Let me know if this worked or not. :smiling_face_with_three_hearts:

the part’s network ownership is set to the player once picked up and set to nil once dropped.

Then the problem lies within the script itself.
Try to find the line of code in the script where it switches the ownership back to the server and just simply removing it.
SetNetworkOwner(nil) --wherever this may be

If it does not exist then try manually setting the network ownership to yourself.
SetNetworkOwner(yourName);

As I’ve said earlier if this does not work as well then the issue is elsewhere.
It’s a bit difficult to debug this problem without actually seeing the code itself.

yup, it removes the lag when i remove the SetNetworkOwner(nil)
but how shall i switch it back without the lag?

A very simple fix is to just wait for a few seconds
here is an example

task.wait(2) -- waits 2 seconds
SetNetworkOwner(nil)

However this only applies after 2 seconds meaning no one can access it within those 2 seconds.

Another way of doing it would be to check if that part has stopped moving
Here is an example

if math.floor(part.Velocity.Magnitude) == 0 then 
    SetNetworkOwner(nil)
end

I will mention that this might not work because when you are dragging the part, sometimes the user might not move it, therefore triggering the above if statement.

So to fix this, it would be to add another check

if math.floor(part.Velocity.Magnitude) == 0 and not isDragging then 
    SetNetworkOwner(nil)
end

Now I’m not entirely sure if there is a boolean that checks if the user is grabbing the part. But in case there isn’t, try to use the key that is used to grab the object and when releasing that key it will activate the if statement.
Just like this:

-- make sure we have UserInputService first
local UserInputService = game:GetService("UserInputService");

-- This function checks whenever a key has been released
UserInputService.InputEnded:Connect(function(input, gameProcessed)
	-- checks if the Left Click has been released
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		-- check if the part has stopped moving
		if math.floor(part.Velocity.Magnitude) == 0 then 
			SetNetworkOwner(nil)
		end
	end
end

Now to finish off, this still might not work. Because it only runs once after the user has stopped pressing the key.
To fix this, create a function and call it every frame in run service then removing it after its done.

local RunService = game:GetService("RunService");
local UserInputService = game:GetService("UserInputService");

local currOwnership = nil;

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		currOwnership = user;
	end
end

local function changeNetworkOwnership()
	if math.floor(part.Velocity.Magnitude) == 0 then 
		SetNetworkOwner(nil);
		currOwnership = nil;
	end
end

RunService.HeartBeat:Connect(function()
	if currOwnership ~= nil then
		changeNetworkOwnership();
	end
end)
1 Like

I simplified the code a bit more without using the function

local RunService = game:GetService("RunService");
local UserInputService = game:GetService("UserInputService");

local holdingKey = false;

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		holdingKey = true;
	end
end

RunService.HeartBeat:Connect(function()
	if math.floor(part.Velocity.Magnitude) == 0 and holdingKey == true then 
		SetNetworkOwner(nil);
		currOwnership = false;
	end
end)

great solution, but has some kinks i found while testing today. if an object is round and rolls, the player will remain in control. good for single player, bad for multi. another thing is it is a little unreliable.

To be honest it’s hard to find a good switching point after you release the part because as you’ve said it will roll, it might take time for the part to settle, etc… There isn’t really a good balance.

Unless you want to try doing it all on the server side so when the player picks it up, it sends that information to the server then sending it back to the client. However this will of course cause some noticable delay on the client’s side when dragging the part.

I tried my best to help counter this issue but it seems quite difficult to really get a smooth transition between the client and the server.

1 Like