What is the proper way to disable/enable a Character to be used in an object pool which supports client and server?

Hi all, I’m hoping someone with experience in this area can help me. First, a little background info:

We are building a multiplayer game which can spawn somewhere around 90 creep characters at a time. Because we spawn so many, there is a significant frame hit each time they spawn which is every 10 seconds. To alleviate this, we have implemented object pooling for our creep classes along with an interface which defines a Reset() call that is used to reset their state before they are reused. In addition, we have some static Enable/Disable calls which are also used in conjunction with reset. Releasing a creep into the pool disables it, resets it, then stores it for future use. Acquiring a creep will enable it and return it.

The problem I’m having is how to disable and enable a creep character, so that its state is replicated properly the clients. I always get proper behavior on the server, just never the client. Here is a code example of how I’m doing it.

Disable

actor->SetActorHiddenInGame(true);
actor->SetActorEnableCollision(false);
actor->SetActorTickEnabled(false);
TSet<UActorComponent*> components = actor->GetComponents();
for (UActorComponent* actorComponent : components)
{		
	actorComponent->Deactivate();
}

// then I do some stuff to get the BrainComponent to call StopLogic & clear the blackboard

Enable

TSet<UActorComponent*> components = actor->GetComponents();
for (UActorComponent* actorComponent : components)
{			
	actorComponent->Activate(true);
}

// then I do some stuff to RestartLogic on the BrainComponent

actor->SetActorTickEnabled(true);
actor->SetActorEnableCollision(true);
actor->SetActorHiddenInGame(false);

I am having 2 problems with this.

  1. Not all components are deactivated or stopped on the clients. Mainly collision and movement. The rest seem to be fine. I have tried using a NetMulticast RPC to disable client side but this caused other issues on respawn (like stuttered movement).
  2. When disabling an actor and calling SetActorHiddenInGame(true) along with SetActorEnableCollision(false), the actor is actually destroyed on the client as EndPlay is called, but it is not on the server. I don’t necessarily want this behavior as I can see frame hits when the actors are respawned client side, basically nullifying pooling. Server side has no hitching as its pooling properly. I played with setting NetDormancy to DormantAll on Disable, and back to Awake on Enable preceded by a FlushNetDormancy() to try and prevent this, which works (prevents client EndPlay), but causes other side effects. Weird behavior where it doesn’t seem to be replicating everything properly, or things are happening out of order, etc.

I’m curious if anyone has faced similar issues, or has implemented proper object pooling on a client/server game with replicated characters? Any help or suggestions would be greatly appreciated.

Thanks