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

Metin2 Switchbot-System: automatischer Bonuswechsel

Ein Metin2 Switchbot-System ist ein Mechanismus, der die Boni (Attribute) eines Items automatisch neu auswürfelt, bis die gewünschte Kombination erscheint, statt Klick für Klick. Der Spieler legt ein Ziel fest — etwa „kritischer Treffer 15% und durchschnittlicher Schaden 10%" — und das System verbraucht Wechsel-Items, würfelt die Attribute immer wieder neu und stoppt, sobald eine Übereinstimmung gefunden ist. In diesem Leitfaden zeige ich, wie du ein solches System serverseitig, mit der Lua-Quest-Engine, sicher und ausgewogen baust. Ziel ist nicht, fertigen Code zu kopieren, sondern die Logik zu verstehen und an deinen eigenen Server anzupassen.

Was automatisiert ein Switchbot genau?

In Metin2 werden die Boni eines Items als Attribute gespeichert: Jede Zeile hat einen Typ (kritische Chance, durchdringender Treffer, Schaden gegen Monster…) und einen Wert. Klassisch nutzt der Spieler ein „Bonuswechsel"-Item, lässt alle Zeilen zufällig neu auswürfeln und versucht es erneut, wenn ihm das Ergebnis nicht gefällt. Das ist eine mühsame Schleife, die Hunderte Klicks kosten kann.

Ein Switchbot verlagert diese Schleife auf den Server: Der Spieler wählt einmal ein Ziel, und bei jedem Schritt verbraucht das System ein Wechsel-Item, würfelt die Attribute neu und vergleicht das Ergebnis mit dem Ziel. Die Vorteile sind klar:

  • Fair und überprüfbar — Zufall und Kosten werden auf dem Server berechnet, nie dem Client vertraut.
  • Missbrauchssicher — Item-Bestand, Versuchslimit und Cooldown werden von einer Stelle aus kontrolliert.
  • Protokollierbar — wer hat was in wie vielen Versuchen geändert; alles wird aufgezeichnet.

Die Grundlage des Bonuswechsels: change_attribute

Das Herz des Systems ist die Engine-Funktion, die alle Bonuszeilen eines Items zufällig neu auswürfelt. In den meisten Sources wird dieser Aufruf als item.change_attribute() bereitgestellt und tut genau das, was das „Bonuswechsel"-Item tut, nur aus einer Quest heraus. Zuerst musst du das zu bearbeitende Item auswählen:

-- das Ziel-Item per VID waehlen, dann seine Boni neu auswuerfeln
item.select(item_vid)
item.change_attribute()

Nach dem Auswürfeln lesen wir die aktuellen Boni und vergleichen sie mit dem Ziel. Der genaue Name der Lesefunktion kann je nach Source-Revision variieren (zum Beispiel ein item.get_attribute(i), das ein Typ/Wert-Paar zurückgibt); wichtig ist, dass jede Zeile als (Typ, Wert)-Paar erhältlich ist. Baust du deine Logik darauf auf, funktioniert das System gleich, selbst wenn der Funktionsname bei dir anders heißt.

Architektur: Server-Quest oder Client-Bot?

Der Name „Switchbot" bezeichnet manchmal ein clientseitiges Makro/einen Bot, der automatisch auf das Item klickt. Diesen Ansatz empfehle ich nicht. Ein Client-Bot fälscht Pakete, kann vom Anti-Hack erwischt werden, lässt sich auf dem Server nicht prüfen und zerstört die Fairness zwischen Spielern. Die richtige Lösung ist, das ganze System auf den Server zu verlagern:

  • Einzige Quelle der Wahrheit — Boni, Kosten und Limits leben auf dem Server; der Client zeigt nur die Oberfläche.
  • Performance-Sicherheit — die Schleife schreitet Schritt für Schritt per Timer voran, ohne zu blockieren.
  • Transparenz — jeder Versuch verbraucht ein Item und bindet so reale Kosten an die Wirtschaft.

Daher bauen wir das System als Quest und teilen die automatische Schleife mit server_timer auf; so friert der Server nicht ein, während er wartet, „bis der gewünschte Bonus erscheint".

Die Kernschleife mit server_timer bauen

Wenn der Spieler das Wechsel-Item benutzt, schreiben wir die VID des Ziel-Items und den gewählten Zielbonus in die Flags des Spielers und starten den Timer. Bei jedem Auslösen macht der Timer einen Versuch: Er prüft, ob das Item verfügbar ist, verbraucht eines, würfelt die Boni neu und prüft auf eine Übereinstimmung.

quest switchbot begin
    state start begin
        -- 71109: Bonuswechsel-Stein (Beispiel-vnum)
        when 71109.use begin
            local target_vid = pc.getqf("sb_target_vid")
            if target_vid == 0 then
                say("Waehle zuerst das zu aendernde Item.")
                return
            end
            -- Versuche zuruecksetzen und Schleifenzaehler starten
            pc.setqf("sb_tries", 0)
            server_timer("sb_tick", 1, get_server_timer_arg())
        end

        when sb_tick.server_timer begin
            local change_vnum = 71109
            local tries = pc.getqf("sb_tries")
            -- haben wir noch ein Wechsel-Item?
            if pc.count_item(change_vnum) < 1 then
                pc.notice("Wechsel-Items aufgebraucht. "..tries.." Versuche.")
                return
            end
            if tries >= 200 then
                pc.notice("Versuchslimit erreicht (200).")
                return
            end

            pc.remove_item(change_vnum, 1)
            pc.setqf("sb_tries", tries + 1)
            item.select(pc.getqf("sb_target_vid"))
            item.change_attribute()

            if sb_match_target() then
                pc.notice("Zielbonus getroffen! Insgesamt "..(tries+1).." Versuche.")
                return
            end
            -- keine Uebereinstimmung: kurz warten und erneut versuchen
            server_timer("sb_tick", 1, get_server_timer_arg())
        end
    end
