Metin2 beceri.lua ile Hasar ve Performans Optimizasyonu

29.11.2025 admin 20 görüntülenme
Metin2 beceri.lua ile Hasar ve Performans Optimizasyonu

Metin2 sunucu yönetiminde, oyunun kalbi veritabanı (SQL) ise, sinir sistemi Lua (Quest) dosyalarıdır. Genellikle "Npc'den P yapma" işlemi basit bir script gibi görülse de, binlerce oyuncunun aynı anda yetenek kullandığı, savaştığı ve ışınlandığı bir ortamda beceri.lua dosyasının yapısı, oyunun "akıcılığını" ve "hasar tutarlılığını" (Damage Stability) doğrudan etkiler.

Bir oyuncunun "Ekranda vurdum görünüyor ama hasar işlemiyor" (Miss/Sync Loss) şikayetinin arkasında, genellikle optimize edilmemiş quest dosyalarının yarattığı mikrosaniye bazlı sunucu gecikmeleri (Quest Lag) yatar. Bu makalede, skill_proto tablosundaki matematiksel formüllerin kusursuz çalışması için beceri.lua tarafında yapılması gereken mimari optimizasyonları inceleyeceğiz.

Geleneksel Yöntemlerin Yarattığı "Hayalet Hasar" Sorunu

Eski nesil server dosyalarında (2010-2014 dönemi yaygın fileslar), yetenek yönetimi uzun if-elseif-else bloklarıyla yapılırdı.

Örneğin, klasik bir P NPC kodu şöyledir:

Lua
if pc.get_job() == 0 and pc.get_skill_group() == 1 then -- Bedensel
    pc.set_skill_level(1, 59)
    -- ... alt alta 6 satır
elseif pc.get_job() == 0 and pc.get_skill_group() == 2 then -- Zihinsel
    -- ... alt alta 6 satır
-- ... ve diğer 8 sınıf için devam eder

Bu Yapı Neden Hasarı Bozar?

Sunucu tarafında (Server-Side), her oyuncu bu Npc'ye tıkladığında veya bir "yetenek sıfırlama" parşömeni kullandığında, işlemci bu satırları tek tek okur. Anlık 2000 oyuncunun olduğu bir sunucuda, bir lonca savaşı sırasında bu scriptin tetiklenmesi I/O darboğazı yaratır.

Bu darboğazın sonucu şudur:

Reklam
gd
  1. Veritabanı Gecikmesi: pc.set_skill_level komutu MySQL'e geç ulaşır.

  2. Senkronizasyon Hatası: Oyuncu istemcide (Client) yeteneğini P görür, ancak sunucu o anki yoğunluktan dolayı veritabanındaki seviyeyi güncelleyememiş olabilir.

  3. Sonuç: Oyuncu "Hava Kılıcı"nı yakar, ancak sunucu bunu hala G1 seviyesinde algılar. skill_proto'daki szMasterBonusPoly formülü maksimum seviyeden değil, daha düşük seviyeden hesaplanır. Oyuncu düşük vurur ve oyunun "bozuk" olduğunu düşünür.

Çözüm: "Lookup Table" (Arama Tablosu) Mimarisi

Modern ve optimize bir Metin2 altyapısında, yetenek yönetimi dinamik tablolarla yapılır. Bu yöntem, işlemci yükünü %90 oranında azaltır ve hasar hesaplamalarının anlık olarak veritabanına işlenmesini garanti eder.

Matematiksel Grup Hesaplaması

Metin2'de karakter sınıfları (Job ID) 0 ile 7 arasındadır. Ancak her sınıfın iki alt grubu (Skill Group) vardır. Bu karmaşayı çözmek için if kullanmak yerine matematiksel bir indeksleme kullanmalıyız:

Formül: (Job ID * 2) + (Skill Group - 1)

Bu formül bize şu indeksleri verir:

  • Bedensel Savaşçı: 0

  • Zihinsel Savaşçı: 1

    Reklam
    d2
  • Yakın Dövüş Ninja: 2

  • Uzak Dövüş Ninja: 3

  • ... ve devam eder.

