R15 ragdolling not working correctly

(FYI this started happening recently, this is not a bug w/the module).

Issue Type: Other
Impact: High
Frequency: Often
Date First Experienced: 2021-03-01 00:03:00 (-05:00)
Date Last Experienced: 2021-03-04 17:03:00 (-05:00)

Reproduction Steps:
I’m using a forked version of EchoReaper’s R15 ragdoll module. Models are owned by the client/created on the client (No server involvement).

  1. Join the test place file (Staff please DM me for a copy, it’s a private place).
  2. Run over one of the NPCs (The one named ‘Genius’ does it all the time).
  3. Observe how the lower torso/limbs fly towards the avatar after the character has been rag dolled.

Expected Behavior:
The NPC should ragdoll and fly across the map (Depending on velocity).

Actual Behavior:
The NPC’s limbs stick in place, then fly over. I suspect this is related to the motors update/upcoming motors update.

Workaround:
Only workaround is setting the player’s character to platform stand (Which causes the limbs to clip through the ground, which is undesirable behavior).

3 Likes

Does your ragdoll system use any of these?

I’m not completely experienced with Roblox physics, but I do know that some particular creations required attention after Roblox made these updates. Maybe this will help you.

1 Like

Ball socket/hinges. I think it’s motor responsiveness (Because it’s a motor w/some of the parts in the humanoid by default). But the weird part is actuator type isn’t set to anything besides none.

I’m glad I gave you some hints on where to start!

1 Like

BallSocketConstraints only seperate and try to reach eachother if one of the parts is anchored. Since a humanoid is not a physics object, and is instead completely isolated from everything else, it is treaded like an anchored part.

If you want to make a solid ragdoll, set the humanoid to platform standing, create pseudo limbs, weld them to the real limbs, and set them to their own collision group.

I dont expect this behavior will be changed, because humanoids probably wont be around much longer.

I saw a few posts in the last couple of days that said that BodyGyros are having issues if they are set to power levels of ‘inf’. If the power is set to a value slightly less than ‘inf’ the BodyGyros go back to their previous operation.
Dunno if this affects you, but I know others with ragdoll scripts were having sudden issues since the update.

1 Like

BallSocketConstraints don’t have to work with an Anchored Attachment on one end. I’ve got them on Vehicles and they work just fine there.

I’m just saying that the separating + slowly reforming behavior only occurs when one of the attachments of the HingeConstraint is parented to an anchored part, or in this case, a humanoid that isnt set to PlatformStanding or a physics state.

The state of the humanoid is set to physics. It also seems to only occur w/certain characters v. others.

I found a reply of his in the module post, where he says:

Perhaps the physics state isnt exactly true to its name. I’ve never had a problem with platform standing, but the physics state I am not super familiar with.

I would say that “un-ending platformstand” is misleading in the first place, because animations still play by default. Who knows what other behavior isnt the same.

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.

4 Likes

Servo Motor Responsiveness feature has not been yet released even for testing, and it seems unlikely that this has to do with the universal constraint as well.

3 Likes

Looks like some dramatic positional correction happening.

Constraints mostly work to keep the attachments aligned by constraining velocities. We don’t use velocity to fix misalignment. If they do get out of alignment they are slowly corrected by positional correction. Positional correction has very conservative limits on how much it can move things each frame, hence the character slowly snapping back together.

I attempted to explain positional correction in a little more detail before here:

So the interesting question is how are the parts getting separated in the first place?

The easiest way this could happen is an ownership transfer or delay in ownership assignment.

It’s really important that network ownership stays consistent once ragdoll is initiated. It should be initiated by and stay simulated by the same network owner, whether that is the client or the server. Ideally this is the same network owner that was simulating the character before it went ragdoll to eliminate hitches on their end too.

This kind of issue could be kind of sporadic and depend on the round trip time to the affected client too…

I would try setting Incoming Replication Lag in Studio network settings to something like 0.3, enable Are Owners Shown under Physics and do a similar test in Start Server / Start Player. If you ever see ownership flickering on the characters on ragdoll switches at all, this is probably the issue.

Happy to look at the place, but this is the first thing it usually takes me few days to get time to do it… You might want to take a look yourself first. Still would like to look eventually, especially if this is not the issue…

There’s several common mistakes most ragdoll modules make that might cause this:

  • Destroying the root joint. This splits the ragdoll off as a separate network ownership, and the client needs to wait for the server to assign ownership before it will simulate. This can cause causes hitches and other discontinuities. EchoReaper’s module gets this right.
  • Disabling the Motor6Ds from the server. Limbs get split off, but physics replication from the client doesn’t come in for those parts until at least later. To prevent any hitches and discontinuities in physics the network owner (the client for player characters) of the character should be the first one to disable the Motor6Ds, so they start simulating and sending physics data at the same time at the moment they ragdoll. Once the server confirms ragdoll was initiated replicated physics data for the rest of the ragdoll has already arrived. As seamless as possible to all observers.
  • Waiting to rig the character for ragdoll on demand. Following above, if client should predicatively break Motor6Ds and notify the server that it initiated ragdoll to broadcast the Motor6D break, it needs to stay a single network ownership unit on the client, and the constraints must already exist on the client before those motors are broken, or the parts will be frozen on the client until the constraints are received and ownership is assigned. You can either create a set of constraints on the client and delete it when the server set comes… Or just rig the character for ragdoll on spawn. Way easier.

Some of the comments here might be interesting:

Especially the player side script.

This is a sligtly outdated version of the ragdoll scripts I wrote for our built-in ragdoll death used by default in China. I spent a lot of time focusing on eliminating network ownership and latency related hitches and discontinuities here.

7 Likes

Sure enough I’ve been disabling the root joint because the physics state doesn’t behave correctly. I think this explains the issue - thank you very much for the in-depth details/solutions!

Only thing I can think of is that these ragdolls are being generated on the client v. the server, and always stay on the client. Not sure how network ownership would be an issue here.

Hopefully it’s helpful! Usually getting things working on Roblox is relatively straightforward, but sometimes polishing them requires some knowledge that’s not as well documented as it could be…

Network ownership is a hidden property assigned by the server. When network ownership changes there’s effectively a pause in simulation of that body, with a duration depending on frame rates and network round trip times, between when the server stops simulating or accepting physics updates from the old owner and when the new owner starts simulating it and sending physics updates.

Every time you create a new network ownership unit or fracture one off from another on the server that is immediately assigned to the client there can be a hitch like this where the parts can appear frozen for an instant from the server and other player’s perspectives, or even to go back in time slightly from the perspective of the owner.

We could possibly do more to try to smooth this out and paper over the fundamentally unavoidable discontinuity, but dealing with multiple timelines that from your perspective are all offset differently is an intrinsic problem of client-server programming. I’m sure you’re well aware of that already! Everything you receive from the client being delayed by some provably unknowable duration, but is now a reaction to a state of the world that is stale by the known full round trip time from the server’s perspective anyway… Perfect is impossible, it’s all about making the right tradeoffs…

Easiest way to avoid this is to make sure network ownership stays consistent and minimize unnecessary ownership reassignment or being deliberate about the timing of the transfers. Keeping the root joint helps with this. The network ownership unit root part of the character doesn’t change when it goes ragdoll and no ownership reassignment is needed.

2 Likes