From 2f96bda6faad8eb4b960871569273481ef6abd0c Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 28 Mar 2026 15:38:44 -0700 Subject: [PATCH] fix: far same-map teleport blocked packet handler for 41 seconds loadOnlineWorldTerrain() was called directly from the worldEntryCallback inside the packet handler, running the 20s warmup loop synchronously. This blocked ALL packet processing and froze the game for 20-41 seconds. Now defers the world reload to pendingWorldEntry_ which is processed on the next frame, outside the packet handler. Position and camera snap immediately so the player doesn't drift at the old location. The /y respawn report was actually a server-initiated teleport (possibly anti-spam or area trigger) that hit this 41-second blocking path. --- src/core/application.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/application.cpp b/src/core/application.cpp index fc68045c..67d01c81 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -2446,11 +2446,19 @@ void Application::setupUICallbacks() { bool farTeleport = (teleportDistSq > 500.0f * 500.0f); if (farTeleport) { - // Far same-map teleport (hearthstone, etc.): do a full world reload - // with loading screen to prevent falling through unloaded terrain. + // Far same-map teleport (hearthstone, etc.): defer full world reload + // to next frame to avoid blocking the packet handler for 20+ seconds. LOG_WARNING("Far same-map teleport (dist=", std::sqrt(teleportDistSq), - "), triggering full world reload with loading screen"); - loadOnlineWorldTerrain(mapId, x, y, z); + "), deferring world reload to next frame"); + // Update position immediately so the player doesn't keep moving at old location + renderer->getCharacterPosition() = renderPos; + if (renderer->getCameraController()) { + auto* ft = renderer->getCameraController()->getFollowTargetMutable(); + if (ft) *ft = renderPos; + renderer->getCameraController()->clearMovementInputs(); + renderer->getCameraController()->suppressMovementFor(1.0f); + } + pendingWorldEntry_ = PendingWorldEntry{mapId, x, y, z}; return; } LOG_INFO("Same-map teleport (map ", mapId, "), skipping full world reload");