I just tried with Lyra, connecting through the Steam online subsystem and I have the same issue. I am thinking it could have something to do with the Steam online subsystem?
Here are my net stat. I don’t see any packet loss, but the behavior looks very much like what I see in PIE when I set a large percentage of packet loss in the Network emulation in the editor settings.
EDIT: Okay! Found out that the problem was that I have a basic Router and a Wifi 6 Access point to give me a better wifi connection. The Wifi 6 point was configured to act as a router instead of as an access point. I changed that and it works fine again.
If anyone is having the issue where the Host was seeying the Client’s character’s clothing or hair stuttering. But the Host on their respective machines were not having this issue. A quick fix that solved my issue was to double check the RigidBody Node option → Evaluation Reset Time this was set to .01 which would constatly reset the rigid body evaluation causing the stuttering. Which explained why only the Clothes/Hair controlled by the Rigid Body Nodes were having this issue and not those controlled by Spring Controllers were not.
TLDR: Double Check RigidBody → Settings → EvaluationResetTime → Try 0 See if that fixes your issue.
Here’s a quick solution that calls TickCharacterPose if necessary every frame by overriding ServerAutonomousProxyTick:
void UMyCharacterMovementComponent::ServerAutonomousProxyTick(float DeltaTime)
{
Super::ServerAutonomousProxyTick(DeltaTime);
if (IsNetMode(NM_ListenServer) && CharacterOwner && CharacterOwner->GetMesh())
{
// on listen server, ensure character pose is ticked every frame
USkeletalMeshComponent* CharacterMesh = CharacterOwner->GetMesh();
const bool bAlreadyTickedThisFrame = CharacterMesh->PoseTickedThisFrame();
if (!bAlreadyTickedThisFrame)
{
TickCharacterPose(DeltaTime);
}
}
}
This at least prevents frames without any mesh animation updates, but as @Chatouille mentioned, this could cause the animations to then tick with larger than intended delta time (once the server moves come in later), which could mess up montage/notify timings.
(That said, there might already be bugs in the engine here as USkeletalMeshComponent::ShouldTickPose already enforces only one tick per frame, but UCharacterMovementComponent::ServerMove_PerformMovement can happen multiple times in the same frame (if the server receives multiple updates in the same frame). In this case, the mesh could then receive a smaller tick than intended.)
SaveMoves are buffered and packed together on send. So the server will only get 1 move update per client. If an out of order latent packet is received in the same tick they’ll both be examined and sorting/discards etc prior to processing the simulation.
Packets are not processed immediately on receival by either client or server. They are handled at start of next tick. The results are flushed on the proceeding tick start.