I’m calling part:GetMass() on descendants of the character when DescendantAdded fires. When it is called on the Handle part in an Accessory, it returns a positive number. Some arbitrary amount of time later (around .15 seconds), the mass becomes 0, seemingly without any detectable indication that it did. Now the mass calculations that already finished are wrong because the mass silently changed.
reproduction (LocalScript in StarterCharacterScripts):
script.Parent.DescendantAdded:Connect(function(part)
if part:IsA("BasePart") and part.Parent:IsA("Accoutrement") then
local path = part:GetFullName()
print(path, part:GetMass())
part.Changed:Connect(function(property)
print("(changed)", part:GetFullName(), property, part[property], part:GetMass())
end)
wait(1)
print("(new mass)", path, part:GetMass())
end
end)
I included the connection to Changed to show that there’s no indication that the mass changes.
The output here seems to also demonstrate another bug: Changed fires because the Parent changed, but it didn’t.
This is likely due to the Massless property. Is part.Massless true before you wait a second? Maybe the engine inserts the hat, then sets the Massless property to true. Hats would ideally be fully initialized before they’re inserted into the DataModel.
Massless is actually never set to true. If it were then the Changed event should have caught it, but it seems to use some other internal mechanic to negate its mass.
It seems that GetMass will return 0 if Massless is true, but only if the part is connected to something that does not have Massless set to true. Which makes sense; applying a force to something massless would propel it at infinite speed, so ignoring it unless it’s attached to something with mass is okay. Hats are attached to the characters, but Massless isn’t true, it just behaves like it is.
Massless in general has no effect unless it is welded to another part and it is not the root part of the welded assembly because we can’t have moving bodies with zero mass. Looks like your script would execute before all descendants of the character are added to the Workspace.
If this script runs before all parts and accessory welds are added, you’ll get the wrong mass value.
If not, at least add a listener for AncestryChanged on the root character Model and wait until after the model is parented to the workspace. If you’re trying to handle accessories added after the fact you’ll need to wait for the weld to be added before you recompute mass.
An easy solution might be to have DescendantAdded just set a dirty flag and recalculating later in the frame if this is set.