end

Die Kernidee hier ist, die Schleife mit einem Timer statt mit einer while zu bauen. Jeder Schritt ist ein eigener server_timer-Auslöser; weil wir eine Sekunde dazwischen setzen, sperren selbst Hunderte Versuche den Server nicht und andere Spieler bleiben unbeeinträchtigt. Du kannst das Tempo an deine Balance anpassen und das Intervall auf stark frequentierten Servern vergrößern.

Die Logik des Zielabgleichs

Das Gehirn des Systems ist die Hilfsfunktion, die die Frage „passen die aktuellen Boni zum Ziel?" beantwortet. Sie hält die vom Spieler gewählten Zielzeilen in Flags und scannt nach jedem Auswürfeln die Zeilen des Items, um zu prüfen, ob der Typ übereinstimmt und der Wert mindestens der geforderte Betrag ist:

-- Beispiel: APPLY_CRITICAL_PCT von mindestens 12% anvisieren
function sb_match_target()
    local want_type  = pc.getqf("sb_want_type")   -- Apply-Typ
    local want_value = pc.getqf("sb_want_value")  -- Mindestwert
    -- alle Bonuszeilen des Items durchgehen
    for i = 0, 6 do
        local atype, avalue = item.get_attribute(i)
        if atype == want_type and avalue >= want_value then
            return true
        end
    end
    return false
end

Dieses Beispiel zielt auf einen einzelnen Bonus; um zwei oder drei gleichzeitig zu fordern, erweiterst du die Zielliste, prüfst jeden einzeln und gibst nur dann true zurück, wenn alle erfüllt sind. Apply-Typen (z. B. APPLY_CRITICAL_PCT, APPLY_PENETRATE_PCT, APPLY_ATTBONUS_MONSTER) bei ihren Konstantennamen zu verwenden, hält den Code lesbar. Ein klassischer NPC-Dialog oder ein einfaches select-Menü reicht, um den Spieler ein Ziel wählen zu lassen.

Balancing: Kosten, Limits, Cooldown und Logs

Ein Switchbot, der unbegrenzt und kostenlos ist, lässt die Wirtschaft sofort kollabieren; jeder würfelt in Minuten ein perfektes Item. Die eigentliche Arbeit, die das System fair hält, ist das Balancing:

  • Reale Kosten: Jeder Versuch sollte ein Wechsel-Item (und optional etwas Yang) verbrauchen. Die Kosten müssen bedeutsam genug sein, damit sich ein perfektes Ergebnis „verdient" anfühlt.
  • Versuchsobergrenze: höchstens N Versuche pro Sitzung (200 im Beispiel). Die Obergrenze verhindert Endlosschleifen und Serverlast.
  • Cooldown: Füge nach Sitzungsende eine kurze Wartezeit hinzu; erzwinge sie mit pc.setqf("sb_cd", get_global_time() + 60).
  • Protokollierung: Schreibe bei jedem Erfolg Spielername, Item, Ziel und Versuchszahl in die Datenbank/Logdatei; das ist entscheidend für Missbrauchserkennung und Debugging.

Vernachlässige auch die Sicherheitsprüfungen nicht: Stelle durchgehend sicher, dass das Ziel-Item noch im Inventar ist (der Spieler könnte es verkauft oder weggeworfen haben), warne den Nutzer, wenn ein +0-Item keine Boni hat, und verwende ein Flag, um zu verhindern, dass zwei Switchbot-Sitzungen gleichzeitig starten. Diese kleinen Prüfungen beugen Beschwerden wie „ich habe Yang für ein leeres Item ausgegeben" auf einem Live-Server vor.

Häufige Fragen

Garantiert der Switchbot einen Bonuswert?

Nein, das tut er nicht und sollte es auch nicht. Das System wiederholt nur change_attribute automatisch; jeder Versuch ist unabhängig und zufällig. Ein Switchbot nimmt nur die Mühe des „hundertfachen Klickens" ab — er ändert nicht die Wahrscheinlichkeiten. Willst du eine Garantie, ist das ein eigenes Feature (z. B. Bonus-Sperrung) mit einer weit heikleren Balance.

Belastet dieses System den Server?

Nein, solange du die Schleife mit server_timer in Schritte aufteilst statt mit einer while. Ein kurzes Intervall zwischen den Versuchen genügt, um die Arbeit zu verteilen, und die Versuchsobergrenze begrenzt den schlimmsten Fall. Die eigentliche Last entsteht, wenn man die Schleife in einem einzigen Frame ausführen will — vermeide das.

Ist ein clientseitiger Switchbot nicht einfacher?

Kurzfristig ja, aber er fällt dir später auf die Füße: Er kann vom Anti-Hack blockiert werden, lässt sich nicht prüfen und zerstört die Fairness zwischen Spielern. Das System auf dem Server zu bauen, kostet etwas mehr Aufwand, ist aber sicher, transparent und nachhaltig.

Willst du einen ausgewogenen, missbrauchssicheren Switchbot für deinen Server? Von der Zielauswahl über Kosten und Limits bis zu Logging und Oberfläche kann ich das ganze System von A bis Z bauen und testen. Um dein Projekt zu besprechen, nimm Kontakt mit mir auf.

Bu kategorideki tüm yazılar →

Devamı için