Iris - Exporting actor components using an index as opposed to a NetRefHandle?

Hello,

Our game requires that we consistently spawn a lot of AI and those AI characters make heavy use of replicated components (20+ components). The result of this heavily componentized approach is that spawning a single AI can take upwards of 3000 bits just for the component exports. I’m considering spending the time necessary to see if we can utilize a scheme where actor components are serialized as the owning actor’s net ref handle and an index. This makes an assumption that the components can be ordered deterministically on both sides and that we cannot add or remove components at runtime (which we already have a policy and guardrails for). Curious if anyone has any thoughts on this approach or if they’ve had similar issues with dealing with export bloat.

Thanks,

Nick

[Attachment Removed]

Hi,

In order to better understand your goals here, I have a couple of questions.

First, are these components stably named default subobjects of the actor, or are they dynamically spawned?

Next, could you clarify what you mean by the component exports? Is your primary concern just for the amount of bandwidth these components are using when the AI actor is initially replicated, or are you having problems with the cost of replicating/creating those components during net-init?

Thanks,

Alex

[Attachment Removed]

They are stably named, we do not allow the adding or removal of components to an actor at runtime. For your 2nd question, I’m not sure I understand the difference. Here I’m specifically talking about the CreationInfo bunch, which to my understanding is the first bunch sent for a newly spawned actor. In that bunch, the exports portion of the packet can take thousands of bits the overwhelming majority of which are exports for the actor’s components.

While the creation info is my first primary concern, ideally I’d like to further extend this so that component references are serialized as either an index in the case that they belong to the actor’s bunch or the owning actor’s net ref handle plus an index in the case that the component belongs to a different actor.

I wouldn’t expect the engine to support this, since it is all predicated on the assumption that we do not add or remove replicated actors at runtime and therefore the sort of the components is deterministic on both sides and the indexes are guaranteed to index the same component on both sides.

Thanks,

Nick

[Attachment Removed]

Hi,

Thank you for the context.

When it comes to replicating references, NetRefHandles/NetTokens are usually very cheap in terms of bandwidth. However, when a stably named subobject is first replicated (such as in the CreationInfo packet), the object’s full path name will be exported along with the NetToken, so future packets can just send the NetToken. We do have a longstanding, backlogged task to look into ways of optimizing this initial export, but I couldn’t provide an estimate as to when any change might be made.

Outside of modifying the FObjectReferenceCache, something you could try would be to create a custom UNetSubObjectFactory that prevents FNetStaticSubObjectCreationHeader from writing the full object reference, instead sending only the data you need. That being said, without having tested this ourselves, it’s hard to say what exactly to expect with an approach like this. It’s possible that something else could replicate a reference to the component, causing the path to be exported anyway.

Thanks,

Alex

[Attachment Removed]

Hi,

Another dev recommended tokenizing the paths being exported, which is essentially the approach you’ve described here. This would likely require making modifications to FObjectReferenceCache, but it could avoid the issue of other packets, such as a RPC, exporting the paths as strings.

Thanks,

Alex

[Attachment Removed]