Optimize Edilmiş Tam Kod Yapısı

Aşağıdaki kod bloğu, hem P verme işlemini, hem pasif yetenekleri (Kombo vb.) hem de "At Becerilerini" tek seferde, gecikmesiz işler.

Lua
quest skill_optimizer begin
    state start begin
        function SetPerfectSkills()
            -- Karakterin meslek ve grup bilgisini al
            local job = pc.get_job()
            local group = pc.get_skill_group()

            -- HATA KONTROLÜ: Grup seçmemiş oyuncuya skill verilirse karakter buga girer
            if group == 0 then
                syschat("Sistem: Önce bir eğitimciye gidip beceri grubu seçmelisiniz.")
                return false
            end

            -- Yetenek Haritası (Skill Vnum Listesi)
            local skill_map = {
                [0] = {1, 2, 3, 4, 5, 6},         -- Bedensel
                [1] = {16, 17, 18, 19, 20, 21},   -- Zihinsel
                [2] = {31, 32, 33, 34, 35, 36},   -- Bıçakçı
                [3] = {46, 47, 48, 49, 50, 51},   -- Okçu
                [4] = {61, 62, 63, 64, 65, 66},   -- Büyülü Silah
                [5] = {76, 77, 78, 79, 80, 81},   -- Kara Büyü
                [6] = {91, 92, 93, 94, 95, 96},   -- Ejderha Gücü
                [7] = {106, 107, 108, 109, 110, 111} -- İyileştirme
            }

            -- Matematiksel İndeksleme
            local target_index = (job * 2) + (group - 1)

            -- Eğer tablo içinde bu indeks varsa işlemi uygula
            if skill_map[target_index] then
                -- 1. Aktif Yetenekleri P Yap (Level 59)
                for _, skill_vnum in ipairs(skill_map[target_index]) do
                    pc.set_skill_level(skill_vnum, 59)
                end

                -- 2. Pasif Yetenek Optimizasyonu (Kritik Öneme Sahip)
                -- Kombo (122): 2 yapılmazsa DPS (Saniye başı hasar) %30 düşer.
                pc.set_skill_level(122, 2) 
                -- Liderlik (121): P yapılmazsa grup bonusları (saldırı değeri) çalışmaz.
                pc.set_skill_level(121, 40)
                -- Dönüşüm (129): Boss keserken hasar maksimizasyonu için şarttır.
                pc.set_skill_level(129, 40)
                -- Madencilik (124) ve At Çağırma (131)
                pc.set_skill_level(124, 40)
                pc.set_skill_level(131, 10)

                -- 3. At Yetenekleri (Asker At Kitabı varsa)
                if pc.get_horse_level() == 21 then
                    pc.set_skill_level(137, 20) -- At Yürüyüşü
                    pc.set_skill_level(138, 20) -- At Güç Dalgası
                    pc.set_skill_level(139, 20) -- At Saldırısı
                end

                syschat("Sistem: Tüm yetenekler ve pasif bonuslar optimize edildi.")
                return true
            else
                syschat("Hata: Bilinmeyen beceri grubu.")
                return false
            end
        end

        when 20094.chat."Becerileri Sıfırla ve P Yap" begin
            -- Fonksiyonu çağır
            skill_optimizer.SetPerfectSkills()
            
            -- Affect Temizliği (Önemli)
            -- Biyolog görevleri hariç tüm geçici etkileri temizleyip tekrar yüklemek gerekir.
            -- Ancak affect.remove_all() tehlikelidir, sadece skill affectleri silinmeli.
            -- Bu detay genelde C++ (Source) tarafında handle edilir.
        end
    end
end

Pasif Yeteneklerin "Gizli" Hasar Etkisi

Geliştiricilerin skill_proto ayarlarken gözden kaçırdığı en büyük detay Kombo (Combo) yeteneğidir.

  • Sorun: Eğer beceri.lua dosyanız oyuncuya Kombo yeteneğini (ID: 122) seviye 2 olarak vermezse, karakterler (özellikle Savaşçı ve Ninja) düz vuruş animasyonlarını (hit animation) tamamlayamaz veya iptal edemez (animation cancel).

  • Hasar Kaybı: Bir Bedensel Savaşçı, Kombo 2 açıkken 10 saniyede 15 vuruş yapabiliyorsa, Kombo kapalıyken sadece 11 vuruş yapar. Bu, %20'nin üzerinde bir DPS (Saniye Başına Hasar) kaybı demektir.

  • Optimizasyon: Yukarıdaki kodda gördüğünüz pc.set_skill_level(122, 2) satırı, oyuncunun potansiyel hasarının tamamını kullanabilmesini sağlayan en kritik satırdır. SQL tablosundaki hasar değerleri ne kadar yüksek olursa olsun, animasyon hızı düşükse hasar çıkmaz.

Hasar Testlerinde "Affect" (Etki) Yönetimi

Sunucunuzun hasar dengesini (PvP/PvM) ayarlarken, sürekli skill_proto düzenleyip reboot atmak yerine, Lua'nın affect sistemini bir Debug Aracı olarak kullanmalısınız.

Örneğin, "Kritik vuruş şansını %10 artırırsam oyun dengesi bozulur mu?" sorusunu test etmek için veritabanını değiştirmeyin. Lua ile oyuncuya geçici özellik verin:

Lua
-- Canlı Test Kodu
when 20095.chat."DEBUG: +10 Yarı İnsan Ver" begin
    -- apply.ATTBONUS_HUMAN (Yarı İnsan)
    -- Değer: 10, Süre: 60 saniye
    if pc.getqf("debug_bonus") == 0 then
        affect.add_collect(apply.ATTBONUS_HUMAN, 10, 60)
        syschat("DEBUG: 60 saniye boyunca Yarı İnsan bonusu aktif.")
        pc.setqf("debug_bonus", 1)
    else
        syschat("Zaten aktif bir test bonusun var.")
    end
end

Bu yöntemle, skill_proto içindeki szPointPoly (Taban Hasar) ve szMasterBonusPoly (Bonus Çarpanı) değerleri arasındaki ilişkiyi, canlı sunucuda oyunculara hissettirmeden test edebilirsiniz.

Veri Bütünlüğü ve Biyolog Çakışmaları

En tehlikeli optimizasyon hatası, beceri sıfırlama (Skill Reset) sırasında yaşanır. Bazı kötü kodlanmış questler, becerileri sıfırlarken affect.remove_all_collect() komutunu kullanır.

  • Risk: Bu komut, oyuncunun Biyolog görevlerinden (Ork Dişi, Lanet Kitabı vb.) aldığı kalıcı özellikleri de silebilir.

  • Sonuç: Oyuncunun hasarı kalıcı olarak düşer (str veya attack_grade bonusu silinir).

  • Doğru Yöntem: Beceri sıfırlama işlemlerinde asla toplu silme (remove_all) yapılmamalıdır. Bunun yerine sadece beceri grubu (Skill Group) 0 olarak ayarlanmalı ve pc.clear_skill() fonksiyonu kullanılmalıdır. Kaynak kod (Source) tarafında ClearSkill fonksiyonu sadece ilgili becerileri temizleyecek şekilde ayarlanmalıdır.

Sonuç

beceri.lua dosyası, Metin2 sunucusunun sadece bir "NPC konuşması" değil, oyunun mekanik kararlılığını sağlayan bir motor parçasıdır. Tablo tabanlı (Table-driven) yapıya geçmek, matematiksel indeksleme kullanmak ve pasif yetenekleri (Kombo gibi) zorunlu hale getirmek; sunucunuzdaki "Hasar bozuk", "Vuruyorum işlemiyor" gibi sorunları kökten çözer ve skill_proto üzerinde yaptığınız ince ayarların oyuna %100 yansımasını sağlar.

metin2 beceri.lua skill.lua metin2 quest optimizasyon metin2 p npc kodu damage sorunu çözümü metin2 hasar testi lua performans metin2 geliştirici server files metin2 pvp ayarı