BodyPosition created dynamically seems to have trouble initializing

Since this won’t be technically resolved, I’m gonna make a tldr.

The bug is that having a BodyPosition on a part with multiple Bodymovers might break if the engines random initialization order decides to initialize BodyPosition first. You can get around it by adding the other Bodymovers first, but you’ll probably have a better time just migrating to the newer constraints (AlignPosition, AlignOrientation, etc…)

original bug report below

A BodyPosition bug has appeared, breaking old existing logic.
A newly created one given to a client object seems to struggle to initialize now. It almost seems like the part is asleep and refusing to listen to the bodyposition until it gets woken up, then it works as expected. This issue does not happen consistently. Here’s a video of the issue.

Just for extra info, here’s what it looks like when it doesn’t break

Again, absolutely random when this occurs now. Issue must have occurred sometime in the past 2 weeks from now.

Additional info:
streaming is disabled
signal behaviour: deferred
physics stepping method: adaptive
reject character deletions: enabled

Addendum:
Managed to repro an issue happening in an empty baseplate. I’m unsure if this is related, but I thought I would mention it.,

You can see it somehow just deletes itself when you run it. If you were to force both numbers to be exactly the same, the issue no longer occurs.

Addendum 2:
Somehow a bodyvelocity doing nothing makes the bodyposition move upward infinitely even though it needs to move downwards?

2 Likes

bodymovers have been deprecated so i don’t think it will be fixed, though as you mentioned it’s logic that used to work before and was randomly broken so there’s a slim chance they could actually fix this.

Deprecated only means that it won’t get significant new work to support new features. Regressions will obviously still be fixed, legacy bodymovers are still the backbone of thousands of games.

3 Likes

Okay so what exactly is the repro you’re doing in the empty baseplate? I don’t understand what you mean “deletes itself”. Is the placefile actually just an empty placefile or do you have other bits added?

Could you try dm’ing me with exact steps to follow and upload an associated placefile for me to look at?

1 Like

Here’s some more details:
First I have a part with a bodyposition, bodyvelocity, and bodygyro. The client copies a version of this part in workspace and tries to update some logic accordingly. For some reason the bodyposition specifically sometimes doesn’t seem to be doing anything right away until it gets moved around a bit, sometimes it freaks out really hard for a frame. Reminds me a bit of how physics objects can sleep to avoid constant updates.

For the baseplate, I tried to recreate the scenario, 1 part with all the bodymovers attached. I THINK I’m recreating the same bug, but I’m not super sure. Here’s a repro place and a video of me just hitting play.

BodyMoversLosingControl.rbxl (57.6 KB)

Here’s a video of it randomly snapping into the correct position after hitting play several times

1 Like

Hi @aaron_mccoy In you initial post you said a newly created BodyPosition was the cause of your problem. I see that the humanoid root part also has a BodyGyro and BodyVelocity mover on it. Did you all 3 movers together or did you add just 1 BodyPosition onto the already existing BodyGyro and BodyVelocity movers?

Thanks

A script creates the part and the bodymovers, parents the the bodymovers to the part, then parents the final part to workspace all in the same frame.

Sorry if my original wording was unclear, that’s why I tried to do a follow up post with more specifics

Thanks for the placefile! Debugging into it now.

So I have no clue what may have caused behavior to actually change, however, I do think I see both a temporary workaround you can apply right now, and I see a likely way to eliminate this kind of bug.

For now let’s try applying a workaround to your game. In a server script I ran print(table.unpack(workspace:WaitForChild("Part"):GetChildren())) to look at the order of children under the buggy part. Thanks again for the helpful repro! Here are possible orderings that can get printed depending on the order of which children were added:

OK
BodyVelocity BodyGyro BodyPosition
BodyVelocity BodyPosition BodyGyro

OK
BodyGyro BodyVelocity BodyPosition
BodyGyro BodyPosition BodyVelocity

BAD
BodyPosition BodyVelocity BodyGyro
BodyPosition BodyGyro BodyVelocity

I noticed the bug occurs if BodyPosition is added first. As a workaround can you try adjusting the order of placement, making sure BodyPosition is not added as the first child?

Otherwise I’m going to start working on the potential fix I mentioned earlier, which will take time to implement and verify.

Edit: Actually, I still see buggy behavior in various orderings… But, still better.

1 Like

Okay, after some more investigating I’ve narrowed down the cause. Unfortunately, you really shouldn’t be using BodyVelocity and BodyPosition together. With the way things are currently implemented it’s feeding two different constraints into the physics solver, and depending on the order the first one solved will get invalidated by the second. This leads to undefined behavior from the system being so overconstrained.

I noticed if you just get rid of the BodyVelocity things seem to work pretty well. Can I ask what you intend for the BodyVelocity? You’re just trying to drive velocity down to 0 to prevent oscillations, right? If you use AlignPosition instead and achieve a nice smooth behavior.

As for “why did this work before”, unfortunately it wasn’t intended to work like this. Using BodyVelocity and BodyPosition together is ultimately undefined behavior. Perhaps with very old implementations of the BodyMovers (as in prior to the 2015 solver update) it was possible to get some consistent results, but since the move to the new solver your setup post 2015 this is just not a valid setup, which explains the order-dependent behavior. Order of initialization can change in the engine for a variety of reasons totally unrelated to physics, so it’s just unfortunate your exact setup has broken here. It’s not feasible to search the engine for exactly what’s changed, so at this point the only option is to recommend you either move off of the old deprecated BodyMovers (this page has some note on migrating), or don’t use BodyVelocity and BodyPosition together.

I find it very strange that it only works from unintended behaviour because I’ve been using this setup since I’ve started on Roblox in 2020, and I’ve never had any issues with this until just a ~week ago. BodyPosition on only the y-axis and BodyVelocity on the xz-axis, then sometimes I disable BodyPosition and let BodyVelocity have access to all axis when you’re falling/jumping.

Regardless, I’ve swapped to the newer constraints since I posted the bug report and I don’t have any issues anymore.

Yeah, it is strange, but expected from my PoV after reading more into the code – lots of other parts of the engine can change and affect initialization/solver ordering for siblings, since that’s not intended to have order-dependent behavior. It’s impossible for me to track exactly what changed ordering for you.

It is important to move off of deprecated pieces though, since they are at-risk over time of technical decay. Sorry it caused you some inconvenience!

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