Metin2 Quest Yazma Rehberi: Profesyonel Görev Kodlama

Metin2 quest (görev) yazma rehberi
Metin2 quest (görev) yazma rehberi

Metin2 dünyası, 20 yılı aşkın süredir hem oyuncular hem de oyun geliştiricileri için bitmek bilmeyen bir macera sunuyor. 2026 yılına geldiğimizde, oyunun temel mekanikleri korunsa da, sunucu sahiplerinin ve geliştiricilerin oyunculara sunduğu içerik kalitesi hiç olmadığı kadar önem kazanmış durumda. Bir sunucunun kimliğini belirleyen en önemli unsurlardan biri, oyuncuların etkileşime girdiği özgün görevlerdir. Quest (görev) yazımı, sadece birkaç satır kod yazmaktan ibaret değildir; bu, oyuncunun hikayesini şekillendirmek, oyun içi ekonomiyi dengelemek ve kullanıcıyı sürekli bir amaç doğrultusunda tutmak için kullanılan sanatsal bir araçtır.

Bir sunucu yöneticisi veya geliştiricisi olarak, standart “10 yabani köpek öldür” görevlerinin ötesine geçmeniz gerekir. Modern Metin2 altyapılarında, Lua tabanlı bu sistemler artık daha karmaşık algoritmaları, çok dilli destekleri ve gelişmiş zindan (dungeon) mekaniklerini desteklemektedir. Bu rehberde, temel seviyeden uzmanlık seviyesine kadar bir görevin nasıl kurgulandığını, kodlandığını ve optimize edildiğini derinlemesine inceleyeceğiz. Kendi özgün senaryolarınızı oluşturmak ve Metin2 PvP serverler dünyasında fark yaratmak için ihtiyacınız olan teknik donanımı bu yazıda bulacaksınız.

Önemli: Quest yazımına başlamadan önce, dosya formatınızın mutlaka ANSI değil, UTF-8 (BOM’suz) olduğundan emin olmalısınız. Aksi takdirde oyun içerisinde Türkçe karakter hataları ile karşılaşırsınız.

Quest Yapısının Temelleri ve Mantıksal Hiyerarşi

Metin2’de bir görev dosyası .quest veya .lua uzantısına sahiptir. Bu dosyalar, oyunun çekirdek mekanizması tarafından okunabilmesi için bir derleyici (genellikle qc dosyası) aracılığıyla işlenir. Bir görev dosyasının mimarisi, belirli bir hiyerarşiye dayanır. En üstte görev ismi yer alır, ardından görev durumları (states) ve son olarak bu durumları tetikleyen olaylar (triggers) gelir.

Görev Bloklarının Tanımlanması

Her görev, quest görev_adı begin ifadesiyle başlar ve end ile son bulur. Bu blok, dosyanın genel sınırlarını çizer. Bir görev dosyasının içinde birden fazla durum (state) olabilir. Ancak her görev mutlaka bir start durumuna sahip olmalıdır. Oyuncu bir göreve başladığında sistem otomatik olarak bu başlangıç durumuna bakar.

quest ilk_gorevim begin
    state start begin
        when login or levelup with pc.get_level() >= 30 begin
            set_state(bilgi_al)
        end
    end
end

Yukarıdaki basit örnekte, oyuncu 30. seviyeye ulaştığında veya bu seviyedeyken oyuna girdiğinde görev tetiklenir ve set_state komutu ile görev bir sonraki aşamaya aktarılır. Bu yapı, Metin2’nin görev mantığının temelidir.

Tetikleyiciler (When Blokları)

