fix(zmmo-client): ZeusPlayerProxy clock offset EMA + asset cleanup L_TestWorld
ZeusPlayerProxy.cpp -- H3 fix (2026-06-06): EMA com clamp para ServerClockOffsetMs ================================================================ Antes: offset congelado na 1a amostra de ApplyEntitySnapshot. Em cross-server handoff, a fonte do ServerTimeMs muda (publisher antigo emitia 12340000, novo emite 12351000) e o offset fica permanentemente skewed. Causa tremor pos-handoff + drift cumulativo de clock cliente vs server. Depois: cada amostra recalcula candidato (LocalNowMs - Snapshot.ServerTimeMs) e suaviza via EMA com alpha=0.02 (~50 amostras para convergir) + clamp max 2ms por amostra (a 30Hz isso converge a 60ms/s, suficiente para absorver drift normal sem causar tremor visual). 1a amostra continua bootstrap direto. Trecho: const double Alpha = 0.02; const int64 RawTarget = ServerClockOffsetMs*(1-Alpha) + OffsetCandidate*Alpha; const int64 Delta = RawTarget - ServerClockOffsetMs; const int64 ClampedDelta = clamp(Delta, -2, 2); ServerClockOffsetMs += ClampedDelta; Asset cleanup L_TestWorld ========================== DT_Maps.uasset modificado + 3 ExternalActors deletados (provavelmente limpeza no UE editor ao reorganizar mapa). Empacotado junto pra branch ficar limpa. * Content/ZMMO/Data/World/DT_Maps.uasset (M) * Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/2/BR/38W34OMKW0W3L1PGS3Y98G.uasset (D) * Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/4/8L/X3PMRJRGAACIU1WG1P1KJ0.uasset (D) * Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/8/L1/C6M65Q91PG5E7ML91VQZX3.uasset (D) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -222,13 +222,33 @@ void AZeusPlayerProxy::SetZeusIdentity(const int64 InEntityId, const EZeusEntity
|
||||
|
||||
void AZeusPlayerProxy::ApplyEntitySnapshot(const FZeusEntitySnapshot& Snapshot)
|
||||
{
|
||||
// Estabiliza o offset de relogio na primeira amostra. Subsequente nao
|
||||
// re-sincroniza para evitar saltos visuais; um esquema mais sofisticado
|
||||
// (ema do offset) cabe quando tivermos ping/RTT estabilizado por sessao.
|
||||
// 2026-06-06 H3 fix — disciplina o ServerClockOffsetMs via EMA com clamp.
|
||||
// Antes: offset congelado na 1a amostra. Em cross-server handoff a fonte
|
||||
// do ServerTimeMs muda (publisher antigo -> novo) e o offset fica
|
||||
// permanentemente skewed, alimentando tremor pos-handoff e drift cumulativo
|
||||
// de clock cliente vs server. Agora cada amostra recalcula candidato e
|
||||
// suaviza (alpha=0.02, ~50 amostras pra convergir) com clamp max 2ms/snapshot
|
||||
// pra evitar salto visual durante transicao.
|
||||
const int64 LocalNowMs = static_cast<int64>(FPlatformTime::Seconds() * 1000.0);
|
||||
const int64 OffsetCandidate = LocalNowMs - Snapshot.ServerTimeMs;
|
||||
if (SnapshotBuffer.Num() == 0)
|
||||
{
|
||||
const int64 LocalNowMs = static_cast<int64>(FPlatformTime::Seconds() * 1000.0);
|
||||
ServerClockOffsetMs = LocalNowMs - Snapshot.ServerTimeMs;
|
||||
// Primeira amostra: bootstrap direto (nao tem baseline pra suavizar).
|
||||
ServerClockOffsetMs = OffsetCandidate;
|
||||
}
|
||||
else
|
||||
{
|
||||
const double Alpha = 0.02;
|
||||
const int64 RawTarget = static_cast<int64>(
|
||||
static_cast<double>(ServerClockOffsetMs) * (1.0 - Alpha)
|
||||
+ static_cast<double>(OffsetCandidate) * Alpha);
|
||||
// Clamp max 2ms por amostra — em 30Hz isso converge a 60ms/s, mais que
|
||||
// o suficiente pra absorver drift normal sem causar tremor visual.
|
||||
const int64 Delta = RawTarget - ServerClockOffsetMs;
|
||||
const int64 ClampedDelta = (Delta > 2) ? 2
|
||||
: (Delta < -2) ? -2
|
||||
: Delta;
|
||||
ServerClockOffsetMs += ClampedDelta;
|
||||
}
|
||||
|
||||
FZeusProxySnapshot S;
|
||||
|
||||
Reference in New Issue
Block a user