From d41b0f1feb0b13ad7a090f7930d8f6ca72d3c0a1 Mon Sep 17 00:00:00 2001 From: Selt <83926739+seltonmt012@users.noreply.github.com> Date: Mon, 27 Jul 2026 22:36:56 +0200 Subject: [PATCH] fix(es_extended/client): stop stacking adjustment threads on every relog Adjustments:Load() runs from the esx:playerLoaded handler, so it runs again on every character switch. AmmoAndVehicleRewards, Multipliers and DiscordPresence each start a `while true` thread that never exits, and SeatShuffle and DisableRadio register another esx:enteredVehicle handler. Nothing tears any of it down, so a player who switches characters a few times ends up with several per-frame threads all writing the same values, and client performance degrades until they reconnect. The loops now run `while ESX.PlayerLoaded`, the same way StartServerSyncLoops and Actions:SlowLoop already do, so they end on logout and a fresh one starts on the next load. The two event handlers are registered once. Actions:Init already documents this exact concern in a comment; Adjustments never got the same treatment. Measured in game on artifact 25770 by counting thread ticks per frame: before: 2.01 -> 3.01 -> 4.02 across two relogs after: 1.00 -> 1.00 -> 1.00 --- [core]/es_extended/client/modules/adjustments.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/[core]/es_extended/client/modules/adjustments.lua b/[core]/es_extended/client/modules/adjustments.lua index 1c83b148..bf80b880 100644 --- a/[core]/es_extended/client/modules/adjustments.lua +++ b/[core]/es_extended/client/modules/adjustments.lua @@ -25,7 +25,9 @@ function Adjustments:DisableNPCDrops() end function Adjustments:SeatShuffle() - if Config.DisableVehicleSeatShuff then + if Config.DisableVehicleSeatShuff and not self.seatShuffleRegistered then + self.seatShuffleRegistered = true + AddEventHandler("esx:enteredVehicle", function(vehicle, _, seat) if seat > -1 then SetPedIntoVehicle(ESX.PlayerData.ped, vehicle, seat) @@ -43,7 +45,7 @@ end function Adjustments:AmmoAndVehicleRewards() CreateThread(function() - while true do + while ESX.PlayerLoaded do if Config.DisableDisplayAmmo then DisplayAmmoThisFrame(false) end @@ -187,7 +189,7 @@ end function Adjustments:DiscordPresence() if Config.DiscordActivity.appId ~= 0 then CreateThread(function() - while true do + while ESX.PlayerLoaded do SetDiscordAppId(Config.DiscordActivity.appId) SetRichPresence(self:ReplacePlaceholders(Config.DiscordActivity.presence)) SetDiscordRichPresenceAsset(Config.DiscordActivity.assetName) @@ -213,7 +215,9 @@ function Adjustments:WantedLevel() end function Adjustments:DisableRadio() - if Config.RemoveHudComponents[16] then + if Config.RemoveHudComponents[16] and not self.disableRadioRegistered then + self.disableRadioRegistered = true + AddEventHandler("esx:enteredVehicle", function(vehicle, plate, seat, displayName, netId) SetVehRadioStation(vehicle,"OFF") SetUserRadioControlEnabled(false) @@ -223,7 +227,7 @@ end function Adjustments:Multipliers() CreateThread(function() - while true do + while ESX.PlayerLoaded do SetPedDensityMultiplierThisFrame(Config.Multipliers.pedDensity) SetScenarioPedDensityMultiplierThisFrame(Config.Multipliers.scenarioPedDensityInterior, Config.Multipliers.scenarioPedDensityExterior) SetAmbientVehicleRangeMultiplierThisFrame(Config.Multipliers.ambientVehicleRange)