Metin2 Haritada Fazla Metin Taşlarının Kastırma Sorunu FİX

  • Konuyu açan Konuyu açan Battle2
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 7
  • Gösterim Gösterim 370

Battle2

Üye
Üye
Mesaj
34
Çözümler
3
Beğeni
29
Puan
329
Ticaret Puanı
0
Merhabalar varmı bilmiyorum ama bunuda burada paylaşmak istedim :)

Bir haritaya 200 den fazla metin sabitlediniz ve oyun açık afk bıraktınız bir geldiniz hop client tahtalı köye gitmiş bu fix ile sorun kalmayacaktır


Client/UserInterface/InstanceBase.cpp 'Aç:
Genişlet Daralt Kopyala
//Arat
void CInstanceBase::Update() {   //Altına yapıştır

 // --- METIN TASI DONMA ENGELLEME FIXI ---
    if (IsStone())
    {
        CInstanceBase* pMainInstance = CPythonCharacterManager::Instance().GetMainInstancePtr();
        if (pMainInstance)
        {
            // Orijinal altyapınızla uyumlu koordinat değişkenleri
            TPixelPosition kMainPos;
            TPixelPosition kStonePos;

            // Pozisyonları güvenli fonksiyonlarla çekiyoruz
            pMainInstance->NEW_GetPixelPosition(&kMainPos);
            NEW_GetPixelPosition(&kStonePos);

            // İki koordinat arasındaki mesafeyi hesaplıyoruz
            float fDx = kStonePos.x - kMainPos.x;
            float fDy = kStonePos.y - kMainPos.y;
            float fDist = sqrt(fDx * fDx + fDy * fDy);
      
            // Uzaktaki taşları gizle ve altındaki ağır işlemleri atla
            if (fDist > 2000.0f)
            {
                Hide(); // Taşın modelini ve efektlerini render dışı bırakır
                return; // Fonksiyonu burada keserek aşağıdaki ağır süreçlerin çalışmasını engeller
            }
            else
            {
                Show(); // Oyuncu yaklaştığında taşı tekrar görünür yapar ve günceller
            }
        }
    }
 

Dosya Eklentileri

  • FİX.webp
    FİX.webp
    62 KB · Gösterim: 144
Son düzenleme:
Dostum selamlar,
Bu gibi kısa kodları genelde incelerim. Merakıma geldi. İnceledim. Ancak kodları çok sağlıklı bulmadım doğrusu.
Mesela taşlarda:
  1. model yükleme
  2. texture yükleme
  3. effect oluşturma
  4. particle
  5. shadow
  6. animation
  7. collision
  8. render instance oluşturma
  9. effect attach/detach
  10. LOD
  11. visibility
gibi işlemler varsa, client kapatılıp açıldığında bunların hepsi tekrar gerçekleşebilir.

Bu kod ise:
"Uzak taşı gizleyeyim, Update'in geri kalanını çalıştırmayayım."
diyor.
Ama taş zaten oluşturulmuş ve kaynakları yüklenmiş olabilir. Dolayısıyla bellekte/CPU/GPU tarafında asıl yük çoktan oluşmuş olabilir. Çünkü işlemi bi nevi kökten durdurmak yerine, üzerine maske atıyosun. En azından ben öyle anladım. Yanlışım varsa lütfen düzeltin.

Birde ek olarak,
C++:
Genişlet Daralt Kopyala
            // Uzaktaki taşları gizle ve altındaki ağır işlemleri atla
            if (fDist > 2000.0f)
            {
                Hide(); // Taşın modelini ve efektlerini render dışı bırakır
                return; // Fonksiyonu burada keserek aşağıdaki ağır süreçlerin çalışmasını engeller
            }
            else
            {
                Show(); // Oyuncu yaklaştığında taşı tekrar görünür yapar ve günceller
            }
Bu kısım, Oyuncu her 2000.0f alanına girdiğinde sadece metinler değil, her frame üzerinde çalışabilir. Buga veya soruna yol açabilecek bir çok olay gerçekleşebilir. Çünkü 1 kez çalışmıyor kod, sürekli çalışıyor ve sabit bir şeyi gizlemiyor/göstermiyor.

Bunları eleştirmek için söylemiyorum yanlış anlaşılma olmasın. Kendim kod pratikleri yapmak için bu tarz kodları okuyorum. Hem daha çok şey öğreniyorum hemde kim nasıl kod yazıyor onu görüyorum.

Çözüm olarak çok fazla şey var aslında ama aklımda mantıklı olabilecek şöyle bir şey yapılabilir diye düşünüyorum.

show/hide için,
Mesafeyi Update() içerisinde sürekli sqrt() ile hesaplamak yerine visibility/LOD sistemine bağlamak daha mantıklı.
Mesela şöyle ;
C++:
Genişlet Daralt Kopyala
if (IsStone())
{
    const float fDistance = ...;

    if (fDistance > STONE_VIEW_DISTANCE)
    {
        if (IsShow())
            Hide();
    }
    else
    {
        if (!IsShow())
            Show();
    }
}

Diğer bir konu için, render mesafesi fixinden ziyade resource/preload/cache tarafını incelemek lazım. Oralarda bir fix uygulayabilirsen hem daha çok performans odaklı olur. Hemde ortaya çıkabilecek sorun/bug daha az olur ya da hiç olmaz.
 
Dostum selamlar,
Bu gibi kısa kodları genelde incelerim. Merakıma geldi. İnceledim. Ancak kodları çok sağlıklı bulmadım doğrusu.
Mesela taşlarda:
  1. model yükleme
  2. texture yükleme
  3. effect oluşturma
  4. particle
  5. shadow
  6. animation
  7. collision
  8. render instance oluşturma
  9. effect attach/detach
  10. LOD
  11. visibility
gibi işlemler varsa, client kapatılıp açıldığında bunların hepsi tekrar gerçekleşebilir.

Bu kod ise:
"Uzak taşı gizleyeyim, Update'in geri kalanını çalıştırmayayım."
diyor.
Ama taş zaten oluşturulmuş ve kaynakları yüklenmiş olabilir. Dolayısıyla bellekte/CPU/GPU tarafında asıl yük çoktan oluşmuş olabilir. Çünkü işlemi bi nevi kökten durdurmak yerine, üzerine maske atıyosun. En azından ben öyle anladım. Yanlışım varsa lütfen düzeltin.

Birde ek olarak,
C++:
Genişlet Daralt Kopyala
            // Uzaktaki taşları gizle ve altındaki ağır işlemleri atla
            if (fDist > 2000.0f)
            {
                Hide(); // Taşın modelini ve efektlerini render dışı bırakır
                return; // Fonksiyonu burada keserek aşağıdaki ağır süreçlerin çalışmasını engeller
            }
            else
            {
                Show(); // Oyuncu yaklaştığında taşı tekrar görünür yapar ve günceller
            }
Bu kısım, Oyuncu her 2000.0f alanına girdiğinde sadece metinler değil, her frame üzerinde çalışabilir. Buga veya soruna yol açabilecek bir çok olay gerçekleşebilir. Çünkü 1 kez çalışmıyor kod, sürekli çalışıyor ve sabit bir şeyi gizlemiyor/göstermiyor.

Bunları eleştirmek için söylemiyorum yanlış anlaşılma olmasın. Kendim kod pratikleri yapmak için bu tarz kodları okuyorum. Hem daha çok şey öğreniyorum hemde kim nasıl kod yazıyor onu görüyorum.

Çözüm olarak çok fazla şey var aslında ama aklımda mantıklı olabilecek şöyle bir şey yapılabilir diye düşünüyorum.

show/hide için,
Mesafeyi Update() içerisinde sürekli sqrt() ile hesaplamak yerine visibility/LOD sistemine bağlamak daha mantıklı.
Mesela şöyle ;
C++:
Genişlet Daralt Kopyala
if (IsStone())
{
    const float fDistance = ...;

    if (fDistance > STONE_VIEW_DISTANCE)
    {
        if (IsShow())
            Hide();
    }
    else
    {
        if (!IsShow())
            Show();
    }
}

Diğer bir konu için, render mesafesi fixinden ziyade resource/preload/cache tarafını incelemek lazım. Oralarda bir fix uygulayabilirsen hem daha çok performans odaklı olur. Hemde ortaya çıkabilecek sorun/bug daha az olur ya da hiç olmaz.
Aslında geliştirilmeye müsait evet bu kodu denediğimde hem mevcut mesafedeki metinler gözüküyor hemde çok uzaktaki metinler hiç görünmüyor hatta bu kodu kullanmadan önce 10 dakika içerisinde client donmaya başlıyordu şuan bir sıkıntı yaşatmıyor ileride deneyip göreceğim bir alt yapı files hazırlıyorum hem test etmiş olurum buğ felan oluyormu hemde kendimi geliştiriyor olacağım yorumun için teşekkürler :)
 
