"Soft" Network Ownership

Feature request credits to @POOPENGUIN

Originally posted in #development-discussion:
https://devforum.roblox.com/t/soft-network-ownership/2672493?u=optimizedfunction

I do endorse the feature request and would love to see it implemented!

As a roblox developer, it is currently difficult to manage physics assemblies that must interact with multiple players.

For example: Suppose there is a jeep with a gun on it. The gun is a separate seat from the driver’s seat, and is handled via physics constraints. physics ownership is assigned to the driver, while say, a gunner controls a turret. Because ownership is given to the driver, the player on the gunner seat will experience very heavy latency when they try to aim the gun because the gun’s physics is controlled by the driver. The current solution is to bypass the physics engine entirely and have the gun be mounted with welds or motor6Ds, as those can be set locally. The result is instant movement on the gun with no weight or momentum, unless the developer spends extra time manually adding those in.

This problem has been universal in roblox for a long time, as any game using physics will occasionally hit the player with an unmovable door that some other player touched a split second ago, or trample the player with an object that is being controlled by someone with a high ping.

I’ve always known this problem, and most devs work around it by simply avoiding the physics engine while keeping in mind best practices.

However, I’ve recently hit a pretty big roadblock when working with physics-based NPCs.

Normally, if an NPC needs to play an animation from say, getting shot by a gun, the client who fired the shot can locally play an animation while also sending the server the message so that all other players can also play the animation.

However, if your NPC’s animations are handled by physics, (such as with active ragdolls), there is no way to locally manipulate the NPC’s physics to reflect getting shot at.

This means the signal must travel from the client who fired the shot to the server, to the player who owns the NPC, back to the server, and then back to the client, which is pretty unacceptable.

Below is an example of how bad this feels with 0.1s of replication lag

You might ask: why not have all clients make local copies of NPCs, who can then be locally animated and then synchronized? I’ve thought of this, but the network bandwidth required to synchronize them would be massive, not to mention that physics in roblox is generally non-deterministic, especially in such a chaotic system as an active ragdoll, so NPCs would regularly stumble in many different directions on each player’s screens, causing huge desync.

Bandwidth of course, is also why my NPCs are owned by the client and not the server, as at least the network owner only needs to recieve physics bandwidth from other player’s NPCs, as opposed to ALL the NPCs.

Proposed solution:
I read about this method while researching for solutions and have no idea what it’s actually called, so I’ll just call it “Soft” Network Ownership

Instead of completely blocking physics changes from non-network owners, allow non network owner clients to locally make physics changes to parts they don’t own. No data is sent to the server based on these local changes, and instead, the client continues to listen for physics updates from the part’s real owner while nudging it’s own local position back to the real position.

My quick and dirty implementation of this:
I have set up a two player demo for this system. One player owns all the parts in the server. When the other player tries to move anything, it is horrendously laggy, shown below:

However, in the iteration below, I have the other player (player 2) create duplicates of all the parts that the first player owns. these new parts are all now locally owned by player 2. the original parts are set to be invisible and untouchable, and the new local part and original part are connected via AlignPosition and AlignOrientation. (you can see the original part with 0.5 transparency in the clip)

The result is that even though player 2 does not own anything, their client is still allowed to move parts without waiting for a response from the server, and silently nudges them to their actual position. The synchronization isn’t perfect of course, but it far surpasses the default behavior ESPECIALLY for the door.

Importantly, these local parts also do not affect the owner or the actual part’s positions, as the Align Constraints have Attachment1 set to the original part and reaction force is turned off. Not to mention player 2 doesn’t have network ownership anyway.

Place file can be found here:
Soft Network Ownership.rbxl (60.8 KB)

This seems like a very important feature that should be at least activatable via API call or something, because it feels like many physics-based game ideas might not be possible or at least be very difficult to implement in roblox.

Anyways thanks for reading.

36 Likes

From what I’m getting this is client prediction? Where the client locally “predicts” future server state, whilst correcting for desync from the server whenever it gets the chance. Built-in client prediction and more broadly some tools to manipulate replication and send unreliable remotes are much needed. I know that last one is already in the works.

3 Likes

I was thinking about exactly this. Some kind of completely non-replicated ownership would be very useful too. For instance, creating a physics interactable I only want to be locally simulated, without needing to clone on the client.

This is a major issue we have to work around as well. You can’t weld things (locally) to assemblies owned by the server, so even if you wanted to simulate the turret locally with constraints on each client - you can’t.

We pretty much avoid using physics unless 100% necessary due to all of the issues with ownership, streaming and stability. Custom Motor6D solutions are the best right now, and you have to implement your own damping/smoothness :confused:

1 Like