GTAMulti.com - Türkiye'nin Türkçe GTA Sitesi

[RAGE:MP] Düşük CPU & RAM Tüketimi İçin Kodlama Taktikleri

TREND Bu konu GTAMulti Trend tablosunda #1. sırada!

Başlatan Krips Je, Dün, 23:23:49

« önceki - sonraki »

0 Üye ve 2 Ziyaretçi konuyu incelemekte.

Krips Je

İyi Akşamlar, Ben Krips.

Bu konuda RAGE:MP sunucularını yazarken dikkat edilmesi gereken performans odaklı kodlama yöntemlerini paylaşacağım. Sunucunuz ister 5 kişi çeksin, ister 100 kişiyle dolsun, kötü yazılmış kodlar yüzünden CPU ve RAM hızlıca tükenir. Bu da hem lag, hem de çökme demektir. O yüzden bu konuda bunlar hakkında bir kaç bilgi paylaşmak isterim sizlerle.

O halde kolları sıvıyoruz ve başlıyoruz..  :oku2:



1. setInterval / setTimeout Kullanımı

Birçok gelistirici oyuncu başına ayrı timerler açıyor. Bu da RAM ve CPU tüketimini katlayarak arttırıyor. Aynı işlemi tek bir global döngüyle çözmek mümkün.

Yanlış kullanım:
Kod (js) Seç
mp.events.add("playerJoin", (player) => {
    setInterval(() => {
        player.outputChatBox("POS: " + player.position);
    }, 100);
});

Doğru kullanım:
Kod (js) Seç
setInterval(() => {
    mp.players.forEach(player => {
        if (player.isLoggedIn) {
            player.outputChatBox("POS: " + player.position);
        }
    });
}, 1000); // tek donguye tuk oyunculari sigdirmak



2. Event Dinleyicilerinde Tekil Yapı Kullan

Aynı eventi birden fazla dosyada dinlemek yerine tek bir yerde yönet. Her yeni dinleyici bellekte yer kaplar.

Yanlış:
Kod (js) Seç
// admin komutlari vb.

mp.events.add("playerEnterVehicle", (player, vehicle) => {

    // admin loglari vb.
});

// speedcheck

mp.events.add("playerEnterVehicle", (player, vehicle) => {

// hız uyarısı

});

Doğru:
Kod (js) Seç
mp.events.add("playerEnterVehicle", (player, vehicle) => {

    // admin log
    // hız kontrol

});



3. Timer Pool Sistemi Kur

Her fonksiyon için ayrı timer yerine, tek bir döngü ile tüm zamanlanmış görevleri kontrol etdirebilirsin hatda özellikle yüzlerce oyunculu sunucularda büyük fark yaratır.

Kod (js) Seç
// basit timer pool sistemi

let timers = [];

function createTimer(callback, delay) {
    timers.push({
        callback: callback,
        delay: delay,
        lastRun: Date.now()
    });
}

setInterval(() => {
    const now = Date.now();
    for (const timer of timers) {
        if (now - timer.lastRun >= timer.delay) {
            timer.callback();
            timer.lastRun = now;
        }
    }
}, 500);



4. Gereksiz JSON.parse / stringify Kullanımından Kaçmak

Her işlemde büyük veri objelerini 'JSON.stringify' ve 'JSON.parse' ile çeviriyorsan, CPU boş yere yorulur.

Yanlış:
Kod (js) Seç
player.call("updateUI", [JSON.stringify(player.data)]);

Doğru:
Kod (js) Seç
player.call("updateUI", [player.data.uiData]); // gereksiz yere kullanmamaya ozen goster.



5. entityStreamIn / streamOut İçin Hafif Veri Gönder

Oyuncu başka bir oyuncuyu gördüğünde entityStreamIn tetiklenir. Bu noktada büyük veri gönderirsen, FPS düşüşü yaşanır.

Mesela:

- Stream in anında sadece gerekli veriler gönderilmeli.
- Büyük veri transferi login esnasında yapılmalı.
- Görsel detaylar client tarafında yönetilmeli.
- vb.



6. Gereksiz Syncleri Kaldırın

RAGE:MP zaten birçok veriyi senkronize ediyor. Pozisyon, hız, yön gibi verileri her tick manuel olarak sync etmeye gerek yok.

Yanlış:
Kod (js) Seç
setInterval(() => {
    mp.players.forEach(player => {
        player.call("updatePosition", [player.position]); // gereksiz bir update
    });
}, 100);