Aslında geliştirilmeye müsait evet bu kodu denediğimde hem mevcut mesafedeki metinler gözüküyor hemde çok uzaktaki metinler hiç görünmüyor hatta bu kodu kullanmadan önce 10 dakika içerisinde client donmaya başlıyordu şuan bir sıkıntı yaşatmıyor ileride deneyip göreceğim bir alt yapı files hazırlıyorum hem test etmiş olurum buğ felan oluyormu hemde kendimi geliştiriyor olacağım yorumun için teşekkürler :)
Changelog gelir mi peki 😄
 
Bu metin taşları herkesin başına bela..
Fikir güzel ama kodun iyileştirilmesi açısından birkaç düzenleme ve ekleme yapılmalı gibi..
Gereksiz fonksiyon çağrıları ve gereksiz hesaplamalar yaparak getirisiyle birlikte götürüsü de olan bir kod olmuş, bu sebeple yapay zekaların verdiği kodları körü körüne kullanmamak gerek.

İlk olarak kodun eklendiği yer yanlış, Update içine eklense bile metin taşları çizim işleminde mantıksal varlığını koruyacaktır. Bir obje görünmüyor diye arkaplanda da "çizilmiyor" demek değildir.
Update içine verdiğin kod yerine şunu eklemek performans açısından daha fazla etki edecektir:
C++:
Genişlet Daralt Kopyala
void CInstanceBase::Update()
{
    ++ms_dwUpdateCounter;   

    if (IsStone())
    {
        m_GraphicThingInstance.RotationProcess();
        ProcessDamage();
        
        // metin taşları için AŞAĞIDAKİ diğer işlemlerin hiçbirinin çağrılmasına gerek yok
        return; // o yüzden fonksiyondan tamamen çıkılabilir.
    }
    ...
    ...
}

Metin taşlarını gerçek anlamda render aşamalarından kaldırmak için ise şöyle yapmak daha iyi:
C++:
Genişlet Daralt Kopyala
bool CInstanceBase::__CanRender()
{
    if (!__IsInViewFrustum())
        return false;
    
    // Buraya ekle
    if (IsStone())
    {
        CInstanceBase* pkInstMain = __GetMainInstancePtr();
        if (pkInstMain)
        {
            const float METIN_STONE_CHECK_DISTANCE = 2000.0f * 2000.0f;

            TPixelPosition chrPos, stonePos;
            pkInstMain->NEW_GetPixelPosition(&chrPos);
            NEW_GetPixelPosition(&stonePos);

            float fDx = stonePos.x - chrPos.x;
            float fDy = stonePos.y - chrPos.y;
            
            // minik not: 'mümkün olduğunca' sqrt kullanmayın
            float fDist = (fDx * fDx) + (fDy * fDy);

            if (fDist > METIN_STONE_CHECK_DISTANCE)
                return false;
        }
    }
    
    ....
    ....
    ....
    return true;
}
 
Geri
Üst