BetonQuest: Minecraft-Server-Quests einrichten (Leitfaden 2026)

BetonQuest: Minecraft-Server-Quests einrichten (Leitfaden 2026)

Wenn ein RPG-Projekt verzweigte NPC-Dialoge mit Bedingungen, Belohnungen und persistentem Status braucht statt eines simplen "tote 10 Zombies", deckt BetonQuest den ganzen Stack mit deklarativem YAML und null Code ab. Unten: Installation, das 2.x-Paketlayout, Objectives und Conditions, Integrationen mit Citizens und DecentHolograms, Migration von 1.x und die Performance-Fallen.

Was BetonQuest ist und warum deklarativ

BetonQuest ist ein Plugin fuer Bukkit-kompatible Cores, das Quests ueber reine YAML-Dateien beschreibt. Kein Skript, keine Kompilierung: Config schreiben, neu laden, der Quest laeuft. Quellcode und Doku liegen auf github.com/BetonQuest/BetonQuest und docs.betonquest.org.

Die Philosophie ist einfach. Ein Quest besteht aus vier Bausteinen.

  • Objectives - Aufgaben, die der Spieler erfuellt (Mob toeten, Item craften, Punkt erreichen)
  • Conditions - Pruefungen des Servers (hat der Spieler einen Tag, welche Klasse, welches Level)
  • Events - Aktionen, die der Server als Reaktion ausloest (Item geben, teleportieren, Tag setzen)
  • Conversations - Dialogbaeume mit NPCs, deren Knoten Conditions und Events tragen

In Summe entsteht ein Zustandsgraph pro Spieler, dessen Uebergaenge Tags und Points steuern. Code fuer "wenn der Spieler die Prinzessin gerettet hat, gibt der Schmied Rabatt" schreibt niemand: das passiert ueber tag-Conditions und tag add-Events.

Alternativen existieren. Quests Plugin hat eine flachere Lernkurve, aber eine harte Decke: komplexe Verzweigungen passen nicht rein. ZNPCsPlus + ZSkriptCore funktionieren, brauchen aber Skript-Code. Fuer einen ernsten RPG-Server mit Hunderten von Dialogknoten und persistentem Fortschritt ist BetonQuest die erste Wahl.

Installation und Abhaengigkeiten

BetonQuest 2.x zielt auf Paper 1.21+ und braucht Java 21. Der 1.x-Branch deckt aeltere Cores (1.16-1.20) ab, bekommt aber keine neuen Features mehr.

cd plugins/
wget -O BetonQuest.jar https://github.com/BetonQuest/BetonQuest/releases/latest/download/BetonQuest.jar
# oder von hangar.papermc.io/BetonQuest/BetonQuest

Nach dem Serverstart legt das Plugin plugins/BetonQuest/ mit folgender Struktur an:

plugins/BetonQuest/
├── config.yml
├── messages.yml
├── menuConfig.yml
├── lang/
└── QuestPackages/
    └── default/
        ├── package.yml
        ├── events.yml
        ├── conditions.yml
        ├── objectives.yml
        ├── conversations/
        └── journal.yml

Optionale Integrationen, die fast jeder Server installiert:

  • Citizens - Dialoge an sichtbare NPCs binden statt an stehende Skelette
  • DecentHolograms - Hologramme ueber NPCs und an Points of Interest
  • LuckPerms - Rechte ueber permission-Events vergeben
  • PlaceholderAPI - %betonquest_*% in Chat, Sidebar, Hologrammen
  • MythicMobs - Bosse ueber BetonQuest-Events spawnen, Killbedingungen fuer MythicMobs
  • ProtocolLib - mehrere Subsysteme brauchen es, standardmaessig installieren

Nach jeder YAML-Aenderung /q reload laufen lassen. Das liest alle Pakete ohne Restart neu ein. Wenn im Chat ein roter Parsefehler erscheint, logs/latest.log oeffnen: BetonQuest schreibt den vollen Pfad zur kaputten Zeile.

