C++ replication

Hi guys! It’s been some days already while I’m trying to understand how replication works. I’ve watched lots of tuts on yt but still can’t manage to figure out why it’s not working properly. I have a flying character and the problem comes when I’m connecting with the clients on the dedicated server. The character is glitchy, like it’s trying to cheat (As I understood it’s trying to increase the speed only on the client side and it’s not sending to the server (or not?!)). The thing is that on listen server, with 1 client and 1 server the flying it’s working (some problems with rotation, but after I’ll understand better the replication, I should solve it. It feels a very bit glitchy) So what I’ve did. Tick → Check if you’re the server (== ROLE AUTH) and process the speed on server Tick → Check if you’re the client and process the speed for client view only. What I’m doing wrong here? Thank you! (edited)

Without having looked at your code, do any of your actors components also replicate?

I’ve found similar issues when a component or child actor of the main component is set to replicate. Can cause bad rubber banding.

Hi. Thank you for taking your time to look into it.
I’ve changed a bit the code.

void ACPPCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	ProcessRotation();
}

void ACPPCharacter::ProcessRotation()
{
	Rot.Roll = 0;
	Rot.Pitch = MousePitch * GetWorld()->DeltaTimeSeconds;
	Rot.Yaw  = MouseYaw * GetWorld()->DeltaTimeSeconds;
	Rot += GetActorRotation();
	SetActorRotation(FRotator(FMath::Clamp(Rot.Pitch,-75.0f,65.0f),Rot.Yaw,Rot.Roll));
}

void ACPPCharacter::MouseX(float Val)
{
	if(GetLocalRole() == ROLE_Authority)
	{
		SR_ProcessYaw(Val);
	}
	if(IsLocallyControlled() && GetLocalRole() < ROLE_Authority)
	{
		SR_ProcessYaw(Val);
	}
}

void ACPPCharacter::SR_ProcessYaw_Implementation(float Val)
{
	NM_ProcessYaw(Val);
}
bool ACPPCharacter::SR_ProcessYaw_Validate(float Val)
{
	return true;
}

void ACPPCharacter::NM_ProcessYaw_Implementation(float Val)
{
	const float YawMulti = Val * 10.0f;
	MouseYaw = FMath::FInterpTo(MouseYaw, YawMulti, GetWorld()->GetDeltaSeconds(), 2.0f);
}

//Mouse up down (Pitch)
void ACPPCharacter::MouseY(float Val)
{
	if(GetLocalRole() == ROLE_Authority)
	{
		SR_ProcessPitch(Val);
	}
	if(IsLocallyControlled() && GetLocalRole() < ROLE_Authority)
	{
		SR_ProcessPitch(Val);
	}
}

void ACPPCharacter::SR_ProcessPitch_Implementation(float Val)
{
	NM_ProcessPitch(Val);
}
bool ACPPCharacter::SR_ProcessPitch_Validate(float Val)
{
	return true;
}
void ACPPCharacter::NM_ProcessPitch_Implementation(float F)
{
	const float PitchMulti = F * 50.0f;
	MousePitch = FMath::FInterpTo(MousePitch, PitchMulti, GetWorld()->GetDeltaSeconds(), 2.0f);
}

The replicated var is ‘Rot’.
What I’ve did from my understandings.
I’ve read that SetActorRotation is already replicated so from Tick I’m only calling the rotation.

The MouseX checks if it’s the server and calls the server function → server calls multicast which updates MouseYaw ( from ProcessRotation()) and the same thing for MouseY.

In listen server the server/client rotates smoothly on each view, but when I’m connecting to dedicated server from Editor or connecting with client it’s a bit choppy. So here I’m confused. Is not in sync with the server or it’s because the latency?
The same choppy thing is happening also on listen server but playing on standalone game.
I could have used AddControllerYawInput and AddControllerPitchInput which is replicated already (or not?!) but I have a flying actor and I couldn’t solved the Pitch (which I wanted to rotate the character up and down. Only the camera rotates).

Edit: I have though a question also. (GetLocalRole() == ROLE_Authority) it’s only for testing on listen server? In case you are the client and the server at the same time? If using only dedicated server, I should use only IsLocallControlled? For example in tick which is called from server and client. Should I use IsLocallyControlled only to send from client to dedicated server? (In case I’m using only dedicated server)

Edit 2: To test, I’ve set the server validate to false, so in case it’s not synced, I get kick and no kick here (It’s a good way to test the sync ?!)