From 2b99011cd8ac6d51a7fd89dd63bddcff45d22b1d Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 20 Mar 2026 18:51:05 -0700 Subject: [PATCH] fix: cap gossipPois_ vector growth and add soft frame rate limiter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cap gossipPois_ at 200 entries (both gossip POI and quest POI paths) to prevent unbounded memory growth from rapid gossip/quest queries. Add soft 240 FPS frame rate limiter when vsync is off to prevent 100% CPU usage — sleeps for remaining frame budget when frame completes in under 4ms. --- src/core/application.cpp | 9 +++++++++ src/game/game_handler.cpp | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/core/application.cpp b/src/core/application.cpp index a0c8e1a7..2826470a 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -646,6 +646,15 @@ void Application::run() { LOG_ERROR("GPU device lost — exiting application"); window->setShouldClose(true); } + + // Soft frame rate cap when vsync is off to prevent 100% CPU usage. + // Target ~240 FPS max (~4.2ms per frame); vsync handles its own pacing. + if (!window->isVsyncEnabled() && deltaTime < 0.004f) { + float sleepMs = (0.004f - deltaTime) * 1000.0f; + if (sleepMs > 0.5f) + std::this_thread::sleep_for(std::chrono::microseconds( + static_cast(sleepMs * 900.0f))); // 90% of target to account for sleep overshoot + } } } catch (...) { watchdogRunning.store(false, std::memory_order_release); diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index ea5e0904..e42704e3 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -2539,6 +2539,8 @@ void GameHandler::handlePacket(network::Packet& packet) { poi.icon = icon; poi.data = data; poi.name = std::move(name); + // Cap POI count to prevent unbounded growth from rapid gossip queries + if (gossipPois_.size() >= 200) gossipPois_.erase(gossipPois_.begin()); gossipPois_.push_back(std::move(poi)); LOG_DEBUG("SMSG_GOSSIP_POI: x=", poiX, " y=", poiY, " icon=", icon); break; @@ -21031,6 +21033,7 @@ void GameHandler::handleQuestPoiQueryResponse(network::Packet& packet) { poi.name = questTitle.empty() ? "Quest objective" : questTitle; LOG_DEBUG("Quest POI: questId=", questId, " mapId=", mapId, " centroid=(", poi.x, ",", poi.y, ") title=", poi.name); + if (gossipPois_.size() >= 200) gossipPois_.erase(gossipPois_.begin()); gossipPois_.push_back(std::move(poi)); } }