Hey Phil, I’ve just read up on your recent posts after returning from Unreal Fest. I see you’ve cut a large number of objects from the dedicated server so that’s great. I’ll respond to all your points one by one, apologies for the wait.
NeedsLoadForServer behavior
You mentioned: “So, when looking into the UObject::NeedsLoadForServer, it looked like the engine code was already written with the mindset of removing primitives without collisions on the server. For some reason though the feature is mostly disabled, I don’t know if that’s a bug.”
I wasn’t aware, but that it’s disabled is in line with other default behavior, where we don’t want the engine to make assumptions for you. That’s just my guess though, if you want to know the answer with certainty let me know and I can ask around internally what the intention was.
FastGeo results
When you say that with FastGeo you reduced object count by roughly 24.5K, that’s compared to WorldPartitionRuntimeCellTransformerISMs, correct? Or is that compared to not transforming the level contents?
As for the resulting GC times (18.74ms), how did you measure that exactly? I.e. which Unreal Insights timer, log message etc. If you’ll provide that, I can ask internally if anyone has ideas for how FastGeo could make GC times worse. But we’ll need some more granular info like how much of those 19ms is spent in PerformReachabilityAnalysis, GatherUnreachableObjects, and so on. A screenshots of an insights capture would be helpful here.
Incorrect results
Ending up with floating objects is wrong in the case of both WP runtime cell transformer and FastGeoStreaming. If you can repro that in a clean UE 5.7 Preview project, our dev team would appreciate that and would investigate it. Or, if you notice any factors that can trigger the floating objects (i.e. are they in embedded level instances, or child actor components, etc) that would be helpful too.
Is that 18-19ms server GC time acceptable or will you want to decrease that more? It might be worthwhile playing with different periods (30s) to see if more frequent GC results in faster passes. Or do them less frequent as long as the server is below a certain memory threshold.
BodySetup numbers
You asked before about whether high UBodySetup counts are to be expected. It depends on a number of factors:
- the number of unique static mesh and skeletal mesh assets you have.
- every skeletal mesh component with per-poly collision constructs a UBodySetup
- every spline mesh component constructs a UBodySetup
This list isn’t exhaustive but I just had a look at what constructs UBodySetups. Since you have many spline mesh components, that number of body setups is expected. If you want to dig into it, you can execute this snippet at any time to log out the source of body setups:
ForEachObjectOfClass(UBodySetup::StaticClass(), [this](UObject* BodySetup)
{
UE_LOG(LogTemp, Warning, TEXT("FOUND BodySetup: '%s' in package '%s'"), *BodySetup->GetPathName(), *BodySetup->GetPackage()->GetName());
});
I suspect it’s the runtime created body setups from SplineMeshComponents though. If those spline mesh components need any collision / overlap / raycastability then they’ll need a body setup.