Why does Character.Head become nil, replaced by a new head? (easy to reproduce)

I’m feeling a bit confused about what exactly is happening after PlayerAdded fires. It seems that when a player is added, player.Character initially has a Head, but then if you wait() just once, the Head has been replaced with a new one. Why?

To see this, make a new baseplate project and just create a (server-side) Script and put this in it:

game.Players.PlayerAdded:Connect(function (player)
	local character = player.Character or player.CharacterAdded:Wait()
	local head = character.Head
	print("Parent of head is", head.Parent)
	wait()
	print("Parent of head is now", head.Parent)
end)

This prints the following:

  00:06:59.726  Parent of head is sudachipapa  -  Server - Script:4
  00:06:59.775  Parent of head is now nil  -  Server - Script:6

You can see that the Parent is first reported as you’d expect. But then after the wait() it becomes nil. If you compare character.Head before and after, it’s a different object and also a little bit smaller.

How come? Just linking to some relevant doc is a fine answer.

Note that stepping through this code in the debugger alters the result.

If I recall correctly the character’s Head is a MeshPart, and a MeshPart’s MeshId can’t be modified => probably forcing roblox to replace it with a new MeshPart.

Player.Character

You might be getting a nil value because of this line:

local character = player.Character or player.CharacterAdded:Wait()

Most likely, once the character is finished loading, there is a new “head” in the fully loaded model and the “head” object that you retrieved from player.Character is no longer valid. To resolve this, just change your code to:

local character = player.CharacterAdded:Wait()
1 Like