Eine neue Metin2-Klasse hinzuzufügen, davon träumt fast jeder Serverbetreiber irgendwann — meist ohne zu ahnen, wie tief diese Aufgabe wirklich reicht. Seit dem Start basiert das Spiel auf vier Kernklassen: Warrior, Sura, Ninja und Shaman; auf offizieller Seite hob der später eingeführte Wolfman (Lycan) diese Zahl auf fünf. Eine fünfte oder sechste Klasse von Grund auf einzubringen, ist etwas völlig anderes als ein neues Modell oder eine neue Map hinzuzufügen: Die Klassenidentität ist gleichzeitig in der Client-, der Server- und der Datenbankschicht verankert. In diesem Artikel erkläre ich, was wirklich möglich ist, was in der Praxis nahezu unmöglich ist, und die realistischen Ansätze dazwischen.
Warum es keine simple "neues Modell"-Aufgabe ist
In Metin2 wird die Klasse einer Figur durch eine einzige Zahl dargestellt, den Job-Index. In der Server-Source sind diese Werte als Konstanten definiert: JOB_WARRIOR = 0, JOB_ASSASSIN = 1, JOB_SURA = 2, JOB_SHAMAN = 3 und in Wolfman-Builds JOB_WOLFMAN = 4. Der "Race"-Wert einer Figur im Spiel ergibt sich grob aus diesem Job kombiniert mit dem Geschlecht — jede Klasse belegt also einen separaten Slot für ihre männliche und ihre weibliche Variante. Diese Zahl ist nicht bloß ein Etikett; sie wird im ganzen Spiel als Array-Index verwendet. Statberechnung, Lebens- und Manaformeln, Startpunkte, der Skillbaum, Item-Trageberechtigungen und vieles mehr greifen über diesen Index auf Tabellen zu. In dem Moment, in dem du einen neuen Index hinzufügst, musst du auch jede dieser Tabellen erweitern.
Serverseite: ohne die Source unmöglich
Das ist der kritischste Teil. Einen neuen Job-Index zu definieren zwingt dich, die Game-Source (den C++-Spielkern) zu bearbeiten und neu zu kompilieren, denn die Anzahl der Klassen gilt an vielen Stellen als fest. Die Bereiche, die du typischerweise anfassen musst, sind:
- Konstanten — Die Header-Dateien, in denen die Jobnummern und die Gesamtzahl der Klassen (etwa
JOB_MAX_NUM) definiert sind. - Punkt- und Stat-Tabellen — Die Arrays mit Leben, Mana und Startwerten pro Stufe jeder Klasse (die Job-Info-Arrays rund um
constants.cpp). Fügst du keine Zeile für die neue Klasse hinzu, stürzt das Spiel ab oder die Figur spawnt mit null Werten. - Das Skillsystem — Die Strukturen, die klassenspezifische Skill-IDs einem Job zuordnen.
- Item-Beschränkungen — Welche Klassen ein Item tragen dürfen, wird als Bitmaske gespeichert (Warrior 1, Sura 2, Ninja 4, Shaman 8). Eine fünfte Klasse nutzt das nächste Bit, und der Kern muss es erkennen.
Der Haken: Die meisten kursierenden "Server Files"-Pakete kommen als kompilierte Binaries, das heißt du hast keinen C++-Quellcode. Ohne die Source kannst du diese Konstanten nicht ändern — das Einzige, was du tun kannst, ist mit den vorhandenen vier (oder fünf) Klassen zu leben. Hast du wirklich eine kompilierbare Source, ist die Arbeit hart, aber machbar; hast du sie nicht, ist eine "echte" neue Klasse schlicht vom Tisch.
Die Datenbankschicht
Die Klasse einer Figur wird in einer job-Spalte in der Player-Tabelle gespeichert. Ein neuer Job-Wert erfordert nicht zwingend eine Schemaänderung (die Spalte ist bereits numerisch), aber die Skill- und Item-Proto-Daten müssen die neue Klasse erkennen. So definiert skill_proto, für welche Jobs jeder Skill offen ist; du musst die Skills deiner neuen Klasse dort eintragen. Ebenso musst du auf der item_proto-Seite die Klassenbeschränkungsmaske tragbarer Items aktualisieren, damit deine neue Klasse nicht mit leeren Ausrüstungsslots herumläuft.
Clientseite: Charaktererstellung und Modelle
Selbst wenn der Server die neue Klasse erkennt, ist es bedeutungslos, wenn der Spieler sie nicht sehen kann. Die Clientseite bildet ihre eigene Liste:
- Charaktererstellungsbildschirm — Die Python-Oberfläche im Root-Paket (die Charakterauswahl- und Erstellungsmodule) liest die wählbaren Races aus einer festen Liste. Du musst die neue Klasse zu dieser Liste hinzufügen und ihr ein Icon, einen Namen und ein Vorschaumodell geben.
- Spielermodelle — Jede Klasse hat separate
.gr2-Modelle, Skelette und vollständige Motion-Sets für männlich und weiblich. Du musst sie alle vorbereiten und in die korrekte Ordnerstruktur legen. - Motion-Listen (.msa) und State Machines — Gehen, Laufen, Angreifen und Skill-Animationen werden über diese Dateien gebunden. Eine fehlende Motion friert diese Klasse während der jeweiligen Aktion ein.
- Skill-Oberfläche — Locale-Dateien und Skilldefinitionen werden aktualisiert, damit die Skillfenster den Baum der neuen Klasse mit korrekten Icons und Beschreibungen zeigen.
Der entscheidende Punkt: Der Race-Index auf der Clientseite und der Job-Index auf der Serverseite müssen exakt übereinstimmen. Verwenden beide Seiten unterschiedliche Nummern, spawnt die Figur mit dem falschen Modell, die Skills bleiben nicht haften, oder der Client stürzt beim Login sofort ab.
Realistische Ansätze
Eine vollwertige fünfte Klasse ist für die meisten Projekte überdimensioniert. In der Praxis sind drei Wege weit verbreiteter:
- Eine bestehende Klasse neu thematisieren (Reskin) — Etwa den Shaman als "neue Klasse" mit völlig neuen Modellen, Effekten und Skillgrafiken präsentieren. Da der Job-Index gleich bleibt, fasst du die Source nie an; du änderst nur die visuellen und die Skillinhalte. Das ist die risikoärmste und gängigste Methode.
- Wolfman (Lycan)-Integration — Die offiziell existierende fünfte Klasse mit ihren fertigen Dateien in dein Projekt holen. Das ist weniger "neue Klasse" und mehr "eine fehlende Klasse vervollständigen"; dennoch erfordert es ernsthafte Arbeit an Skills, Balance und Item-Beschränkungen.
- Eine echte neue Klasse auf Source-Ebene — Hast du die vollständige Source, alle obigen Schichten erweitern, um einen fünften oder sechsten Job zu definieren. Der flexibelste, aber längste Weg; er verlangt solides C++- und Balance-Wissen.
Eine praktische Roadmap
Gehst du wirklich den Source-Weg, ist die sinnvolle Reihenfolge: Erweitere zuerst die Job-Konstanten und alle Stat-/Skill-/Item-Tabellen in der Server-Source, kompiliere, und lege die Klasse unsichtbar (ohne Modell) in der DB an, um zu bestätigen, dass der Kern sie akzeptiert. Füge danach die Skill- und Item-Proto-Daten hinzu. Erst am Ende geh zum Client: Bereite die Modelle vor, füge die Klasse zur Charaktererstellung hinzu und gleiche die Race-Indizes mit dem Server ab. Lies bei jedem Schritt die syserr-Logs — klassenbezogene Array-Überläufe (out of range) werden hier am häufigsten abgefangen. Hetzt du und machst alles auf einmal, wird es nahezu unmöglich herauszufinden, aus welcher Schicht der Fehler stammt.
Häufig gestellte Fragen
Kann eine neue Klasse ohne die Source hinzugefügt werden?
Nicht im "echten" Sinne. Der Job-Index und die abhängigen Stat-/Skill-/Item-Tabellen liegen im Spielkern fest und lassen sich nur durch Neukompilierung der Source erweitern. Ohne sie kannst du nur eine bestehende Klasse neu thematisieren (Reskin).
Zählt das Hinzufügen von Wolfman als neue Klasse?
Halb und halb. Wolfman ist die offiziell definierte fünfte Klasse; sie hinzuzufügen bedeutet nicht, eine Klasse von Grund auf zu erschaffen, sondern eine zu integrieren, die existiert, in deinem Projekt aber fehlt. Dennoch ist es erhebliche Arbeit hinsichtlich Skills, Balance und Item-Beschränkungen.
Was ist der Unterschied zwischen einem Reskin und einer echten neuen Klasse?
Bei einem Reskin ändert sich der Job-Index nicht; das Spiel sieht diese Figur weiterhin als die alte Klasse, nur Grafik und Skillinhalt unterscheiden sich. Bei einer echten neuen Klasse wird auf Kernebene ein völlig neuer Job definiert, mit eigenen Statformeln, eigenen Item-Beschränkungen und einem unabhängigen Skillbaum.
Willst du eine wirklich neue Klasse oder einen cleveren Reskin? Ich kann die Source-Situation deines Projekts prüfen und den Weg planen, der mit dem geringsten Risiko die größte Wirkung erzielt. Nimm Kontakt mit mir auf, und lass uns besprechen, was dein Server braucht.