humanoid.BreakJointsOnDeath = false prevents Anchored characters from dying

Reproduction Steps

Anchored Humanoid.Died Bug.rbxl (31.7 KB)

In this place file I have 3 LuaSourceContainers that requires your attention

The first one inside ServerScriptService handles PlayerAdded, CharacterAdded and changes the Humanoid’s properties.

The second and third creates a button that Kills the Humanoid on the Client or on the Server.

You can press either one of them and you will see that Humanoid player has Died will NEVER fire on the Server

Code

ServerScript:

local RunService = game:GetService("RunService")

game.Players.PlayerAdded:Connect(function(addedPlayer)
	local player = addedPlayer

	player.CharacterAdded:Connect(function(addedCharacter)
		local character = addedCharacter
		local humanoid: Humanoid = character:WaitForChild("Humanoid")
		local rootpart: BasePart = character:WaitForChild("HumanoidRootPart")
		
		rootpart.RootPriority = 127
	end)
	
	player.CharacterAppearanceLoaded:Connect(function(addedCharacter: Model)
		RunService.Heartbeat:Wait()
		
		local character = addedCharacter
		local humanoid: Humanoid = character:WaitForChild("Humanoid")
		
		humanoid.BreakJointsOnDeath = false
		humanoid.AutomaticScalingEnabled = false
	end)
end)

Expected Behavior
I expect the Humanoid to die when this is executed

	humanoid.Health = 0
	humanoid:ChangeState(Enum.HumanoidStateType.Dead)

Actual Behavior
The Humanoid doesn’t die and causes Humanoid.Died to NEVER fire

Issue Area: Engine
Issue Type: Humanoid State
Impact: Critical
Frequency: Constantly
Date First Experienced: 2021-07-10 00:07:00 (+07:00)
Date Last Experienced: 2021-07-31 00:07:00 (+07:00)

This started happening when this was implemented

Second revision of change switching Humanoid state replication to a property from an assembly property in physics replication.

and this FFlag

since they happen in the same time period they might correlate


Related: Humanoid.Died won't fire when Humanoid.BreakJointsOnDeath is disabled?

6 Likes

I tried disabling FFlagHumanoidSimulateNullptrCheck locally and the issue still reproduces. I suspect this has been “broken” for a much longer, if this ever worked.

I can imagine a really racy case where the code to kill and anchor the humanoid run at separate times in the frame is run there might be a possibility for it to manage to send out a notification that the character died. I’d be very surprised if anything expecting death to replicate similar to the repro ever worked consistently!

Currently, normal humanoid state replication is through the physics sender. No physics replication, no humanoid state replication. When you anchor the character there’s no more physics replication, so you’ve disabled humanoid state transmission as well.

If BreakJointsOnDeath was enabled this repro would still work because destroying character joints on the client is whitelisted in the FilteringEnabled network filter for ugly legacy breakjoints reasons. The server will then kill the character as soon as it notices the missing Neck.

So there’s currently two ways for death to replicate from the client to the server and this repro targetedly breaks both of them!

You’ve also anchored the character only on the client in this case, but the character is still unanchored on the server, so you’ve also created a weird desyncronized network ownership unit scenario as well. The client no longer thinks it should be able to send physics updates for the parts, because normally anchored parts do not have network ownership. The server still sees the character as unanchored and owned by the client, but it’s mysteriously not getting any physics updates.

In this case, if you unanchor the character on the client physics replication will resume, be accepted by the server for the still unanchored character, and the character finally dies on the server.

Predictively anchoring on the client first is fine, but you’d also want to notify the server and have it anchor the character parts as well to restore consistency. You just can’t rely on waiting for Death on the server though, which in this case won’t work. Unrelated to the issue itself, but FYI.

This refers to SFFlagNetworkHumanoidStatePropertyReplication2, which has not yet been enabled. It probably won’t fix this problem though.

This flag changes Humanoid state replication to internally use standard property replication, conditionally whitelisted for humanoids you currently have network ownership of, so it no longer depends on physics replication but still depends on network ownership. So still no state replication for anchored characters. It should mostly maintain the status quo.

We’ll have to add some additional whitelisting based on Player.Character even if they’re anchored to make this work. I’m not sure if we want to make this change, but we’ll look into it.

For now, if you must anchor the character before the character is dead on the server, you should use a RemoteEvent to have the client notify the server of Death.

8 Likes

This topic was automatically closed after 7 days. New replies are no longer allowed.