Iris is unable to replicate a UObject subobject this is not outered directly to the RootObject when the RootObject is dynamic and the UObject is static.
Here are the relevant logs from the object failing to instantiate on the client side:
Error: BeginInstantiateFromRemote Failed to find Outer [NetRefHandle (Id=...):(RepSystemId=?)](NOT_IN_CACHE) for dynamic subobject NetRefHandle (Id=...):(RepSystemId=?)
UNetSubObjectFactory::InstantiateNetObjectFromHeader NetRefHandle (Id=...):(RepSystemId=?): Failed to find static or stable name object referenced by SubObject: [NetRefHandle (Id=...):(RepSystemId=?)](EMPTY).[NetRefHandle (Id=...):(RepSystemId=?)](...), Owner: RootObject ... (InternalIndex: ...) (NetRefHandle (Id=...):(RepSystemId=1)), RootObject: /...
LogIris: Error: FReplicationReader::ReadObject Failed to read object batch handle: NetRefHandle (Id=...):(RepSystemId=?) skipping batch data
LogIris: Error: ReplicationBridge(0)::OnErrorWithNetRefHandleReported: ReplicationDisabled from client ConnectionId:1 ViewTarget: ... Named: [UNetConnection] RemoteAddr: ..., Name: RGINetConnection_14, Driver: Name:GameNetDriver Def:GameNetDriver ..., IsServer: YES, PC: ..., Owner: ..., UniqueId: .... Problematic object was RootObject ...(InternalIndex: ...) (NetRefHandle (Id=...):(RepSystemId=0))
Iris’ FReplicationWriter::WriteObjectAndSubObjects calls FReplicationConditionals::GetSubObjectsToReplicate which has a comment about how it tries to mimic the legacy replication by inserting SubObject before their parent, however, unlike legacy replication, the client will not deserialize the outer before its inner objects. This leads to the errors above where an object will fail to instantiate because the outer object is replicated after its inner object from the order given by GetSubObjectsToReplicate. Using Kanh’s Topological sorting algorithm to ensure outer are replicated prior to their inner objects fixes the issue for our project.
My questions are:
- Is this a known issue/limitation?
- Does the solution sound reasonable?
- Are we doing something wrong here?
- Several of our object types are using their Outer to determine a hierarchy without having to define a member property, is this a pattern we can keep using?
[Attachment Removed]
- Several of our object types are using their Outer to determine a hierarchy without having to define a member property, is this a pattern we can keep using?