Server owned bodyposition "adding force" on client, when should be inert

Hi,
I have isolated a bug involving bodypositions and network ownership.

Setup:
Start with a server-owned elevator using a bodyposition. Networkowner is nil.
Have the client de-parent the elevator to hide it (eg: a basic client side visibility system)
Have the client re-parent the elevator to see it again

Expected:
The elevator appears and moves around as before, and the local player can continue to ride it.

What happens:
The elevator appears and moves around as before, except now that it applies ā€˜random’ large forces to the local player that interacts with it, launching them!

Speculation
I think what is going on is the bodyposition gets confused once it has been de-parented and re-parented. The elevator is server owned, and so the local bodyposition should not be doing anything, but for some reason the bodyposition is adding in its own forces.

It is interesting to note if you delete the bodyposition locally, the problem goes away, but this feels like an even bigger hack.

Reproduction file:
BuggyElevator.rbxl (35.5 KB)

Thanks for the report! We’ve filed a ticket to our internal database and we’ll follow up when we have an update for you.

1 Like

What’s going on here is that when you de-parent an Instance from the DataModel it is no longer part of the physics world, it loses all of its physics state.

So, locally reparenting the elevator looks exactly the same as locally inserting an entirely new elevator physics wise as far as the client is concerned.

1 Like

Thanks for having a look.

I appreciate the reply, but are you 100% sure that is all that is going on here?

If I understand you, parenting and deparenting it locally on the client should make it like a brand new elevator, and it shouldn’t move at all because the script that is changing the bodyposition position is on the server.

If I cloned it locally, for example, the elevator would stop moving.

Is this because reparented instances in the client data-model still get replicated property changes from the server?

Can you check if you can still repro this after restarting Studio?

I cannot! You fixed it!
That was fast. Any details on what it was? The gritty details of this system are really useful for me.

1 Like

Heh. So… Funny story. I fixed this in November of 2020, but forgot to turn it on. I need to go through my log of things I shipped in last 8 months to make sure I didn’t miss anything else…

Explanation:

  • When a player observes something the server owns, its seeing that object in the past due to latency and interpolation delay (we have to hold animation back until we have 2 frames to lerp between).
  • BodyPosition properties are not synchornized with physics data/interpolation, so when you modify BodyPosition goal it replicates to clients faster than the physics data is interpolated through.
  • When this happens, and you trigger local simulation (by being on the elevator), you have an object that is being interpolated to a position back in time, but local simulation (due to BodyPosition’s replication) is trying to drag it WAY AWAY by applying massive forces. (If you wrote a script that printed the difference between the elevator and the body position goal, you will see large values on Client, but smaller values on server).
  • Because of this, I have some code that prevents local simulation of objects that I expect to be moved around by someone updating properties every frame.
  • This code had a bug if the object was pulled out of workspace or anchored, and this bug I fixed but forgot to turn on.

Your bug was happening because the local simulation was fighting too much with ā€œtruthā€ data coming from the server because of latency. This isn’t supposed to happen in this specific case because we catch it and prevent local simulation, but in this case some of the operations you were doing were breaking them.

6 Likes

Oh that’s super interesting, especially the detail about local simulation.

If you’re animating the part locally via interpolation (like this), I had assumed that there was no need for the part to participate in the local physics simulation at all?

Is this not the case? I thought all you’d need would be to have ā€œmostly correctā€ position, orientation, and velocities?

1 Like

If you do that, unfortunately it makes the object extremely stiff. A pebble that’s interpolating could cause a train to derail. When objects get close to something you are simulating authoritatively, we trigger ā€œlocal simulationā€ in order to help with some of these discrepancies. So that pebbles don’t derail trains.

There are some cases where its problematic and we try to block local simulation, like in the case you posted a repro with.

2 Likes

Oh, right.
so… Is there a guaranteed/proper way to block local simulation on things? :slight_smile:

In this case, (and many like it!) I explicitly set the network ownership to nil, because I don’t care about what the client wants and just want the object to get simulated on the server with full authority.

1 Like

So there is no official API for this.

Although if you make something with a strong enough constraint (like your elevator) it shouldn’t be an issue even if you have local simulation. Local simulation will never ā€˜override’ the authoritative simulation, its simply to make the interaction between someone’s authoritative items more realistic with the object.

3 Likes

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