Paketlayout in 2.x: der Hauptunterschied zu 1.x

In 2.x wurden Pakete echte Verzeichnisse. Das alte Layout hielt alles in einer package.yml: Events, Conditions, Objectives, Dialoge. Das neue zerlegt die Teile in Unterordner, und jede Datei im Paket wird automatisch in die Konfiguration zusammengefuehrt.

QuestPackages/
└── city_quests/
    ├── package.yml          # Paket-Metadaten
    ├── events/
    │   ├── reward.yml
    │   └── teleport.yml
    ├── conditions/
    │   └── access.yml
    ├── objectives/
    │   └── main_chain.yml
    ├── conversations/
    │   ├── innkeeper.yml
    │   └── blacksmith.yml
    └── journal.yml

Das zahlt sich ab 50 Quests aus. Jeder Story-Bogen lebt in seiner eigenen Datei, Sub-Pakete entsprechen verschachtelten Ordnern: QuestPackages/main/chapter_one/ und QuestPackages/main/chapter_two/ sind zwei separate Pakete main-chapter_one und main-chapter_two.

Eine minimale package.yml:

package:
  enabled: true
  priority: 0
variables:
  city_name: "Nordhafen"
  reward_amount: 200

Variablen aus variables: stehen dann als %city_name% in jedem Dialogtext oder Message zur Verfuegung.

Erster Dialog: ein YAML-Beispiel

QuestPackages/city_quests/conversations/innkeeper.yml anlegen. Das ist ein Dialog mit dem Wirt, der einen Quest zur Rattenbekaempfung im Keller vergibt.

conversations:
  innkeeper:
    quester: "&6Wirt"
    first: greeting
    NPC_options:
      greeting:
        text: "Komische Geraeusche aus dem Keller... Schaust du nach?"
        conditions: "!quest_started,!quest_done"
        pointers: accept,ask_reward,decline
      already_started:
        text: "Wie laeufts mit den Ratten?"
        conditions: "quest_started,!rats_killed"
        pointers: still_busy,decline
      give_reward:
        text: "Danke, hier dein Anteil."
        conditions: "rats_killed,!quest_done"
        events: pay_reward,close_quest
      after_done:
        text: "Komm vorbei, Reisender."
        conditions: "quest_done"
    player_options:
      accept:
        text: "Ich schau mal. Wo ist der Eingang?"
        events: start_quest,give_torch
        pointer: accepted
      ask_reward:
        text: "Was springt fuer mich raus?"
        pointer: reward_info
      decline:
        text: "Nicht jetzt."
      still_busy:
        text: "Suche noch."
      reward_info:
        text: "200 Muenzen und Essen aufs Haus."
        pointer: greeting

Was hier passiert:

  • quester - der Name im Dialogfenster
  • first - der Start-Knoten des NPC
  • NPC_options - NPC-Zeilen. Jede mit eigenen Conditions und einer Liste von Pointern auf Spieleroptionen
  • player_options - Spielerzeilen. Jede kann Events feuern und ueber pointer weiterspringen
  • conditions - was wahr sein muss, damit eine Zeile erscheint. Praefix ! invertiert
  • events - feuern, wenn die Zeile gewaehlt wird

Die IDs accept, quest_started, pay_reward sind noch nicht definiert, der Server meckert beim /q reload. Auf zu Objectives und Events.

Objectives und Conditions: Aufgaben und Pruefungen

Objectives in QuestPackages/city_quests/objectives/main_chain.yml:

objectives:
  hunt_rats:
    type: mobkill
    conditions: ""
    events: rats_done
    instruction: mobkill RAT 5 events:rats_done notify
  reach_cellar:
    type: location
    instruction: location 100;64;200;world 3 events:cellar_reached
  craft_torch:
    type: craft
    instruction: craft TORCH 4

Der Typ mobkill nutzt einen MythicMob mit der ID RAT, das Beispiel braucht also MythicMobs. Fuer Vanilla-Mobs mobkill ZOMBIE 5 schreiben. Das Flag notify zeigt dem Spieler den Fortschritt in der Action Bar.

