Is there a maximum number of Subobject that can replicate whith ActorChannel?

Hello there,

I am trying to replicate an Array of Custom UObject.

I am doing this with overriding “ReplicateSubobjects” in an actor and using “Channel->ReplicateSubobjectList” to replicate my Array of UObject.

It works fine.

Except when my array is kind of large (~ 500 items), it does not replicated.

Do you know if there is a limit or how too handle large amount of UObject to replicated ?

Thanks a lot.

Have you checked the logs? Seems like you’re sending too much data, so the logs will give you a warning that looks like this: "FBitWriter overflowed! ..."

And you can definitely optimize.

Hello,

I did not see anything in logs neither in visual logger.

I checked what you suggest and I tried a bunch of stuff without success (with KeyNeedsToReplicate).

What I did not say it is that I use a custom FFastArraySerializer struct to replicate the UObject Array.

Anyway, you did help me by showing me the right direction. I succeed to double the Objects that I can replicate :slight_smile: That’s enought for me, for now.

But I am still wondering where I can see functionnal example of KeyNeedsToReplicate on the Web, I did not find realy good one.

Here is my solution :
In my actor :

bool AGrid::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
	bool bWroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);

	for (int32 idx = 0; idx < GridItemsRefPool.Num(); ++idx)
	{
		if (idx < 100 * (1 + CurrentIteration))
		{
			UGridItem* Obj = GridItemsRefPool[idx];
			bWroteSomething |= Channel->ReplicateSubobject(Obj, *Bunch, *RepFlags);
		}
	}
	
	return bWroteSomething;
}

And I just set a timer that increment “CurrentIteration” every X seconds.

Thx :slight_smile:

FastArrays are amazing, and they prove helpful when your array becomes big.

Yes, there is an example and that is somehow similar to what you did. You can check ActorChannel.h:

// --------------------------------
	// Subobject Replication state
	//
	//	Concepts: 
	//		ObjID  - this is an arbitrary identifier given to us by the game code.
	//		RepKey - this is an idenifier for the current replicated state. 
	//
	//	ObjID should be constant per object or "category". Its up to the game code. For example the game code could use 0 to determine if an entire array is dirty,
	//	then usen 1-N for each subobject in that list. Or it could have 5 arrays using 0-4, and then use 100*ArrayNum + idx for the items in the array.
	//
	//	RepKey should change as the subobject changes. Each time a subobject is marked dirty, its RepKey should change.
	//
	//	GameCode should call ::KeyNeedsToReplicate(ObjID, RepKey) to determine if it needs to replicate. For example:
	//
	//
	/*

	bool AMyActorClass::ReplicateSubobjects(UActorChannel *Channel, FOutBunch *Bunch, FReplicationFlags *RepFlags)
	{
		bool WroteSomething = false;

		if (Channel->KeyNeedsToReplicate(0, ReplicatedArrayKey) )	// Does the array need to replicate?
		{
			for (int32 idx = 0; idx < ReplicatedSubobjects.Num(); ++idx )
			{
				UMyActorSubobjClass *Obj = ReplicatedSubObjects[idx];
				if (Channel->KeyNeedsToReplicate(1 + idx, Obj->RepKey))
				{								
					WroteSomething |= Channel->ReplicateSubobject<UMyActorSubobjClass>(Obj, *Bunch, *RepFlags);
				}
			}
		}

		return WroteSomething;
	}

	void UMyActorSubobjClass::MarkDirtyForReplication()
	{
		this->RepKey++;
		MyOwningActor->ReplicatedArrayKey++;
	}