FiveM sunucularında oyuncuların en çok şikayet ettiği sorunların başında; sunucuda harita veya oyuncu sayısı arttıkça yaşanan ani FPS düşüşleri ve mikro takılmalar (stuttering) gelir. Birçok sunucu sahibi bu durumu doğrudan harita (MLO) veya araçlara bağlasa da, perde arkasındaki gizli katil çoğu zaman kötü yazılmış istemci (client-side) döngüleridir.
Şehirdeki 50 market, 30 garaj, onlarca depo ve meslek etkileşim noktası için sürekli çalışan while true do döngüleri, istemci işlemcisini (CPU) gereksiz yere boğar. 2026 yılı FiveM standartlarında bu yükü sıfırlamanın formülü: Vektör optimizasyonu, Adaptif Polling ve Mekânsal Bölümleme (Spatial Hashing) mimarisidir.
Bu rehberde, tek bir scriptin resmon değerini 0.15ms'den 0.00ms'ye nasıl indireceğinizi somut kod örnekleriyle ele alıyoruz.
1. Klasik Hata: Sabit Wait(0) ve Eski Mesafe Fonksiyonları
Acemi geliştiricilerin veya eski nesil scriptlerin en yaygın hatası, oyuncunun koordinatını saniyede yüzlerce kez eski GTA V native fonksiyonlarıyla hesaplatmaktır:
-- ❌ KAÇINILMASI GEREKEN ESKİ YÖNTEM
Citizen.CreateThread(function()
while true do
Citizen.Wait(0) -- Her karede (frame) çalışır, işlemciyi tüketir!
local ped = PlayerPedId()
local pCoords = GetEntityCoords(ped)
for _, spot in pairs(Config.GarageSpots) do
-- Native mesafe hesabı çok maliyetlidir:
local dist = GetDistanceBetweenCoords(pCoords.x, pCoords.y, pCoords.z, spot.x, spot.y, spot.z, true)
if dist < 10.0 then
DrawMarker(1, spot.x, spot.y, spot.z - 1.0, 0, 0, 0, 0, 0, 0, 1.0, 1.0, 1.0, 0, 150, 255, 100, false, true, 2, false, nil, nil, false)
if dist < 2.0 then
-- Etkileşim tuşu kontrolü
end
end
end
end
end)Bu yaklaşımda oyuncu haritanın öbür ucunda (örneğin Paleto Bay'de) bile olsa, Los Santos'taki 40 garaj noktası her karede (Wait(0)) mesafe kontrolünden geçirilir. Sonuç: Resmon tablosunda kırmızı yanan scriptler!
GetDistanceBetweenCoords bir FiveM native çağrısıdır. Lua sanal makinesinden C++ çekirdeğine geçiş maliyeti yaratır. Bunun yerine modern FiveM Lua 5.4 vektör farkı operatörünü (#) kullanmalısınız.2. Vektör Farkı Operatörü: #(v1 - v2) Gücü
FiveM Lua ortamında iki koordinat arasındaki mesafeyi ölçmenin en hafif ve hızlı yolu vektör çıkarma işlemidir. Native çağırmak yerine saf Lua matematiği kullanır ve CPU yükünü yaklaşık %70 oranında azaltır.
-- ✅ MODERN VE YÜKSEK PERFORMANSLI MESAFE ÖLÇÜMÜ
local pCoords = GetEntityCoords(PlayerPedId())
local targetCoords = vector3(215.5, -810.2, 30.5)
-- '#' operatörü vektörün uzunluğunu (magnitude) anında döndürür:
local distance = #(pCoords - targetCoords)3. Adaptif Döngü (Dynamic Sleep) Stratejisi
Bir oyuncu etkileşim noktasından uzaktaysa döngünün her 1 milisaniyede bir dönmesine gerek yoktur. Oyuncu noktadan uzaklaştıkça döngü uyuma süresini (sleep interval) dinamik olarak artırmalıyız:
- 100+ metre uzakta: Her 1500ms (1.5 saniye) kontrol et.
- 20-50 metre mesafede: Her 500ms kontrol et.
- 10 metre mesafede: Marker çizimi için
Wait(0)moduna geç.
Örnek Adaptif Döngü Kodu:
-- client/cl_garages.lua
local garagePoints = {
vector3(215.1, -810.0, 30.7),
vector3(-340.2, -870.5, 31.2),
vector3(1150.8, -320.1, 69.2)
}
CreateThread(function()
while true do
local sleep = 1500 -- Varsayılan olarak işlemciyi dinlendir
local ped = PlayerPedId()
local pCoords = GetEntityCoords(ped)
for i = 1, #garagePoints do
local spot = garagePoints[i]
local distance = #(pCoords - spot)
if distance < 25.0 then
sleep = 0 -- Marker çizimi ve akıcı görüntü için kare başına düşür
DrawMarker(36, spot.x, spot.y, spot.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 30, 144, 255, 180, false, false, 2, true, nil, nil, false)
if distance < 2.0 then
-- Ekrana bildirim basma veya E tuşu kontrolü
end
elseif distance < 60.0 and sleep > 300 then
sleep = 300 -- Oyuncu yaklaşıyor, kontrol sıklığını artır
end
end
Wait(sleep)
end
end)sleep değişkenini döngü başında en yüksek değere (örneğin 1500) eşitleyin. Şartlar sağlandığında sleep = 0 değerine çekin. Böylece oyuncu hiçbir etkileşim alanında değilken script Resmon'da tam olarak 0.00ms tüketecektir.4. İleri Düzey: Spatial Hashing (Mekânsal Izgara) Mantığı
Sunucunuzda 500'den fazla etkileşim noktası (örneğin evler, depolar, dükkanlar) varsa, adaptif loop bile bir noktada for döngüsünde 500 elemanı taramak zorunda kalır. Spatial Hashing, haritayı hayali hücrelere (grid) böler.
İstemci, yalnızca kendi bulunduğu ızgara hücresindeki ve komşu 8 hücredeki noktaları denetler. 500 nokta yerine her döngüde sadece 3-5 nokta kontrol edilir.
-- Basit Spatial Grid Hash Fonksiyonu
local GRID_SIZE = 100.0 -- 100x100 metrelik kare hücreler
local function GetCellKey(coords)
local cx = math.floor(coords.x / GRID_SIZE)
local cy = math.floor(coords.y / GRID_SIZE)
return string.format("%d:%d", cx, cy)
endBu yöntemle devasa ölçekli envanter zemin eşyaları (ground drops) ve mülk sistemleri sıfır gecikmeyle çalıştırılır.
5. Hazır ve Optimize Altyapılarla Zaman Kazanın
Tüm bu adaptif mimarileri sıfırdan kurmak, yüzlerce scripti elden geçirmek ve her etkileşim için ayrı hash algoritmaları geliştirmek ciddi bir geliştirici mesaisi gerektirir.
Eğer bu optimizasyonlarla sıfırdan uğraşmak istemiyorsanız, tüm meslek ve garaj sistemleri en baştan adaptif döngülerle optimize edilmiş DxAV1 - Roleplay Paketi çözümümüzü inceleyebilir veya mevcut sistemlerinizi profesyonelce elden geçirmek için Developerlik Hizmeti paketimizden faydalanabilirsiniz.
Sıkça Sorulan Sorular (SSS)
1. Wait(0) ile Wait(1) arasında performans farkı var mı?
Evet. FiveM istemcisinde Wait(0), bir sonraki oyun karesine (frame) kadar bekler (60 FPS için ~16ms). Ancak Wait(1) Windows işletim sisteminin timer çözünürlüğüne bağlı olarak 1ms ile 15ms arasında tutarsız gecikmelere sebep olabilir. Ekrana DrawMarker, 3D Text veya HUD çiziyorsanız Wait(0), arka plan kontrollerinde ise en az Wait(250) ve üzeri değerler tercih edilmelidir.
2. DrawMarker yerine ox_target kullanmak FPS'i artırır mı?
Kesinlikle. ox_target veya genel hedefleme kütüphaneleri, ekrana sürekli marker çizmek yerine raycast (ışın izleme) ve mesafe kontrolü mantığıyla çalışır. Ekranda sürekli render edilen ışık ve 3D efekt yükünü ortadan kaldırarak istemci ekran kartını ve işlemcisini rahatlatır.
3. Tüm scriptlerimi adaptif döngüye çevirdiğimde oyuncular ne kazanır?
Ortalama 80-100 kaynak (resource) barındıran bir sunucuda oyuncuların ortalama resmon tüketimi 2.50ms seviyelerinden 0.40ms seviyelerine geriler. Bu da oyuncuların kalabalık alanlarda yaşadığı FPS düşüşlerini doğrudan %25 ile %40 oranında engeller.