Conditions in conditions.yml:

conditions:
  quest_started:
    type: tag
    instruction: tag rats_quest_started
  rats_killed:
    type: objective
    instruction: objective hunt_rats
  quest_done:
    type: tag
    instruction: tag rats_quest_done
  has_torch:
    type: item
    instruction: item torch:1
  is_warrior:
    type: variable
    instruction: variable %class% warrior

Conditions lesen sich als "Pruefung des Servers im Klickmoment". Wenn der Spieler die accept-Zeile waehlt, evaluiert BetonQuest alle Conditions des NPC-Knotens und zeigt die Zeile nur, wenn sie alle wahr sind.

Events und Tags: was das Plugin auswirft

Events sind, was der Server auf Spieleraktionen oder Timer feuert. Die Datei events.yml:

events:
  start_quest:
    type: tag
    instruction: tag add rats_quest_started
  pay_reward:
    type: give
    instruction: give emerald:5,gold_ingot:10
  close_quest:
    type: folder
    instruction: folder mark_done,remove_objective,journal_finished
  mark_done:
    type: tag
    instruction: tag add rats_quest_done
  remove_objective:
    type: objective
    instruction: objective remove hunt_rats
  give_torch:
    type: give
    instruction: give torch:4
  journal_finished:
    type: journal
    instruction: journal add rats_finished
  teleport_cellar:
    type: teleport
    instruction: teleport 100;64;200;world
  rats_done:
    type: notify
    instruction: notify {en}Rats cleared!{de}Ratten erledigt! io:Title

Der Trick mit folder ist ein Container, der mehrere Events nacheinander abarbeitet. Damit muessen Aufrufe nicht in jedem Dialogzweig dupliziert werden.

Tags sind der zuverlaessigste Weg, Quest-Status zu merken. Sie liegen in der Plugin-Datenbank (Standard SQLite, oder MySQL via config.yml) und ueberleben Restarts. Im Produktivbetrieb gehoert MySQL aktiviert: SQLite sperrt die Datei beim Schreiben, und ein Crash mitten im Schreiben kostet Spielerfortschritt.

Citizens- und DecentHolograms-Integration

Um einen Dialog an einen Citizens-NPC zu binden, in package.yml einen npcs:-Block hinzufuegen. Die NPC-ID kommt aus /npc select und /npc info.

npcs:
  "12": innkeeper
  "13": blacksmith
  "14": village_elder

Ein Rechtsklick auf NPC 12 oeffnet jetzt den innkeeper-Dialog. Keine separate npc.yml noetig, alles im Paket.

DecentHolograms macht Hologramme bedingt, etwa ein "?"-Icon ueber einem NPC mit verfuegbarem Quest:

events:
  show_marker:
    type: hologram
    instruction: hologram quest_marker
  hide_marker:
    type: hologram
    instruction: hologram quest_marker hide

Das Hologramm selbst entsteht ueber /dh create quest_marker und wird mit /dh attach quest_marker npc_12 0 2.5 0 befestigt. BetonQuest steuert nur die Sichtbarkeit.

Journal und Spieler-UI

Das Journal ist ein Buch, das dem Spieler erzaehlt, was er gerade tut und was schon erledigt ist. Eintraege in journal.yml:

journal:
  rats_started: "&7Im Kellerraum der Schenke raschelt etwas. Der Wirt bat mich, mich um die Ratten zu kuemmern."
  rats_finished: "&aRatten weg, Belohnung kassiert."
  blacksmith_intro: "&7Der Schmied sucht einen Lehrling."

Eintraege werden mit journal add <id> ergaenzt und mit journal del <id> entfernt. Standardmaessig oeffnet /journal das Buch. Der Aufruf laesst sich ueber config.yml an den Rechtsklick auf das Buch im Inventar haengen:

journal:
  give_on_join: true
  custom_journal: true
  show_in_backpack: true

