Dedicated Server Bug with Interactive Foliage

If you are using regular Listen servers, then this does not apply to you!

It has come to my attention that running the Foliage System on Dedicated Servers causes the server to crash.

Assertion failed: Assertion failed: (Index >= 0) & (Index < ArrayNum) [File:Runtime/Core/Public\Containers/Array.h] [Line: 634]
Array index out of bounds: 3530 from an array of size 0

I have a simple solution for this, all you need to do is change a few lines of Engine code to fix it, this is because the Dedicated Server doesn’t consider the Instance array valid since they are not being rendered on the server.

Open up “C:\UnrealEngine\Engine\Source\Runtime\Engine\Private\HierarchicalInstancedStaticMesh.cpp”

Go to line 2394 (UE Source 4.17.2)

Inside the function UHierarchicalInstancedStaticMeshComponent::BuildTreeAsync()

 

Old code

const bool bMeshIsValid =
// make sure we have instances
PerInstanceSMData.Num() > 0 &&
// make sure we have an actual staticmesh
GetStaticMesh() &&
GetStaticMesh()->HasValidRenderData() &&
// You really can’t use hardware instancing on the consoles with multiple elements because they share the same index buffer.
// @todo: Level error or something to let LDs know this
1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;
}

New code

// Verify that the mesh is valid before using it.
bool bMeshIsValid =
// make sure we have instances
PerInstanceSMData.Num() > 0 &&
// make sure we have an actual staticmesh
GetStaticMesh() &&
GetStaticMesh()->HasValidRenderData() &&
// You really can’t use hardware instancing on the consoles with multiple elements because they share the same index buffer.
// @todo: Level error or something to let LDs know this
1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;

if (GetNetMode() == NM_DedicatedServer)
{
bMeshIsValid =
// make sure we have instances
PerInstanceSMData.Num() > 0 &&
// make sure we have an actual staticmesh
GetStaticMesh() &&
// You really can’t use hardware instancing on the consoles with multiple elements because they share the same index buffer.
// @todo: Level error or something to let LDs know this
1;
}