fix: transport elapsed time lost millisecond precision after ~4.5 hours

elapsedTime_ was float (32-bit, ~7 significant digits). At 16384
seconds the float can only represent integers, so elapsedTime_*1000
jumps in 1-second steps — ships and elevators visibly jerk. Changed to
double (53-bit mantissa) which maintains sub-millisecond precision for
~285 million years. Also changed lastServerUpdate to double to match.
This commit is contained in:
Kelsi 2026-03-29 20:14:45 -07:00
parent ef25785404
commit fa15a3de1f
2 changed files with 7 additions and 5 deletions

View file

@ -64,7 +64,7 @@ struct ActiveTransport {
bool serverYawFlipped180; // Auto-correction when server yaw is consistently opposite movement
int serverYawAlignmentScore; // Hysteresis score for yaw flip detection
float lastServerUpdate; // Time of last server movement update
double lastServerUpdate; // Time of last server movement update
int serverUpdateCount; // Number of server updates received
// Dead-reckoning from latest authoritative updates (used only when updates are sparse).
@ -147,7 +147,9 @@ private:
rendering::WMORenderer* wmoRenderer_ = nullptr;
rendering::M2Renderer* m2Renderer_ = nullptr;
bool clientSideAnimation_ = false; // DISABLED - use server positions instead of client prediction
float elapsedTime_ = 0.0f; // Total elapsed time (seconds)
// double: float loses millisecond precision after ~4.5 hours (2^23 / 1000),
// causing transport path interpolation to visibly jerk in long play sessions.
double elapsedTime_ = 0.0;
};
} // namespace wowee::game

View file

@ -98,7 +98,7 @@ void TransportManager::registerTransport(uint64_t guid, uint32_t wmoInstanceId,
if (transport.useClientAnimation && path.durationMs > 0) {
// Seed to a stable phase based on our local clock so elevators don't all start at t=0.
transport.localClockMs = static_cast<uint32_t>(elapsedTime_ * 1000.0f) % path.durationMs;
transport.localClockMs = static_cast<uint32_t>(elapsedTime_ * 1000.0) % path.durationMs;
LOG_INFO("TransportManager: Enabled client animation for transport 0x",
std::hex, guid, std::dec, " path=", pathId,
" durationMs=", path.durationMs, " seedMs=", transport.localClockMs,
@ -259,7 +259,7 @@ void TransportManager::updateTransportMovement(ActiveTransport& transport, float
}
// Evaluate path time
uint32_t nowMs = static_cast<uint32_t>(elapsedTime_ * 1000.0f);
uint32_t nowMs = static_cast<uint32_t>(elapsedTime_ * 1000.0);
uint32_t pathTimeMs = 0;
if (transport.hasServerClock) {
@ -1154,7 +1154,7 @@ bool TransportManager::assignTaxiPathToTransport(uint32_t entry, uint32_t taxiPa
// Seed local clock to a deterministic phase
if (path.durationMs > 0) {
transport.localClockMs = static_cast<uint32_t>(elapsedTime_ * 1000.0f) % path.durationMs;
transport.localClockMs = static_cast<uint32_t>(elapsedTime_ * 1000.0) % path.durationMs;
}
updateTransformMatrices(transport);