Fuer eine konsolidierte Fortschritts-UI gibt es das eingebaute Menue (/q menu) oder externe Plugins wie QuestsGUI. Grosse Projekte bauen meist eine eigene GUI auf PlaceholderAPI, weil das eingebaute Menue feature-arm ist.

Objective-Spickzettel

TypWas es zaehltBeispiel-Instruction
mobkillMob-Killsmobkill ZOMBIE 10 notify
locationZone betretenlocation 100;64;-50;world 5
blockBlock break/placeblock COAL_ORE 32 events:done
craftCraftingcraft DIAMOND_PICKAXE 1
interactKlick auf Block/Mobinteract left ANY ENTITY
consumeEssen/Trinkenconsume cooked_beef 5
enchantVerzaubernenchant diamond_sword sharpness:3
fishAngelnfish COD 20
killSpielerkillkill name:Steve 1
breedTierzuchtbreed COW 3
commandBefehlseingabecommand !/spawn
delayX Minuten wartendelay 30 ticks:false
experienceXP sammelnexperience 30 level
passwordChat-Eingabepassword secretWord

Vollstaendige Liste und Parameter auf docs.betonquest.org/objectives. Jedes Objective akzeptiert Flags wie notify, persistent (kein Reset bei Reconnect), events: fuer Trigger nach Abschluss.

Migration von 1.x auf 2.x: was zu beachten ist

Wer noch 1.x produktiv faehrt, kann nicht einfach umschalten. Das Paketformat ist neu, viele Events wurden umbenannt, das Journal sitzt auf neuem Storage. Das BetonQuest-Team hat einen eingebauten Migrator:

/q migrate

Der Befehl konvertiert alte QuestPackages/<name>/main.yml-Layouts in das neue Verzeichnisformat. Vorher plugins/BetonQuest/ und die Datenbank (SQLite-Datei oder MySQL-Dump) sichern. Nach der Migration auf einem Staging-Server testen: eigene Events und Integrationen muessen oft nachgezogen werden.

Was umbenannt wurde:

  • inline tag: -> expliziter tag-Typ mit instruction
  • inline-Conditions per Komma -> separates conditions:-Feld
  • altes point-Format -> neues point-Event mit instruction
  • Compat zu Heroes/MythicLib gegen neue APIs neu gebaut

Bricht die Migration, Backup zurueckspielen und docs.betonquest.org/migration Schritt fuer Schritt durchgehen. Die Maintainer dokumentieren jeden Breaking Change.

Performance: was TPS frisst

BetonQuest selbst ist leicht: Events und Conditions laufen auf Bukkit-Hooks, Pruefungen im Main-Thread. Engpaesse entstehen durch Fehlkonfiguration.

  • MySQL statt SQLite ist Pflicht ab 100+ gleichzeitigen Spielern. Der File-Lock von SQLite blockiert Writes, Quest-Events stauen sich
  • location-Objectives pruefen jede Spielerposition einmal pro Sekunde. 200 solche Objectives bei 100 Online sind 20000 Checks pro Sekunde. location fuer Zielpunkte nutzen, fuer Zonen lieber region mit WorldGuard und worldguard-Condition
  • delay-Objectives laufen nur auf Ticks, wenn ticks:true gesetzt ist. Ohne das nutzen sie Systemzeit, ueberleben Restarts und belasten den Scheduler nicht
  • debug in config.yml muss in Produktion false sein. Mit true spamt BetonQuest jede Aktion in die Konsole, ein aktiver Quest-Strang blaeht das Log um 100 MB pro Stunde
  • Conversations mit grossen Baeumen (100+ Knoten) brauchen Sekunden zum Parsen bei /q reload. In mehrere Dateien unter conversations/ aufteilen, das Plugin merged automatisch

Wenn das Plugin im Spark-Profiler auftaucht, lohnt der Blick auf WorldGuard-Tickers und die Objectives selbst. Oft liegt es nicht an BetonQuest, sondern an Callback-Plugins (MythicMobs, Citizens), die BetonQuest aufruft.

