An API to determine if the local client/server has network ownership of a part

As a Roblox developer, it is currently too hard to determine whether or not the current client has physics control of a part.

If Roblox is able to address this issue, it would improve my development experience because it would allow my client code to decide if a part is currently able to be controlled.

Currently, there is no way to determine this from the client. From the server this may also be somewhat unreliable due to network delay and other things.

Being able to determine if a part is owned by the local client/local server would be very very useful in physics code because it would allow me to decide when to control the physics of a part locally to prevent desyncing between the client and server.

10 Likes

BasePart:GetNetworkOwner()?

This doesn’t work on the client.

Then they should probably expand it to work on the client then. I’m honestly not sure why it doesn’t.

1 Like

The network ownership APIs are disabled completely on the client. That includes the ones for getting/setting which is what my feature request is asking to be changed or provide an alternative to.

There is also probably some reason that the network owner can’t be known by the client, the client probably just knows “yes I can control this” or “no I can’t control this” so BasePart:HasNetworkOwnership() would probably be an easier feature than making BasePart:GetNetworkOwner() work which is why I titled it the way I did, but, that’s not the only way this problem could be solved.

1 Like

Why not use built-in physics constraints? Why do you need to write custom physics?

Seems like an anti-pattern to me.

Because I’m not using constraint-like behaviour, the physics I’m doing is too complex to represent with some constraints. For one, I’m actively changing the speed of physics and that’s not something you can do with constraints. I’m also adjusting the physics behavior of certain specific objects in more complex ways than what I could feasibly represent with constraints without a ton of attachments sitting in every single part in the entire game, that’s just not going to happen.

I doubt I could even represent this sort of stuff with constraints since constraints are, well, constraints, and, my goal isn’t to manipulate objects within the physics engine my goal is to add new features to the physics engine that don’t already exist.

And, even with constraints, it still doesn’t fix the issue I’m running into, I want to know when the client is able to control some objects, particularly automatically owned objects. The client knows whether or not another client is already doing physics stuff.

My own use case is not really perfectly representative of why this feature is useful either. There are a lot of times where you’d want to know if the local client has control of something. For example, for vehicles, if the client isn’t the one controlling the physics there are certain things you wouldn’t want to do that you might generally do locally.

A lot of vehicles, including the endorsed models on the Toolbox iirc do some physics or animation related stuff client sided and you usually don’t want to do that stuff when the vehicle isn’t owned, being able to know if the client has physics control would make it a lot less hacky to prevent duplicated physics without having to wait for various data to go through.

A lot of stuff is throttled differently when it comes to networking so not every piece of data tells you if you’ve received another piece of data from the same time, you can’t for example rely on a remote call to know if the network ownership info is up to date.

With my current code that results in things that were previously owned by the server simulating without any physics changes for a good second or two until my remote call goes through to tell the client that the parts are owned by them now.

2 Likes

I’m not too entirely sure why you would want to get the network owner of a part on the client, but the best workaround for this that I can think of is to use attributes on the part you wish to access the network owner.


Server
local RunService = game:GetService("RunService")

local Heartbeat = RunService.Heartbeat

local part = workspace.Part

while true do
	local networkOwner = part:GetNetworkOwner()
	networkOwner = networkOwner and networkOwner.Name or nil
	
	if not (part:GetAttribute("NetworkOwner") == networkOwner) then
		print(string.format("Setting Attribute NetworkOwner to %s", networkOwner or "the server"))
		part:SetAttribute("NetworkOwner", networkOwner)
	end
	
	Heartbeat:Wait()
end

Client
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local Heartbeat = RunService.Heartbeat

local part = workspace.Part

part:GetAttributeChangedSignal("NetworkOwner"):Connect(function()
	local networkOwner = part:GetAttribute("NetworkOwner")
	networkOwner = networkOwner and Players:FindFirstChild(networkOwner)
	
	print(string.format("New NetworkOwner of %s is now %s", part.Name, networkOwner and networkOwner.Name or "the server"))
end)

Note: This makes me think that there should be an event for BasePart.NetworkOwnerChanged :sweat_smile: