aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Metin2 Event Sistemi: Otomatik Etkinlik Kurulumu

Bir metin2 event sistemi, sunucunuzun her gün belirli saatlerde OX yarışması açması, çifte drop ya da çifte EXP başlatması, balık etkinliği duyurması gibi periyodik aktiviteleri GM müdahalesi olmadan yürütmesini sağlar. İyi kurulmuş bir etkinlik döngüsü oyuncuyu düzenli olarak giriş yapmaya teşvik eder; kötü kurulmuş bir tanesi ise ekonomiyi şişirir, lag yaratır veya sunucu yeniden başladığında etkinliği "açık" sanıp kalır. Bu yazıda etkinliklerin temelinde yatan event flag mantığını, manuel GM komutlarını ve bunları quest zamanlayıcısı ya da işletim sistemi cron'u ile nasıl otomatikleştireceğinizi anlatıyorum.

Event flag: tüm etkinliklerin ortak dili

Metin2 kaynağında etkinliklerin neredeyse tamamı bir event flag üzerinden çalışır. Flag, isimle eşleşen bir tam sayıdır (örneğin double_drop = 1) ve hem oyun çekirdeği (C++) hem de quest sistemi (Lua) tarafından okunabilir. Mantık basittir: bir yerde flag'i 1 yaparsınız, drop/exp/etkinlik kodu bu değeri kontrol eder ve davranışını değiştirir, etkinlik bitince 0'a çekersiniz.

Quest tarafında iki temel fonksiyon kullanırsınız:

-- flag'i ayarla (1 = açık, 0 = kapalı)
game.set_event_flag("double_drop", 1)

-- flag'i oku
local acik = game.get_event_flag("double_drop")
if acik == 1 then
    -- etkinlik aktif
end

Bu yaklaşımın gücü, tek bir merkezi anahtarın tüm sistemleri tetiklemesidir. Drop hesaplamasından arayüz duyurusuna kadar her parça aynı flag'e bakar, böylece etkinliği açıp kapatmak tek satıra iner.

Manuel kontrol: GM komutları

Otomatikleştirmeden önce her etkinliği elle açıp kapatabilmeniz gerekir; bu hem test hem de acil durumlar için şarttır. Çoğu kaynakta bir GM, oyun içinde event flag'i doğrudan komutla değiştirebilir:

/event_flag double_drop 1   // çifte drop'u aç
/event_flag double_drop 0   // kapat

Komutun tam adı kaynağınıza göre değişebilir (cmd.cpp içinde SetEventFlag'i çağıran komutu kontrol edin). OX gibi haritası ve özel mantığı olan etkinliklerin ise kendi komutları vardır; tipik olarak etkinliği başlatan, soru soran ve kapatan üç ayrı GM komutu bulunur. Bu komutları bir GM hesabıyla doğruladıktan sonra otomasyon kurmak çok daha güvenlidir, çünkü zamanlayıcı sadece "GM'in elle yazdığı şeyi" tetikler.

Quest zamanlayıcısı ile otomatikleştirme

İçeride kalan en temiz otomasyon yöntemi, sunucunun kendi quest sistemini bir zamanlayıcı olarak kullanmaktır. Düzenli aralıkla tetiklenen bir server timer kurar, her tetiklenişte saati kontrol eder ve uygun anda flag'i değiştirirsiniz. Aşağıdaki örnek her dakika saati okur ve günde iki kez çifte drop etkinliğini açıp kapatır:

quest auto_event begin
    state start begin
        when login begin
            -- zamanlayıcıyı yalnızca bir kez başlat
            if not q.getf("running") then
                q.setf("running", 1)
                server_timer("event_tick", 60)
            end
        end

        when event_tick.server_timer begin
            local t = os.date("*t", get_global_time())
            if t.hour == 20 and t.min == 0 then
                game.set_event_flag("double_drop", 1)
                notice_all("Çifte drop etkinliği başladı! 2 saat sürecek.")
            elseif t.hour == 22 and t.min == 0 then
                game.set_event_flag("double_drop", 0)
                notice_all("Çifte drop etkinliği sona erdi.")
            end
            -- zamanlayıcıyı yeniden kur
            server_timer("event_tick", 60)
        end
    end
end

Burada üç noktaya dikkat edin: zamanlayıcıyı yalnızca bir kez başlatmak (aksi halde her girişte yeni bir tane açılır), her tetiklenişte yeniden kurmak (server timer'lar tek seferliktir) ve notice_all ile tüm sunucuya duyuru yapmak. Zamanlayıcı/fonksiyon adları kaynaktan kaynağa küçük farklar gösterebilir; kendi questlib.lua dosyanızdaki mevcut örnekleri referans alın.

Drop ve EXP çarpanını flag'e bağlamak

Quest flag'i ayarlar ama asıl çarpan etkisi oyun çekirdeğinde olur. Drop oranını flag'e duyarlı hale getirmek için char_item.cpp içindeki drop hesaplamasına bir kontrol eklersiniz:

int iEventFlag = quest::CQuestManager::instance().GetEventFlag("double_drop");
if (iEventFlag > 0)
    iDropPct *= 2;   // drop ihtimalini iki katına çıkar

Aynı mantık EXP için char.cpp içindeki tecrübe puanı kazanım fonksiyonunda, yang/para drop'u için ilgili fonksiyonda geçerlidir. Burada en sık yapılan hata, çarpanı çok agresif vermek (örneğin x5 EXP) ve etkinlik bitince flag'i sıfırlamayı unutup ekonomiyi kalıcı şişirmektir. Çarpanları ölçülü tutun ve her açtığınız flag'in mutlaka bir kapatma koşulu olduğundan emin olun.

OX, balık ve diğer haritalı etkinlikler

OX yarışması basit bir flag'den fazlasını ister: özel bir harita (genellikle ayrı bir map index'i), oyuncuları oraya ışınlama, soru-cevap döngüsü ve yanlış cevaplayanı eleme mantığı. Bu yüzden OX, çoğu kaynakta hazır bir quest ve haritayla gelir; sizin işiniz onu zamanlayıcıya bağlamaktır. Otomatik kurulumda zamanlayıcınız uygun saatte OX'u başlatan komutu/fonksiyonu çağırır, oyunculara bir duyuru yapar ve süre dolunca etkinliği kapatır.

  • OX yarışması: oyuncuları toplama, soru sorma ve ödül dağıtma; haritaya ışınlama gerektirir.
  • Balık etkinliği: balıkçılık sistemine bir flag bağlayarak nadir balık/eşya ihtimalini geçici olarak artırma.
  • Çifte drop / EXP / yang: yalnızca event flag ve çekirdekte çarpan kontrolü; kurulumu en kolay olanlar.

İşletim sistemi tarafından otomasyon isterseniz, Linux cron ile belirli saatlerde flag'i değiştiren küçük bir betik de çalıştırabilirsiniz; ancak betiğin oyun çekirdeğiyle güvenli biçimde haberleşmesi gerektiğinden çoğu sunucu için quest zamanlayıcısı daha basit ve daha az kırılgandır.

Kalıcılık ve sık yapılan hatalar

Event flag'ler bellekte tutulur ve birçok kaynakta sunucu yeniden başladığında sıfırlanır. Bu yüzden zamanlayıcınızı, sadece "saat geldiğinde aç" değil, "şu an etkinlik aralığındaysa açık tut" mantığıyla yazmak daha sağlamdır; böylece bir crash sonrası etkinlik kendiliğinden doğru duruma döner. Dikkat edilecek diğer noktalar:

  • Her set_event_flag(..., 1) için net bir kapatma koşulu olsun; "açık unutulan" etkinlik ekonomiyi bozar.
  • Duyuruları abartmayın; her dakika ekrana düşen notice_all oyuncuyu rahatsız eder.
  • OX gibi ışınlamalı etkinlikleri yoğun saatte test edin; harita kapasitesi ve ışınlama mantığı yük altında farklı davranabilir.
  • Flag isimlerini bir yerde belgeleyin; double_drop, double_exp gibi tutarlı adlar ileride karışıklığı önler.

Sık Sorulan Sorular

Event flag'ler sunucu yeniden başlayınca kayboluyor, ne yapmalıyım?

Çoğu kaynakta flag'ler bellektedir ve restart'ta sıfırlanır. En pratik çözüm, zamanlayıcıyı "aralık mantığı" ile yazmaktır: her tetiklenişte güncel saatin etkinlik aralığında olup olmadığını kontrol edip flag'i ona göre ayarlayın. Böylece restart sonrası bir-iki dakika içinde durum kendiliğinden düzelir.

Çifte drop etkinliğini açtım ama drop değişmedi, sebebi ne?

Büyük olasılıkla quest flag'i ayarlıyor fakat oyun çekirdeği bunu okumuyordur. Drop çarpanını char_item.cpp içindeki hesaplamaya eklemeniz ve kaynağı yeniden derlemeniz gerekir. Flag adının quest ile çekirdekte birebir aynı yazıldığından emin olun.

OX etkinliğini sıfırdan mı yazmalıyım?

Gerek yok. OX, harita ve özel mantığıyla birlikte çoğu kaynakta hazır gelir; sizin işiniz onu doğrulayıp zamanlayıcıya bağlamak. Sıfırdan yazmak yalnızca tamamen özgün bir mekanik istiyorsanız mantıklıdır.

Sunucunuza istikrarlı bir otomatik etkinlik sistemi mi kurmak istiyorsunuz? Metin2 event flag mimarisi, OX ve çifte drop otomasyonu üzerine birlikte çalışabiliriz. Projenizi konuşmak için benimle iletişime geçin.

Bu kategorideki tüm yazılar →

Devamı için