Doğru:
Pozisyon gibi native sync lenen verileri tekrar sync etme.
Sadece custom veriler için çağrı yap.
Her tick veri göndermek yerine, değişiklik olduğunda tetikle.



7. Global Data Kullanımında Dikkatli Ol

Sunucu tarafında her oyuncu için ayrı veri saklamak gerekirken, yanlış yapılan şeylerden biri global değişkenlerde oyuncuya özel bilgi tutmaktır. Bu, veri çakışmalarına ve bellek hatalarına neden olur.

Yanlış:
Kod (js) Seç
// tüm oyuncuların aynı değişkeni paylaşması;

let lastCommandTime;

mp.events.addCommand("test", (player) => {
    lastCommandTime = Date.now();
});

Doğru:
Kod (js) Seç
// oyuncuya özel veri tut;

mp.events.addCommand("test", (player) => {
    player.lastCommandTime = Date.now();
});

Bu şekilde her oyuncunun verisi kendi içinde izole olur, daha güvenli ve kararlı olur.



8. Gereksiz Loglama & outputChatBox Kullanımı

Sunucu tickleri sırasında aşırı log veya oyuncuya mesaj göndermek, FPS ve CPU yu yorar. Özellikle her tick veya sık tetiklenen eventlerde bundan kaçınılmalı.

Yanlış:
Kod (js) Seç
setInterval(() => {
    console.log("bu oyuncu suanda aktif.");
    player.outputChatBox("aktif mi ?");
}, 100);

Doğru:
Kod (js) Seç
// sadece durum değiştiğinde mesaj verdir;

if (!player.afkNotified && player.afk) {
    player.outputChatBox("afk mode on.");
    player.afkNotified = true;
}



9. Fonksiyonları Parçala, Tek Sorumluluk Prensibi Uygula

Her fonksiyonun sadece tek iş yapması, hem debug sürecini kolaylaştırır hem de belleği daha verimli kullanmanı sağlar.

Yanlış:
Kod (js) Seç
function processPlayer(player) {
    checkAFK(player);
    updateHealth(player);
    syncPosition(player);
    givePaycheck(player);
    // hepsi bir arada
}

Doğru:
Kod (js) Seç
// her işlem icin ayrı fonksiyon;

processAFK(player);
processHealth(player);
processSync(player);
processPaycheck(player);

Bölünmüş yapı, hata ayıklama ve optimizasyon için şart.



10. Oyuncu Disconnect / Crash Sonrası Temizleme

Oyuncu sunucudan ayrıldığında arkasında kalan tüm referansları temizlemen gerekir. Aksi takdirde "memory leak" oluşur.

Yapılması gerekenler:

Tüm setInterval ve setTimeout fonksiyonlarını clear et.
Oyuncuya özel event listener varsa kaldır.
MySQL bağlantısı varsa kapat ya da serbest bırak.
Oyuncu datasını RAM den sil.

Kod (js) Seç
mp.events.add("playerQuit", (player) => {
    clearInterval(player.myTimer);
    delete player.customData;
});



11. Gereksiz require / import Kullanımına Dikkat

Sunucu başlarken binlerce modül gereksiz şekilde içeri alınırsa, boot süresi uzar ve bellek gereksiz yere dolarş


Gereksiz tüm bağımlılıkları temizle, sadeleştir.



12. MySQL Sorgularında LIMIT Kullanmayı Unutma

Veritabanından bilgi çekerken, LIMIT koymadığın sorgular büyük tabloları baştan sona tarar. Bu da ciddi performans kaybı yaratır.

Yanlış:
Kod (js) Seç
connection.query("SELECT * FROM users WHERE username = ?", [name]);

Doğru:
Kod (js) Seç
connection.query("SELECT * FROM users WHERE username = ? LIMIT 1", [name]);

Ek olarak SELECT yerine COUNT gibi işlemler için de aynı mantık geçerlidir.



13. ClientSide Kodlarda Performans

Server kadar önemli bir diğer konu da client tarafındaki kodların performansıdır. Özellikle render işlemleri dikkatli yönetilmeli.

Öneriler:

Her frame çizilen UI elemanları minimumda tutulmalı.
mp.events.add("render", ...) içerisine karmaşık hesaplamalar konmamalı.
HTML + CEF arayüzlerde sade CSS/JS tercih edilmeli.
FPS düşüşlerini görmek için mp.game.graphics.getFPSLimit() ve devtools izlenebilir.



14. N1 Sorgu Sorunu