Typische Fehler im Adminalltag

  • Alle Quests in einem Paket. Nach sechs Monaten liegen 200 Dateien in default/ und jede Aenderung bricht den Nachbarn. Pro Storyline ein Paket
  • Tags statt Objective-Conditions. Wenn das Objective direkt geprueft werden kann (condition objective hunt_rats), keine Zwischen-Tags wie started_hunt_rats anlegen
  • Hartkodierte Koordinaten in YAML. Spawn verschoben, alle location-Objectives kaputt. Koordinaten in variables: auslagern, %spawn_x% referenzieren
  • Keine Journaleintraege. Spieler laeuft durch 5 NPCs, vergisst, zu wem er zurueck soll, bricht den Quest ab. Jeder Schritt sollte eine Journalzeile erzeugen
  • ID-Konflikte zwischen Paketen. start-Dialog in drei Paketen: BetonQuest nimmt das zuerst geladene. Praefixe nutzen: city_innkeeper, dungeon_innkeeper
  • Keine !-Inversionen. Ohne !quest_done bietet der NPC den Quest endlos auch nach Abschluss an
  • MySQL ohne Backup. Quest-Fortschritt sind Spielerdaten, der Verlust schmerzt wie ein zerschossenes Inventar. Stuendliches Dump auf separate Platte einrichten

FAQ

Laeuft BetonQuest auf Folia? Offiziellen Folia-Support gibt es nicht. Manche Teile funktionieren, aber Conversations und Timer brechen ueber Regionen. Das Issue-Tracker-Team nennt Folia in der Roadmap, ohne Datum. Bis dahin Quests Plugin oder warten.

Wo unterscheiden sich BetonQuest und Quests Plugin? Quests ist einfacher zu starten: GUI-Konfigurator, simple Aufgaben. BetonQuest ist haerter, liefert aber verzweigte Dialoge, beliebige Condition-Logik und einen echten Quest-Graph. Fuer "tote 50 Zombies, kriege einen Diamanten" reicht Quests. Fuer eine Skyrim-aehnliche Kette ueber 30 NPCs und Bedingungen liefert nur BetonQuest.

Wie baue ich Daily Quests? Mit delay-Event und ticks:false plus objective-Condition. Spieler beendet Quest -> Event setzt einen Tag mit TTL ueber ein delay-Objective -> nach 24 Stunden entfernt BetonQuest den Tag, der Quest ist wieder verfuegbar.

Was tun, wenn das Plugin beim Start crasht? In 90% der Faelle ist es kaputtes YAML in einem Paket. logs/latest.log zeigt den exakten Pfad. Eine Runde durch yamllint faengt das oft.

Kann ich fertige Quests importieren? Ja, github.com/BetonQuest/Quest-Tutorials hat eine 2.x-Sample-Sammlung. Ordner nach QuestPackages/ legen, /q reload. Vor Einsatz Versionskompatibilitaet pruefen: 1.x-Pakete laden ohne Migration nicht.

Wie trenne ich Quests pro Server in BungeeCord? In config.yml mysql: auf eine gemeinsame Datenbank zeigen lassen. BetonQuest speichert Tags an die Spieler-UUID, der Fortschritt ist serveruebergreifend. Pakete bleiben pro Server unterschiedlich: Hub-Set, RPG-World-Set, Minigames-Set.

Wenn die Quests Fahrt aufnehmen und der Server echtes Publikum zieht, gehoert DDoS-Schutz auf die Liste fuer Event-Launches. Ein gut inszenierter Quest-Event mit Massen-Teleport hat sich bei uns mehr als einmal mit Angriffsversuchen ueberlappt. BetonQuest aendert daran nichts, aber ein Filter davor ist in solchen Spitzen Gold wert.


Schützen Sie Ihren Server vor DDoS-Angriffen

Kostenloser Schutz mit 5-Minuten-Einrichtung. 1 TB Traffic inklusive.

Kostenlos testen


Weitere Artikel