These spikes won’t show up on an empty baseplate though. I’ve included a place file privately that can show the spikes as it seems to only happen on maps with some detail. The place file has no code running (other than the script that parents parts) and has no humanoids.
According to the docs, updateInvalidatedFastClusters is correlated with humanoids, however, the repro place has no humanoids.
Hello and thank you for reaching out. The reason this happens is that when you parent a part to the workspace, it creates a “virtual” skeleton with the workspace being the root. This will cause slow downs for sure, and is the current expected behavior. Our recommendation is to always place parts under a an empty model or a folder created below the workspace in the tree. That will avoid such spikes when directly parenting to the workspace.
Please let us know if you have additional questions, or if we can provide further assistance.
Thank you again for your patience and support and for reaching it with issues.
Instead of putting the Parts under Models, put all the skinned MeshParts in your Workspace under Models:
local function addSkinMeshModels(parent)
children = parent:GetChildren()
for _, child in children do
if child:isA("MeshPart") then
if child.HasSkinnedMesh then
print(child.Name)
model = Instance.new("Model")
model.Name = child.Name
model.Parent = parent
child.Parent = model
continue
end
end
if child:isA("Model") then
continue
end
addSkinMeshModels(child)
end
end
local workspace = game:GetService("Workspace")
addSkinMeshModels(workspace)
Do folders work for this purpose as well? Also curious, why is this expected behavior? What is this virtual skeleton?
This is highly unexpected honestly, I wish Studio would offer hints to avoid gotchas like this, putting things directly into workspace is an extremely common practice.
This is not your fault, there are several interacting engine bugs at play here:
The “Tall grass” MeshParts in your Workspace are skinned. So, the engine searches for bones to build a skeleton for them, and renders them using FastClusters. For typical skinned characters, the skeleton search is limited to the hierarchy beneath the character’s Model. Because these skinned meshes aren’t under any models, the engine searches the entire Workspace for possible bones. Additionally, when new Parts are added, the engine considers them potential new bones, so it re-does the skeleton search, and rebuilds the FastClusters. The skeleton search is fast, but the FastCluster rebuild is slow, especially for skinned meshes, which causes the spikes you are seeing.
All this work the engine is doing is obviously unnecessary and inefficient. We are aware of this and are actively working to make it faster and more efficient on several fronts. We have an optimization in progress that reduces the FastCluster rebuild times significantly. We are also aware that the “Workspace skeleton” is inefficient and are considering changes to improve that as well. Thanks for your patience with this!
Why is the workspace considered a valid skeleton root at all? Seems like an easy quick exit to check if the root is the workspace, this should never work.
Also, the “fix” I am suggesting is just a temporary workaround, we are planning to fix this in the engine so you will not have to worry about it in the future.
This is also a bug. Unfortunately this one is tricky to fix, because changing it has the potential to break games that are currently using skinning in the Workspace without Models. We do plan to fix it, we just have to do it carefully, which may take some time.
Another compounding issue is there is currently no visual indication as to which MeshParts contain skinning data. There used to be a special icon for skinned MeshParts, but it was accidentally removed. We are working to restore that as well.
I’ve updated the script to only parent skinned MeshParts under Models. It will also tell you which MeshParts are skinned, in this case it is the “Tall grass” meshes.