ORM veya manuel SQL kullananlar bazen farkında olmadan N+1 hatasına düşer. Bu da döngü içinde sürekli sorgu çalıştırmak anlamına gelir.

Yanlış:
Kod (js) Seç
players.forEach(p => {
    db.query("SELECT * FROM bans WHERE user_id = ?", [p.sqlid]);
});

Doğru:
Kod (js) Seç
let ids = players.map(p => p.sqlid);
db.query("SELECT * FROM bans WHERE user_id IN (?)", [ids]);

Bu şekilde 100 oyuncu için 100 sorgu yerine tek sorgu çalıştırmış olursun.



Final (Devam Edecek...)




Konu zamanla güncellenmeye devam edecek. Yeni ipuçları ve örneklerle ileride daha fazla detay ekleyeceğim. Senin de katkıların olursa, yorum olarak belirtmen yeterde artar :)

Bu konudaki taktikler uzun vadede CPU ve RAM kullanımını ciddi şekilde azaltır. Özellikle kalabalık saatlerde sunucunun stabil kalmasını sağlar. Düzgün kodlanmış bir sunucu hem daha az sorun çıkarır, hem oyuncuya daha akıcı deneyim sunar.

Eğer senin de eklemek istediğin bir yöntem ya da öneri varsa, yorumlara yazabilirsin. Elimden geldiğince yanıtlarım :serefe:
Son düzenlenme: Dün, 23:29:57 Krips Je
"Kodunu yaz, gerisini compiler düşünsün." - Meçhul Yazılımcı
    

Krips Je

atladığım ve anlatmayı unuttuğum kısımlar mevcut ise bu konu üzerinden iletebilirsiniz.
iyi akşamlar dilerim  :aynen:

"Kodunu yaz, gerisini compiler düşünsün." - Meçhul Yazılımcı
    

Feovac

Faydalı içerik kaliteli developer. +ref  :serefe:

Türkiye'nin En Büyük Mobil/PC Discord Topluluğu
Samp Media : discord.gg/sampmedia
Side Roleplay : discord.gg/siderpg
Azteca Deathmatch : discord.gg/azteca

Purgatory

Ellerinize sağlık, her ne kadar bu işlerden anlamasam da yapılan iş üzerinde bu şekilde düzenlemeler yapıp kodu optimize hale gietirip CPU ve RAM kullanımını ideal seviyede tutmak muhakkak iyi bir şeydir diye düşünüyorum. Bu biraz da metin yazıp ya da çeviri yapıp daha sonra cümlelerdeki amlam belirsizliklerini, anlatım bozukluklarını, dilbilgisi ve yazım yanlışlarını ayıklamaya, kullanılabilecek daha kısa cümleler varsa uzun cümleleri bu kısa cümlelerle değiştirmeye benziyor. Yani en azından amaç benzer: Daha derli toplu bir iş çıkarmak ve son kullanıcının daha iyi bir deneyim yaşamasını sağlamak.

Neyse, konu için teşekkürler ve tekrar ellerinize sağlık.
Son düzenlenme: Bugün, 09:54:54 Purgatory

Krips Je

Alıntı yapılan: Purgatory - Bugün, 09:53:47
Ellerinize sağlık, her ne kadar bu işlerden anlamasam da yapılan iş üzerinde bu şekilde düzenlemeler yapıp kodu optimize hale gietirip CPU ve RAM kullanımını ideal seviyede tutmak muhakkak iyi bir şeydir diye düşünüyorum. Bu biraz da metin yazıp ya da çeviri yapıp daha sonra cümlelerdeki amlam belirsizliklerini, anlatım bozukluklarını, dilbilgisi ve yazım yanlışlarını ayıklamaya, kullanılabilecek daha kısa cümleler varsa uzun cümleleri bu kısa cümlelerle değiştirmeye benziyor. Yani en azından amaç benzer: Daha derli toplu bir iş çıkarmak ve son kullanıcının daha iyi bir deneyim yaşamasını sağlamak.

Neyse, konu için teşekkürler ve tekrar ellerinize sağlık.

Aslında yazarken "anlamayan da okuyunca bir şeyler kapabilsin" kafasıyla gittim ama haklısın, bazı yerler biraz dolambaçlı olmuş. İlk fırsatta sadeleştirip daha okunabilir hale getirmeye çalışırım.

Geri bildirimin not edildi, böyle yapıcı yorumlar cidden işe yarıyor. Tekrar sağ ol. :)

"Kodunu yaz, gerisini compiler düşünsün." - Meçhul Yazılımcı