Replicated Anim Montage is extremely choppy when viewed from the server

So, this is an issue that im only getting on 4.20 On every other engine release it works just fine, im replicating an animation montage, and it works great, both clients and server can see the montages. however when the server (or a player as a listen server ) is seeing the montage from another client it looks extremely choppy, as if its play rate or frame rate was very low. Clients can see each other montages AND server montages just fine though…

Here is a video showcasing the problem (Server is on the left, client is on the right)

As you can see, if the client initiates the montage, it looks fine for the client but on the server it looks extremely choppy

If the server initiates his montage then the client can see it at a proper rate

All im truly doing, is setting a struct as a replicated variable ( which contains all of my montage info montage to play, section, time etc ) and once this variable is replicated and it reaches the client, the client plays the montage based on the info from the struct

Any help would certainly be appreciated

You can’t replicate variables from a client. Only the server can replicate variables.

Try this: When someone wants to play the montage (I assume because of a player input?), he calls a NetMulticast function which plays the montage. In that function call you can use your struct as a parameter.
It may be, that you play the montage more then once.

A server RPC runs only on the server, but not on the clients. How can the character play the animation on all clients then?
Also, if the server runs the PlayAnimMontage function, he creates an endless loop, because in line 30 you call that function again.

Feel free to correct me if im wrong
but isnt the server only calling the
PlayAnimMontage function ( which just
plays the montage locally) not
PlayMontage which is the one im using
to handle the replication?

Yes you are right about that one, haven’t seen it -.-
Is any component on your character set to replicate? Especially the mesh? If the mesh is set to replicate, then you need to deactivate that. I had the problem, when it was replicated, that my character didn’t move smoothly.
In general your setup seems way to complicated for what you are doing.
If you want every client to play an montage because of an event that only happens on one client (e.g. player imput), simply use a NetMutlicast which plays the montage like so:

void AGun::Multicast_PlayReloadAnimation_Implementation()
{
	UAnimInstance* AnimInstance;	
	AnimInstance = _MyOwner->GetMesh()->GetAnimInstance();
	if (AnimInstance)
	{
		AnimInstance->Montage_Play(_ReloadAnimation, 1.f);
	}
}

Also, why do you call ForceNetUpdate()?

Thanks for the reply!, Ill explain myself a bit better now

I do know that clients cant replicate variables, Which is why if a client tries to play a montage he calls a server RPC instead, so the variable is always set from the server. Here is the code im using to achieve this

void AMeleeKitCharacter::ServerMontageTest_Implementation(UAnimMontage* AnimMontage)
{
//Skipping the sections for now
	PlayMontage(AnimMontage, 1.0f, NAME_None);
}

bool AMeleeKitCharacter::ServerMontageTest_Validate(UAnimMontage* AnimMontage)
{
	return true;
}


void AMeleeKitCharacter::PlayMontage(UAnimMontage* Montage,float PlayRate, FName SectionName)
{
	if (Role < ROLE_Authority)
	{
                 //Call the server function with the montage we want to play
                //and dont go any further
		ServerMontageTest(Montage);
		return;
	}

	if (Role == ROLE_Authority)
	{
		RepAnimMontageInfo.MontageToPlay = Montage;
		RepAnimMontageInfo.PlayRate = 1.0f;
		RepAnimMontageInfo.StartSectionName = SectionName;
		RepAnimMontageInfo.STime = GetWorld()->TimeSeconds;
		ForceNetUpdate();
		PlayAnimMontage(Montage, 1.0f, SectionName);
	}
}

void AMeleeKitCharacter::OnRep_AnimMontage()
{
	PlayAnimMontage(RepAnimMontageInfo.MontageToPlay, 1.0f, RepAnimMontageInfo.StartSectionName);
	print("playing anim montage replicated");
}

I did try to use a NetMulticast function as you suggested, however the result is the same. ( Montage is choppy when viewed from the server, but clients can see each other and the server montages just fine )

The animation is played across all clients becouse i got an OnRep function tied to RepAnimMontageInfo, whatever it changes and gets replicated all the clients call play anim montage with the info from the struct as seen here

UPROPERTY(ReplicatedUsing = OnRep_AnimMontage)
FRepAnimMontageInfo RepAnimMontageInfo;


void AMeleeKitCharacter::OnRep_AnimMontage()
{
	PlayAnimMontage(RepAnimMontageInfo.MontageToPlay, 1.0f, RepAnimMontageInfo.StartSectionName);
	print("playing anim montage replicated");
}

void AMeleeKitCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(AMeleeKitCharacter, RepAnimMontageInfo);
}

Feel free to correct me if im wrong but isnt the server only calling the PlayAnimMontage function ( which just plays the montage locally) not PlayMontage which is the one im using to handle the replication?, And again i appreciate the help!, im just trying to make sure that its all clear

Well it seems that changing ClientNetSendMoveDeltaTimeStationary in my engine installation BaseGame.ini from 0.833 to 0.0166 fixed the issue, Still thanks for the help!

I tried this in my project, and the animations are still laggy