I ran into the same thing and managed to narrow it down.
In my test, a dedicated server and client were running on two PCs in the same LAN.
A simple UDP responder gave me:
PONG RTT: 2.8–3.3 ms
But a request/response going through Unreal’s networking layer consistently gave me:
RPC RTT: ~32 ms
And APlayerState::GetPingInMilliseconds() was also around:
28–35 ms
So the ~30 ms isn’t simply the physical network RTT. It appears to be introduced by the Unreal networking path / packet processing / timing.
For testing this, I used a minimal Server RPC + Client RPC round trip:
// PlayerController.h
UFUNCTION(Server, Unreliable)
void ServerPingTest(double ClientSendTime);
UFUNCTION(Client, Unreliable)
void ClientPingTestResult(double ClientSendTime);
// PlayerController.cpp
void AMyPlayerController::ServerPingTest_Implementation(double ClientSendTime)
{
// Respond immediately.
ClientPingTestResult(ClientSendTime);
}
void AMyPlayerController::ClientPingTestResult_Implementation(double ClientSendTime)
{
const double Now = FPlatformTime::Seconds();
const double RTTSeconds = Now - ClientSendTime;
const double RTTMs = RTTSeconds * 1000.0;
UE_LOG(
LogTemp,
Warning,
TEXT("UE RPC RTT: %.3f ms"),
RTTMs
);
}
void AMyPlayerController::TestNetworkPing()
{
const double StartTime = FPlatformTime::Seconds();
ServerPingTest(StartTime);
}
Then compare it with a raw UDP ping to the same machine.
In my case:
Raw UDP RTT: ~3 ms
UE RPC RTT: ~32 ms
GetPing...: ~32 ms
So if you’re trying to measure the latency that actually matters for gameplay, I would not use a separate UDP socket as the displayed “ping”. That measures the network path to the host, not necessarily the latency through Unreal’s networking stack.
A separate UDP ping is still useful for diagnostics, because it lets you distinguish:
network RTT
vs.
Unreal networking RTT
But where the goal is to show players an estimate of actual gameplay responsiveness, I’d measure through the same Unreal networking path used by the game.