Player ragdolls - the floppy state a player's body enters after being killed - have been revamped this month.
They can now collide with all vehicles in the game (trains, cars, boats, helicopters etc), where previously they simply fell through. Issues with ragdolls stretching out unnaturally have also been eliminated. If you ever saw a corpse where the interaction wasn't lined up with the visible ragdoll, that's fixed too.
When a player died, a corpse entity used to spawn that was basically just a pelvis-sized collider, which was physically simulated on the server. The position of that "corpse" would sync with every client.
On the client side, a separate "ragdoll" object would spawn, that was a whole visible person with a full set of physically simulated limbs. That ragdoll was attached to the server-side-simulated corpse basically by a tight spring.
The corpse object controlled the actual loot interaction.
Essentially the intention was:
- Let the client do the work of simulating a whole body. We don't really
care how their arms and legs are positioned, on the server. If it's different between clients, also don't care.
- Keep the loot interaction consistent between clients by simulating just that part on the server.
- Keep the (client-side) ragdoll and the (server-side) corpse together with the spring.
In reality, things were not perfect:
- If a player died somewhere like the top of a wall, the corpse might fall down but not the ragdoll, or vice versa. Since the collision setup was quite different between (server-side) corpse and (client-side) ragdoll - only the pelvis area matched - this was relatively common. The result would be a mismatched position between corpse and ragdoll, sometimes putting the interaction in a strange place.
- The client-side ragdoll joints really did not like working with the pelvis position data that was coming from the server. If movement was sudden, rather than just ending up in the wrong place, the ragdoll would sometimes stretch out unnaturally.
- If a ragdoll was on a moving vehicle, things were especially bad, to the point that we couldn't enable ragdoll collision with vehicles at all. Things would happen like a ragdoll dangling under a scrap heli because it had fallen out but the "corpse" hadn't.
This was exacerbated by the fact that the client-side ragdoll physics simulation didn't work well with the fact that the vehicle was being moved on the server, rather than simulating on the client like the ragdoll was. Although the physics did work, they acted like the surface had zero friction, so the ragdoll would tend to slide around while the server-side corpse wanted to stay put - and the spring kept trying keep them together.
I also discovered a bug where if a player entered a network area where a ragdoll was parented to something else, it would tend to stretch out wildly. I think that one was causing a lot of the ragdoll issues seen on the Cargo Ship.
My first instinct for the simplest fix was to try just locking the ragdoll to the corpse, rather than using a spring. That would force them to stay together.
Unfortunately locking the pelvis to a position that was coming from the server, whilst simulating all the connected joints on the client, made the physics system very unhappy. Trying Unity tricks like using 'rigidbody.MovePosition' versus '.position', projection on or off, more solver iterations etc didn't really help. The limbs would really want to stay where they were while the pelvis pulled them around, and you'd just end up with a horrifying stretched-out ragdoll instead of one that was simply in the wrong place. Plus the limbs still had some of the old problems, like the zero-friction-on-vehicles issue.
The pelvis also didn't always simulate well for a full body, since it didn't have any of the connected torso/legs/arms/head, so it'd try to go places the full body didn't want to go. The spring allowed for that kind of leeway, but a fixed connection didn't.
So ragdoll-on-vehicle support was going to require either writing a custom physics solution for simulating the limbs on the client plus making something better for the pelvis simulation on the server side, or moving the whole ragdoll simulation to the server.
Ultimately the custom physics solution was going to require most of the same work that a fully server-simulated ragdoll was, on top of being difficult to code on my own in a way that came out superior to what Unity has already managed with 7,700 employees. So server-side ragdolls was the winner.
The new ragdolls work like this:
- A corpse spawns on the server, and that corpse is a fully simulated ragdoll with limbs etc.
- The base position of that corpse syncs to the client like it did before, but now the limbs also sync, in an efficient way that's packed into a couple of 32-bit integers.
- The client no longer has a ragdoll object that's separate from the corpse. The corpse is the ragdoll, and it's simulated only on the server.
That basically eliminates all the problems at once, apart from the performance cost on the server of simulating more than it did before. To handle that, I've made sure that ragdolls stop simulating as soon as they've settled down, including when they're on a moving vehicle. Overall the performance cost on the server is low, and behaviour is much improved.
If anything does go wrong, there is a new 'serversideragdolls` console command that can be set true or false. It's now true by default, but setting it to false will immediately revert to the old system.