Metin2 yeni sınıf ekleme, hemen her sunucu sahibinin bir noktada hayalini kurduğu ama çoğu zaman ne kadar derin bir iş olduğunu bilmeden yola çıktığı bir konudur. Oyun, açılışından beri dört temel karakter sınıfı üzerine kuruludur: Savaşçı, Sura, Ninja (Sılahşör) ve Şaman; resmi tarafta sonradan eklenen Kurtadam (Lycan) ile bu sayı beşe çıktı. Bir beşinci ya da altıncı sınıfı sıfırdan getirmek, yeni bir model ya da harita eklemekten çok farklıdır: sınıf kimliği, oyunun hem client hem server hem de veritabanı katmanına gömülüdür. Bu yazıda neyin mümkün, neyin pratikte imkânsıza yakın olduğunu ve gerçekçi yaklaşımları anlatıyorum.
Neden basit bir "yeni model" işi değil
Metin2'de bir karakterin sınıfı tek bir sayıyla, yani job index ile temsil edilir. Server kaynağında bu değerler sabit olarak tanımlıdır: JOB_WARRIOR = 0, JOB_ASSASSIN = 1, JOB_SURA = 2, JOB_SHAMAN = 3 ve Kurtadam'lı sürümlerde JOB_WOLFMAN = 4. Karakterin oyundaki "ırk" değeri ise kabaca bu job ile cinsiyetin birleşiminden çıkar — yani her sınıfın erkek ve kadın varyantı ayrı bir slot kaplar. Bu sayı sadece bir etiket değil; oyunun her yerinde dizi indeksi olarak kullanılır. Stat hesaplama, can/mana formülleri, başlangıç puanları, skill ağacı, item giyme izinleri ve daha fazlası, bu indeks üzerinden tablolara bakar. Yeni bir indeks eklediğin an, bu tabloların hepsini de genişletmen gerekir.
Server tarafı: source olmadan olmaz
İşin en kritik kısmı budur. Yeni bir job index'i tanımlamak, oyunun game source'unu (C++ ile yazılı oyun çekirdeği) düzenleyip yeniden derlemeyi zorunlu kılar. Çünkü sınıf sayısı pek çok yerde sabit kabul edilir. Tipik olarak dokunman gereken yerler şunlardır:
- Sabitler — Job numaralarının ve toplam sınıf sayısının (
JOB_MAX_NUMgibi) tanımlandığı başlık dosyaları. - Puan ve stat tabloları — Her sınıfın seviye başına can, mana ve başlangıç istatistiklerini tutan diziler (
constants.cppcivarındaki job bilgisi dizileri). Yeni sınıf için bir satır eklemezsen oyun çöker ya da sıfır statla doğar. - Skill sistemi — Sınıfa özel skill ID'lerinin job ile eşlendiği yapılar.
- Item kısıtları — Eşyaların hangi sınıfların giyebileceği bir bit maskesiyle tutulur (Savaşçı 1, Sura 2, Ninja 4, Şaman 8 gibi). Beşinci sınıf bir sonraki biti kullanır ve bunun çekirdek tarafında tanınması gerekir.
Buradaki sorun şudur: piyasada dolaşan "server files" paketlerinin çoğu, derlenmiş binary hâlinde gelir; yani elinde C++ kaynak kodu yoktur. Source'un olmadan bu sabitleri değiştiremezsin — yapabileceğin tek şey var olan dört (ya da beş) sınıfla yaşamaktır. Elinde gerçekten derlenebilir bir source varsa iş zorlu ama mümkündür; yoksa "gerçek" anlamda yeni sınıf masada değildir.
Veritabanı katmanı
Karakterlerin sınıfı oyuncu tablosunda bir job sütununda saklanır. Yeni bir job değeri, veritabanı şemasını değiştirmeyi gerektirmese de (sütun zaten sayısal), skill ve item proto verilerinin yeni sınıfı tanıması gerekir. Örneğin skill_proto içindeki her becerinin hangi job'lara açık olduğu tanımlanır; yeni sınıfın becerilerini buraya eklemen gerekir. Aynı şekilde item_proto tarafında giyilebilir eşyaların sınıf kısıt maskesini güncellemen, yeni sınıfın çıplak dolaşmaması için şarttır.
Client tarafı: karakter seçim ve modeller
Server yeni sınıfı tanısa bile oyuncu onu göremiyorsa bir anlamı olmaz. Client tarafında yapılması gerekenler ayrı bir liste oluşturur:
- Karakter oluşturma ekranı — Root paketindeki Python arayüzü (karakter seçim ve oluşturma modülleri), oyuncunun seçebileceği ırkları sabit bir listeden okur. Yeni sınıfı bu listeye eklemen, ona bir simge, isim ve önizleme modeli tanımlaman gerekir.
- Oyuncu modelleri — Her sınıfın erkek ve kadın için ayrı
.gr2modeli, iskeleti ve tüm hareket dosyaları vardır. Yeni sınıf için hepsini hazırlaman ve doğru klasör yapısına koyman gerekir. - Hareket listeleri (.msa) ve durum makineleri — Yürüme, koşma, saldırı, skill animasyonları bu dosyalarla bağlanır. Eksik bir motion, o sınıfın o eylemde donmasına yol açar.
- Skill arayüzü — Skill pencerelerinin yeni sınıfın yetenek ağacını doğru ikon ve açıklamalarla göstermesi için locale dosyaları ve skill tanımları güncellenir.
Dikkat edilmesi gereken nokta: client'taki ırk indeksi ile server'daki job index'i birebir uyumlu olmalıdır. İki taraf farklı numara kullanırsa karakter yanlış modelle çıkar, skilleri tutmaz ya da girişte anında çöker.
Gerçekçi yaklaşımlar
Tam anlamıyla yeni bir beşinci sınıf çoğu projeye göre fazla maliyetlidir. Pratikte daha sık tercih edilen üç yol vardır:
- Var olan sınıfı yeniden temalamak (reskin) — Örneğin Şaman'ı tamamen yeni modeller, efektler ve skill görselleriyle "yeni bir sınıf" gibi göstermek. Job index'i aynı kaldığı için source'a dokunmazsın; sadece görsel ve skill içeriğini değiştirirsin. En düşük riskli ve en yaygın yöntem budur.
- Kurtadam (Lycan) entegrasyonu — Resmi olarak var olan beşinci sınıfı, ona ait hazır dosyalarla projene taşımak. Bu "yeni sınıf"tan çok "eksik sınıfı tamamlamak"tır; yine de skill, denge ve item kısıtları açısından ciddi iş ister.
- Source seviyesinde gerçek yeni sınıf — Elinde tam source varsa, yukarıdaki tüm katmanları genişletip beşinci/altıncı bir job tanımlamak. En esnek ama en uzun yoldur; iyi bir C++ ve denge bilgisi gerektirir.
Pratik bir yol haritası
Eğer gerçekten source seviyesinde gidiyorsan, mantıklı sıra şudur: önce server source'unda job sabitlerini ve tüm stat/skill/item tablolarını genişlet, derle ve sınıfı görünmez şekilde (model olmadan) DB'de yarat ki çekirdeğin onu kabul ettiğini doğrulayasın. Sonra skill ve item proto verilerini ekle. En son client'a geç: modelleri hazırla, karakter oluşturmaya ekle ve ırk indekslerini server'la eşitle. Her adımda syserr loglarını oku — sınıfla ilgili dizi taşmaları (out of range) en sık burada yakalanır. Acele edip her şeyi aynı anda yaparsan, hatanın hangi katmandan geldiğini bulmak neredeyse imkânsızlaşır.
Sık Sorulan Sorular
Source olmadan yeni sınıf eklenebilir mi?
"Gerçek" anlamda hayır. Job index'i ve ona bağlı stat/skill/item tabloları oyun çekirdeğinde sabittir ve sadece source derlemesiyle genişletilir. Source'un yoksa yapabileceğin tek şey var olan bir sınıfı yeniden temalamaktır (reskin).
Kurtadam eklemek yeni sınıf sayılır mı?
Yarı yarıya. Kurtadam resmi olarak tanımlı beşinci sınıftır; onu eklemek sıfırdan sınıf yaratmak değil, var olan ama projende eksik olan sınıfı entegre etmektir. Yine de skill, denge ve item kısıtları açısından hatırı sayılır bir iştir.
Reskin ile gerçek yeni sınıf arasındaki fark nedir?
Reskin'de job index'i değişmez; oyun hâlâ o karakteri eski sınıf olarak görür, sadece görseli ve skill içeriği farklıdır. Gerçek yeni sınıfta ise çekirdek düzeyinde yepyeni bir job tanımlanır; ayrı stat formülleri, ayrı item kısıtları ve bağımsız bir skill ağacı olur.
Yeni bir sınıf mı, yoksa akıllıca bir reskin mi istiyorsun? Projenin source durumunu inceleyip en az riskle en çok etki yaratacak yolu birlikte planlayabiliriz. Benimle iletişime geç ve sunucunun ihtiyacını konuşalım.