Tetikleyiciler, bir eylemin ne zaman gerçekleşeceğini belirler. Metin2 Lua motoru onlarca farklı tetikleyiciyi tanır:

  • when login: Oyuncu oyuna girdiğinde.
  • when kill: Bir canavar veya oyuncu öldürüldüğünde.
  • when click: Bir NPC’ye tıklandığında.
  • when use: Bir eşya kullanıldığında (örneğin bir yüzük veya binek).
  • when levelup: Seviye atlandığında.
  • when chat: NPC menüsünde bir seçenek göründüğünde.
  • Tetikleyicilerin verimli kullanılması, sunucu performansını doğrudan etkiler. Örneğin, her saniye çalışan bir tetikleyici yerine, sadece gerektiğinde (event-driven) çalışan tetikleyiciler tercih edilmelidir.

    Lua Dilinin Metin2’deki Rolü ve Temel Fonksiyonlar

    Metin2 görev sistemi, Lua programlama dilinin basitleştirilmiş bir versiyonunu kullanır. Karmaşık matematiksel hesaplamalar yapabilir, oyuncu verilerini (flag) saklayabilir ve oyun dünyasına müdahale edebilirsiniz. 2026 yılındaki güncel sunucu yapılarında, Lua fonksiyonları artık daha geniş bir kütüphaneye sahiptir.

    Değişkenler ve Flag Kullanımı

    Bir oyuncunun görevde hangi aşamada olduğunu veya bir görevi daha önce yapıp yapmadığını anlamak için “flag” sistemini kullanırız. pc.setf ve pc.getf fonksiyonları, oyuncunun karakterine özel kalıcı veriler kaydetmenizi sağlar.

  • pc.setf("gorev_adı", "durum", deger): Veri kaydeder.
  • pc.getf("gorev_adı", "durum"): Kaydedilen veriyi okur.
  • Örneğin, bir oyuncunun günde sadece bir kez girebileceği bir zindan yapmak istiyorsanız, oyuncunun en son girdiği zamanı get_global_time() ile bir flag içine kaydedebilir ve her girişte bu süreyi kontrol edebilirsiniz.

    Temel Çıktı ve Etkileşim Fonksiyonları

    Oyuncuyla iletişim kurmak için en sık kullanılan fonksiyon say() fonksiyonudur. Ancak modern tasarımlarda say_item(), say_reward() ve say_title() gibi görseli zenginleştiren yardımcı fonksiyonlar da mevcuttur.

    say_title("Demirci:")
    say("Merhaba evlat, bana 10 adet Bakır Cevheri")
    say("getirirsen sana özel bir ödül verebilirim.")
    local secim = select("Kabul Ediyorum", "Vazgeç")
    

    Buradaki select() fonksiyonu, oyuncuya seçenek sunar ve oyuncunun tıkladığı butonun indeksini döndürür. Bu, görev dallanmaları için hayati önem taşır.

    Önemli: say fonksiyonu içerisinde çok uzun metinler kullanmak, pencerenin taşmasına veya oyuncunun ekranının donmasına neden olabilir. Her zaman metinlerinizi makul uzunlukta tutun.

    Gelişmiş Görev Senaryoları ve Zindan Kodlama

    2026 yılı Metin2 PvP dünyasında standart görevlerden ziyade “Dungeon” (Zindan) görevleri revaçtadır. Bir zindan yazmak, normal bir görev yazmaktan daha karmaşıktır çünkü grup (party) kontrolü, harita indeksleri ve canavar doğurma (spawn) koordinatlarını yönetmeniz gerekir.

    Zindan Başlatma Mantığı

    Bir zindanı başlatmak için d.new_jump veya d.new_jump_all fonksiyonları kullanılır. Bu fonksiyonlar oyuncuyu veya grubu izole edilmiş (instance) bir haritaya ışınlar.

    Zindan içerisinde kullanılan bazı özel fonksiyonlar şunlardır:

  • d.notice(): Zindandaki herkese duyuru geçer.
  • d.spawn_mob(): Belirli bir koordinata canavar çağırır.
  • d.setf(): Sadece o zindan oturumuna (instance) özel veri saklar.
  • d.kill_all(): Haritadaki tüm canavarları temizler.
  • Zindan tasarlarken en sık yapılan hata, timer (zamanlayıcı) kullanımında yaşanır. timer yerine server_timer veya loop_timer kullanmak, sunucu taraflı senkronizasyonu artırır ve oyuncuların zindandan düşmesi (kick) durumunda görevin askıda kalmasını engeller.

    Ödüllendirme ve Eşya Kontrolü

    Görevlerin sonunda oyuncuya eşya vermek için pc.give_item2() fonksiyonu kullanılır. Bu fonksiyon, envanter doluysa eşyayı yere atmaz, sistem üzerinden bir uyarı verir. Eşya kontrolü yaparken ise pc.count_item() fonksiyonu ile oyuncunun elinde yeterli malzeme olup olmadığı denetlenmelidir.

    Fonksiyon Adı Amacı Örnek Kullanım
    pc.give_item2 Oyuncuya eşya verir pc.give_item2(19, 1)
    pc.remove_item Oyuncudan eşya siler pc.remove_item(30006, 5)
    pc.get_job Oyuncunun karakter sınıfını döner if pc.get_job() == 0 then
    pc.warp Oyuncuyu ışınlar pc.warp(x_koordinat, y_koordinat)
    mob.spawn Canavar oluşturur mob.spawn(101, x, y, adet)

    Quest Yazımında Performans ve Güvenlik

    Büyük oyuncu kitlesine sahip sunucularda hatalı yazılmış bir quest, CPU kullanımını %100’e çıkarabilir veya oyun veritabanında (db) açıklar yaratabilir. Bu nedenle kod yazarken “temiz kod” prensiplerine uymak zorunludur.

    Performans Optimizasyonu

    1. Döngülerden Kaçının: Görev içerisinde çok büyük for veya while döngüleri kullanmak oyunun anlık takılmasına (lag) neden olabilir. Eğer bir liste üzerinde işlem yapacaksanız, bunu küçük parçalara bölün.
    2. Sorgu Sayısını Azaltın: pc.getf gibi fonksiyonlar veritabanı ile doğrudan etkileşime girmese de, sürekli çağrılmaları bellek yükünü artırır. Değişkenleri bir yerel değişkene (local) atayıp oradan kullanmak daha hızlıdır.
    3. Gereksiz Tetikleyicileri Kapatın: Kullanılmayan bir görevi qc ile derleyip aktif bırakmak, her oyuncu girişinde sistemin o görevi kontrol etmesine neden olur.
    4. Güvenlik Önlemleri

      Bir oyuncunun görevi suistimal etmesini (exploit) önlemek için her zaman kontrollerinizi çift taraflı yapın. Örneğin, bir NPC’den ödül alınacaksa:

    5. Oyuncu NPC’nin yanında mı? (pc.get_distance)
    6. Oyuncu gerekli seviyede mi?
    7. Oyuncunun envanterinde yer var mı?
    8. Oyuncu bu ödülü daha önce aldı mı?
    9. Bu kontrolleri yapmadan verilen ödüller, hile kullanan oyuncuların görevi uzaktan tetikleyerek sonsuz eşya almasına neden olabilir.

      Quest Derleme ve Sunucuya Entegre Etme

      Metin2 quest (görev) yazma rehberi
      Metin2 quest (görev) yazma rehberi

      Yazdığınız .quest dosyasını oyuna dahil etmek için şu adımları izlemelisiniz:

    10. Dosyayı sunucunuzun /usr/game/share/locale/turkey/quest dizinine yükleyin.
    11. quest_list (veya bazı filestarda locale_list) dosyasına yazdığınız dosyanın adını ekleyin.
    12. SSH (Putty) üzerinden ilgili dizine giderek ./qc dosya_adi.quest komutunu çalıştırın.
    13. Oyun içerisinden yönetici (GM) karakteriyle /reload q komutunu verin veya sunucuyu yeniden başlatın.

    Önemli: /reload q komutu büyük sunucularda anlık donmaya neden olabilir. Canlı sunucularda bu komutu kullanırken dikkatli olmalısınız.

    Örnek Bir Senaryo: Günlük Hediye Görevi

    Aşağıda, 2026 yılı standartlarına uygun, hata payı düşük ve optimize edilmiş bir günlük giriş ödülü görevi örneği bulunmaktadır. Bu kod bloğunu inceleyerek mantığı kavrayabilirsiniz.

    quest gunluk_odul begin
        state start begin
            when 20095.chat."Günlük Hediyeni Al" begin
                local son_alim = pc.getf("gunluk_odul", "son_zaman")
                local su anki_zaman = get_global_time()

    if su_anki_zaman < son_alim + 86400 then say_title("Sistem:") say("Henüz 24 saat geçmemiş.") say("Tekrar gelmek için beklemen gereken süre:") say_reward(string.format("%d saat.", (son_alim + 86400 - su_anki_zaman) / 3600)) else say_title("Sistem:") say("Harika! Bugünün hediyesini hak ettin.") pc.give_item2(71084, 10) -- Efsun Nesnesi pc.setf("gunluk_odul", "son_zaman", su_anki_zaman) say_reward("10x Efsun Nesnesi kazandın.") end end end end

    Bu örnekte get_global_time() fonksiyonu ile Unix zaman damgası alınmış ve 24 saatlik (86400 saniye) kontrol mekanizması kurulmuştur. Bu, modern sunucularda en sağlıklı çalışma yöntemidir.

    Sonuç

    Metin2 quest yazımı, teknik bilgi ile yaratıcılığın buluştuğu bir noktadır. İyi bir geliştirici, sadece kod yazan değil, aynı zamanda yazdığı kodun oyuncu üzerindeki etkisini ve sunucu üzerindeki yükünü hesaplayan kişidir. 2026 yılında, oyuncu toplulukları artık daha bilinçli ve kaliteli içerik bekliyor. Bu rehberde öğrendiğiniz temeller üzerine kendi özgün sistemlerinizi inşa ederek, oyun dünyasında kalıcı bir iz bırakabilirsiniz. Unutmayın ki en iyi görev, oyuncuyu sıkmayan, ona bir hikaye sunan ve adil bir ödül sistemiyle çalışan görevdir.

    Yasal Uyarı: Bu rehberdeki bilgiler eğitim amaçlıdır. Uygulama sırasında oluşabilecek veri kayıplarından veya sunucu hatalarından geliştiricinin kendisi sorumludur. Her zaman yedek alarak çalışınız.

    Sıkça Sorulan Sorular

    Quest dosyasını derlerken "Segmentation Fault" hatası alıyorum, ne yapmalıyım?

    Bu hata genellikle Lua kodundaki yazım yanlışlarından (eksik end, parantez hatası vb.) kaynaklanır. Kodunuzu satır satır kontrol edin ve blokların doğru kapandığından emin olun. Ayrıca dosya sonuna bir boş satır bırakmak bazen bu sorunu çözebilir.

    Bir görevi sadece belirli bir krallığa özel nasıl yapabilirim?

    pc.get_empire() fonksiyonunu kullanarak kontrol sağlayabilirsiniz. Örneğin; if pc.get_empire() == 1 then kontrolü, görevin sadece Kırmızı Krallık (Shinsoo) oyuncuları tarafından yapılmasını sağlar.

    Quest dosyalarındaki Türkçe karakterler neden "?" olarak görünüyor?

    Bu durum tamamen dosya kodlaması ile ilgilidir. Notepad++ gibi bir editör kullanarak "Kodlama" menüsünden "UTF-8 (BOM'suz)" seçeneğini işaretleyip dosyayı kaydedin ve sunucuya tekrar yükleyip derleyin.

    Quest ile oyun içi "Sistem" (C++ tabanlı) arasındaki fark nedir?

    Questler Lua dilini kullanır ve yorumlanarak çalışır; esnektirler ancak çok yoğun işlemlerde performansı etkileyebilirler. Sistemler (source tarafı) C++ ile yazılır, çekirdeğe gömülüdür ve çok daha hızlı çalışırlar. Karmaşık mantıklar için quest, temel mekanikler için C++ tercih edilir.

    Yazdığım görev oyunda görünmüyor, sebebi ne olabilir?

    Bunun birkaç sebebi olabilir: qc ile derlenmemiş olabilir, quest_list dosyasına eklenmemiş olabilir, NPC kodu yanlış yazılmış olabilir veya görevdeki seviye/krallık şartlarını karşılamıyor olabilirsiniz.

    Birden fazla NPC'ye aynı görevi nasıl atayabilirim?

    when 20011.chat."Görev" or 20012.chat."Görev" begin şeklinde or (veya) bağlacını kullanarak birden fazla NPC kodunu aynı tetikleyiciye bağlayabilirsiniz.

    Timer (zamanlayıcı) kullanırken server kapanırsa ne olur?

    Standart timer fonksiyonları bellek üzerinde tutulur ve sunucu (veya kanal) kapandığında sıfırlanır. Eğer kalıcı bir süre takibi istiyorsanız (örneğin 1 hafta sürecek bir görev), veritabanına kayıt yapan pc.setf ve get_global_time ikilisini kullanmalısınız.

    Kaynaklar

  • Metin2 PvP Serverler Tanıtım Portalı
  • Metin2 Geliştirici Ansiklopedisi
  • Resmi Metin2 Wiki Rehberleri
  • Metin2 Etkinlik ve Quest Arşivi

İlk yorum yapan olun

Bir yanıt bırakın

E-posta hesabınız yayımlanmayacak.


*