Ein metin2 event system lässt deinen Server jeden Tag zu festen Uhrzeiten ein OX-Quiz öffnen, eine Double-Drop- oder Double-EXP-Phase starten oder ein Angel-Event ankündigen — und das alles, ohne dass ein GM einen Finger rührt. Eine gut gebaute Event-Schleife holt Spieler nach einem festen Zeitplan immer wieder zurück; eine schlecht gebaute bläht die Wirtschaft auf, verursacht Lags oder glaubt nach einem Neustart, ein Event sei noch „an". In diesem Artikel behandle ich die Event-Flag-Logik, die jedem Event zugrunde liegt, die manuellen GM-Befehle und wie du sie mit einem Quest-Timer oder dem Cron des Betriebssystems automatisierst.
Event-Flags: die gemeinsame Sprache jedes Events
In der Metin2-Source läuft fast jedes Event über ein Event-Flag. Ein Flag ist eine ganze Zahl, die einem Namen zugeordnet ist (zum Beispiel double_drop = 1) und sowohl vom Spielkern (C++) als auch vom Questsystem (Lua) gelesen werden kann. Die Logik ist einfach: Irgendwo setzt du das Flag auf 1, der Drop-/Exp-/Event-Code prüft diesen Wert und ändert sein Verhalten, und wenn das Event endet, setzt du es wieder auf 0.
Auf der Questseite verwendest du zwei Kernfunktionen:
-- das Flag setzen (1 = an, 0 = aus)
game.set_event_flag("double_drop", 1)
-- das Flag auslesen
local aktiv = game.get_event_flag("double_drop")
if aktiv == 1 then
-- Event läuft
end
Die Stärke dieses Ansatzes ist, dass ein einziger zentraler Schalter jedes System antreibt. Von der Drop-Berechnung bis zur Bildschirm-Meldung schaut jeder Teil auf dasselbe Flag, sodass ein Event an- oder auszuschalten auf eine einzige Zeile hinausläuft.
Manuelle Kontrolle: GM-Befehle
Bevor du irgendetwas automatisierst, musst du jedes Event von Hand umschalten können — unverzichtbar für Tests und Notfälle. In den meisten Sources kann ein GM ein Event-Flag direkt mit einem Befehl im Spiel ändern:
/event_flag double_drop 1 // Double Drop einschalten
/event_flag double_drop 0 // ausschalten
Der genaue Befehlsname kann sich je nach Source unterscheiden (prüfe, welcher Befehl in cmd.cpp SetEventFlag aufruft). Events mit eigener Map und Spezial-Logik wie OX haben eigene Befehle — typischerweise drei separate GM-Befehle, um das Event zu starten, eine Frage zu stellen und es zu schließen. Sobald du diese Befehle mit einem GM-Konto geprüft hast, ist das Einrichten der Automatisierung viel sicherer, weil der Timer einfach auslöst, „was ein GM von Hand getippt hätte".
Automatisieren mit einem Quest-Timer
Die sauberste In-Game-Automatisierung ist, das eigene Questsystem des Servers als Scheduler zu nutzen. Du startest einen Server-Timer, der in regelmäßigen Abständen feuert, prüfst bei jedem Tick die Uhr und kippst das Flag im richtigen Moment. Das folgende Beispiel liest jede Minute die Uhr und schaltet das Double-Drop-Event zweimal täglich an und aus:
quest auto_event begin
state start begin
when login begin
-- den Timer nur einmal starten
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("Das Double-Drop-Event hat begonnen! Es dauert 2 Stunden.")
elseif t.hour == 22 and t.min == 0 then
game.set_event_flag("double_drop", 0)
notice_all("Das Double-Drop-Event ist beendet.")
end
-- den Timer neu setzen
server_timer("event_tick", 60)
end
end
end
Achte hier auf drei Dinge: Starte den Timer nur einmal (sonst öffnet jeder Login einen neuen), setze ihn bei jedem Tick neu (Server-Timer sind einmalig) und kündige mit notice_all dem ganzen Server an. Timer- und Funktionsnamen können sich je nach Source leicht unterscheiden; nutze die vorhandenen Beispiele in deiner eigenen questlib.lua als Referenz.
Den Drop- und EXP-Multiplikator an das Flag binden
Die Quest setzt das Flag, aber der eigentliche Multiplikator passiert im Spielkern. Damit die Drop-Rate auf das Flag reagiert, fügst du der Drop-Berechnung in char_item.cpp eine Prüfung hinzu:
int iEventFlag = quest::CQuestManager::instance().GetEventFlag("double_drop");
if (iEventFlag > 0)
iDropPct *= 2; // die Drop-Chance verdoppeln
Dieselbe Logik gilt für EXP in der Erfahrungsfunktion in char.cpp und für Yang-/Geld-Drops in der entsprechenden Funktion. Der häufigste Fehler hier ist, den Multiplikator zu aggressiv zu wählen (etwa x5 EXP) und dann zu vergessen, das Flag am Eventende zurückzusetzen, was die Wirtschaft dauerhaft aufbläht. Halte die Multiplikatoren maßvoll und stelle sicher, dass jedes Flag, das du einschaltest, eine passende Aus-Bedingung hat.
OX, Angeln und andere map-basierte Events
Ein OX-Quiz braucht mehr als ein einfaches Flag: eine eigene Map (meist ein separater Map-Index), das Teleportieren der Spieler dorthin, eine Frage-Antwort-Schleife und Logik, um jeden auszuscheiden, der falsch antwortet. Deshalb kommt OX in den meisten Sources als fertige Quest und Map; deine Aufgabe ist es, es an den Scheduler zu koppeln. In einem automatisierten Aufbau ruft dein Timer den Befehl/die Funktion auf, die OX zur richtigen Stunde startet, kündigt es den Spielern an und schließt das Event, wenn die Zeit abläuft.
- OX-Quiz: Spieler sammeln, Fragen stellen und Belohnungen verteilen; erfordert das Teleportieren auf eine Map.
- Angel-Event: Binde ein Flag an das Angelsystem, um die Chance auf seltene Fische/Items vorübergehend zu erhöhen.
- Double Drop / EXP / Yang: nur ein Event-Flag plus eine Multiplikator-Prüfung im Kern — am einfachsten einzurichten.
Bevorzugst du Automatisierung auf OS-Ebene, kannst du per Linux cron ein kleines Skript laufen lassen, das das Flag zu bestimmten Stunden umschaltet; da das Skript aber sicher mit dem Spielkern kommunizieren muss, ist ein Quest-Timer für die meisten Server einfacher und weniger fehleranfällig.
Persistenz und häufige Fehler
Event-Flags liegen im Speicher und werden in vielen Sources zurückgesetzt, wenn der Server neu startet. Deshalb ist es robuster, deinen Timer mit einer „lass es an, wenn wir im Event-Zeitfenster sind"-Logik zu schreiben statt nur „schalte es zu dieser Stunde an"; so kehrt ein Event nach einem Crash von selbst in den richtigen Zustand zurück. Weitere Punkte, auf die du achten solltest:
- Gib jedem
set_event_flag(..., 1)eine klare Aus-Bedingung; ein versehentlich „an" gelassenes Event bricht die Wirtschaft. - Übertreibe es nicht mit Ankündigungen; ein
notice_all, das jede Minute auf dem Bildschirm erscheint, nervt die Spieler. - Teste teleport-basierte Events wie OX zu Stoßzeiten; Map-Kapazität und Teleport-Logik können unter Last anders reagieren.
- Dokumentiere deine Flag-Namen irgendwo; konsistente Namen wie
double_dropunddouble_expverhindern später Verwirrung.
Häufige Fragen
Event-Flags verschwinden, wenn der Server neu startet — was soll ich tun?
In den meisten Sources liegen Flags im Speicher und werden beim Neustart zurückgesetzt. Die praktischste Lösung ist, den Timer mit „Fenster-Logik" zu schreiben: Prüfe bei jedem Tick, ob die aktuelle Zeit ins Event-Fenster fällt, und setze das Flag entsprechend. So korrigiert sich der Zustand nach einem Neustart innerhalb von ein, zwei Minuten von selbst.
Ich habe das Double-Drop-Event eingeschaltet, aber die Drops haben sich nicht geändert — warum?
Höchstwahrscheinlich setzt die Quest das Flag, aber der Spielkern liest es nicht aus. Du musst den Drop-Multiplikator zur Berechnung in char_item.cpp hinzufügen und die Source neu kompilieren. Stelle sicher, dass der Flag-Name in der Quest und im Kern exakt gleich geschrieben ist.
Muss ich das OX-Event von Grund auf schreiben?
Nein. OX kommt mit seiner Map und Spezial-Logik in den meisten Sources mit; deine Aufgabe ist es, es zu prüfen und an den Scheduler zu koppeln. Von Grund auf zu schreiben lohnt sich nur, wenn du eine völlig originelle Mechanik willst.
Willst du ein stabiles automatisches Event-System auf deinem Server? Wir können gemeinsam an Metin2 Event-Flag-Architektur, OX und Double-Drop-Automatisierung arbeiten. Um über dein Projekt zu sprechen, nimm Kontakt mit mir auf.