BetonQuest: konfiguracja questow na serwerze Minecraft (2026)

BetonQuest: konfiguracja questow na serwerze Minecraft (2026)

Jezeli projekt RPG potrzebuje rozgalezionych dialogow z NPC, warunkow, nagrod i trwalego stanu zamiast prostego "zabij 10 zombie", BetonQuest ogarnia caly stack przez deklaratywny YAML i zero kodu. Ponizej: instalacja, uklad pakietow 2.x, objectives i conditions, integracja z Citizens i DecentHolograms, migracja z 1.x i pulapki wydajnosciowe.

Czym jest BetonQuest i po co deklaratywne questy

BetonQuest to plugin pod silniki kompatybilne z Bukkit, ktory definiuje questy w plikach YAML. Bez skryptu, bez kompilacji: piszesz config, przeladowujesz, quest dziala. Zrodla i dokumentacja: github.com/BetonQuest/BetonQuest i docs.betonquest.org.

Filozofia jest prosta. Quest sklada sie z czterech klockow.

  • Objectives - zadania, ktore gracz wykonuje (zabij moba, zrob przedmiot, dotrzyj do punktu)
  • Conditions - sprawdzenia serwera (czy gracz ma tag, jaka klase, jaki poziom)
  • Events - akcje, ktore serwer odpala w odpowiedzi (daj item, teleportuj, ustaw tag)
  • Conversations - drzewa dialogow z NPC, w ktorych wezlach siedza warunki i eventy

Razem to graf stanow gracza, w ktorym przejscia steruja tagami i punktami. Nikt nie pisze kodu dla "jezeli gracz uratowal ksiezniczke, kowal daje znizke" - to robia warunki tag i eventy tag add.

Alternatywy istnieja. Quests Plugin ma niski prog wejscia, ale niski sufit: zlozone gałezie sie nie miesza. ZNPCsPlus + ZSkriptCore dzialaja, ale wymagaja kodu Skript. Do powaznego serwera RPG z setkami wezlow dialogowych i trwalym postepem miedzy sesjami bierz BetonQuest od razu.

Instalacja i zaleznosci

BetonQuest 2.x celuje w Paper 1.21+ i wymaga Java 21. Galaz 1.x obsluguje starsze rdzenie (1.16-1.20), ale juz nie dostaje nowych funkcji.

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

Po starcie serwera plugin tworzy plugins/BetonQuest/ z taka struktura:

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

Opcjonalne integracje, ktore prawie kazdy zaklada:

  • Citizens - zeby przypiac dialogi do widocznych NPC zamiast szkieletow
  • DecentHolograms - hologramy nad NPC i w punktach zainteresowania
  • LuckPerms - nadawanie uprawnien przez eventy permission
  • PlaceholderAPI - %betonquest_*% w czacie, sidebarze, hologramach
  • MythicMobs - spawnowanie bossow eventami BetonQuest i warunki na zabicie MythicMoba
  • ProtocolLib - kilka podsystemow tego potrzebuje, instalujemy domyslnie

Po kazdej zmianie YAML uruchom /q reload. To przeczyta wszystkie pakiety bez restartu serwera. Jezeli na czacie pojawi sie czerwony blad parsowania, otworz logs/latest.log: BetonQuest zapisuje tam pelna sciezke do popsutej linii.

Uklad pakietow w 2.x: glowna roznica wzgledem 1.x

W 2.x pakiety stalo sie pelnoprawnymi katalogami. Stary uklad trzymal wszystko w jednym package.yml: eventy, warunki, objectives, dialogi. Nowy rozkłada to na podfoldery, a kazdy plik w pakiecie automatycznie laczy sie do jednej konfiguracji.

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

Sila przy 50+ questach. Kazda linia fabularna w osobnym pliku, sub-pakiety jako zagniezdzone foldery: QuestPackages/main/chapter_one/ i QuestPackages/main/chapter_two/ to dwa odrebne pakiety nazwane main-chapter_one i main-chapter_two.

Minimalny package.yml:

package:
  enabled: true
  priority: 0
variables:
  city_name: "Polnocny Port"
  reward_amount: 200

Zmienne z variables: sa potem dostepne jako %city_name% w dowolnym tekscie dialogu lub wiadomosci.

Pierwszy dialog: konkretny YAML

Tworzymy QuestPackages/city_quests/conversations/innkeeper.yml. To dialog z karczmarzem, ktory daje quest na szczury w piwnicy.

conversations:
  innkeeper:
    quester: "&6Karczmarz"
    first: greeting
    NPC_options:
      greeting:
        text: "Dziwne dzwieki z piwnicy... rzucisz okiem?"
        conditions: "!quest_started,!quest_done"
        pointers: accept,ask_reward,decline
      already_started:
        text: "Co ze szczurami?"
        conditions: "quest_started,!rats_killed"
        pointers: still_busy,decline
      give_reward:
        text: "Dzieki, oto twoja dzialka."
        conditions: "rats_killed,!quest_done"
        events: pay_reward,close_quest
      after_done:
        text: "Wpadaj, podrozniku."
        conditions: "quest_done"
    player_options:
      accept:
        text: "Zerkne. Gdzie wejscie?"
        events: start_quest,give_torch
        pointer: accepted
      ask_reward:
        text: "Co z tego mam?"
        pointer: reward_info
      decline:
        text: "Nie teraz."
      still_busy:
        text: "Nadal je tropie."
      reward_info:
        text: "200 monet i posilek na koszt firmy."
        pointer: greeting

Co tu sie dzieje:

  • quester - imie wyswietlane w oknie dialogowym
  • first - startowy wezel NPC, od ktorego rusza rozmowa
  • NPC_options - kwestie NPC. Kazda z wlasnymi warunkami i lista pointerow do opcji gracza
  • player_options - kwestie gracza. Kazda moze odpalac eventy i przeskakiwac dalej przez pointer
  • conditions - co musi byc spelnione, zeby kwestia sie pokazala. Prefiks ! odwraca
  • events - odpalaja sie po wybraniu kwestii

ID accept, quest_started, pay_reward jeszcze nie ma, wiec serwer przyklepie blad przy /q reload. Czas na objectives i events.

Objectives i conditions: zadania i sprawdzenia

Objectives w 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

Typ mobkill uzywa MythicMoba o id RAT, wiec ten przyklad wymaga MythicMobs. Dla zwyklego zombie wpisz mobkill ZOMBIE 5. Flaga notify pokazuje graczowi postep w action barze.

Warunki w 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

Warunki czyta sie jako "sprawdzenie serwera w momencie kliku". Gdy gracz wybiera kwestie accept, BetonQuest sprawdza wszystkie warunki rodzicielskiego wezla NPC i pokazuje kwestie tylko, jezeli wszystkie sa prawda.

Events i tagi: jak plugin reaguje

Eventy to to, co serwer odpala w odpowiedzi na akcje gracza lub timer. Plik 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!{pl}Szczury wyczyszczone! io:Title

Sztuczka z folder to kontener kilku eventow odpalanych po kolei. Eliminuje duplikowanie wywolan w kazdej galezi dialogu.

Tagi to najpewniejszy sposob zapamietania stanu questa. Siedza w bazie pluginu (domyslnie SQLite, opcjonalnie MySQL po zmianie w config.yml) i przezywaja restart. Na produkcji wlaczasz MySQL: SQLite blokuje plik na zapis i crash w trakcie pisania kosztuje postep gracza.

Integracja z Citizens i DecentHolograms

Zeby przypiac dialog do NPC z Citizens, w package.yml dodajemy blok npcs:. ID NPC bierze sie z /npc select plus /npc info.

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

Prawy klik w NPC o id 12 otwiera teraz dialog innkeeper. Zadnego osobnego npc.yml nie trzeba, wszystko siedzi w pakiecie.

DecentHolograms robi hologramy warunkowe, np. ikone "?" nad NPC z dostepnym questem:

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

Sam hologram tworzy sie przez /dh create quest_marker i przyczepia komenda /dh attach quest_marker npc_12 0 2.5 0. BetonQuest zarzadza tylko widocznoscia.

Dziennik i UI gracza

Dziennik to ksiazka, ktora mowi graczowi, co teraz robi i co skonczyl. Wpisy w journal.yml:

journal:
  rats_started: "&7W piwnicy karczmy cos szelesci. Karczmarz prosil, zebym zajal sie szczurami."
  rats_finished: "&aSzczury wyczyszczone, nagroda odebrana."
  blacksmith_intro: "&7Kowal szuka czeladnika."

Wpisy dodaje sie eventem journal add <id> i kasuje journal del <id>. Domyslnie gracz otwiera dziennik komenda /journal. Otwieranie da sie podpiac pod prawy klik ksiazki w ekwipunku przez config.yml:

journal:
  give_on_join: true
  custom_journal: true
  show_in_backpack: true

Do zbiorczego UI z postepem questow jest wbudowane menu (/q menu) lub wtyczki w stylu QuestsGUI. Wieksze projekty piszą wlasne GUI na PlaceholderAPI, bo wbudowane menu jest dosc ubogie.

Sciaga z objectives

TypCo liczyPrzykladowy instruction
mobkillzabicia mobowmobkill ZOMBIE 10 notify
locationwejscie w promienlocation 100;64;-50;world 5
blockbreak/place blokublock COAL_ORE 32 events:done
craftcraftingcraft DIAMOND_PICKAXE 1
interactklik w blok/mobainteract left ANY ENTITY
consumejedzenie/picieconsume cooked_beef 5
enchantzakleciaenchant diamond_sword sharpness:3
fishwedkowaniefish COD 20
killzabicie graczakill name:Steve 1
breedhodowla zwierzatbreed COW 3
commandwpisanie komendycommand !/spawn
delayodczekanie X minutdelay 30 ticks:false
experiencezbieranie XPexperience 30 level
passwordwpis na czaciepassword secretWord

Pelna lista i parametry: docs.betonquest.org/objectives. Kazdy objective przyjmuje flagi typu notify, persistent (brak resetu po reconnect), events: na uruchomienie po zakonczeniu.

Migracja z 1.x na 2.x: na co uwazac

Jezeli na produkcji nadal siedzi 1.x, prosto sie nie przeskoczy. Format pakietow inny, sporo eventow zmienilo nazwy, dziennik przeniesiony na nowy storage. Zespol BetonQuest zrobil wbudowany migrator:

/q migrate

Komenda przerabia stary uklad QuestPackages/<name>/main.yml na nowy katalog. Przed uruchomieniem zrob backup plugins/BetonQuest/ i bazy (plik SQLite albo zrzut MySQL). Po migracji puscic na stagingu - czesc wlasnych eventow i integracji wymaga reki.

Co zmienilo nazwy:

  • inline tag: -> jawny typ tag z instruction
  • inline-warunki po przecinku -> osobne pole conditions:
  • stary format point -> nowy event point z instruction
  • compat z Heroes/MythicLib przepisany pod nowe API

Jezeli migracja sie wywala, wracaj do backupu i przejdz docs.betonquest.org/migration krok po kroku. Maintainerzy opisuja kazdy breaking change.

Wydajnosc: co zjada TPS

Sam BetonQuest jest lekki: eventy i conditions chodza po hookach Bukkit, sprawdzenia w glownym watku. Waskie gardla biora sie ze zlej konfiguracji.

  • MySQL zamiast SQLite to obowiazek przy 100+ online. Lock pliku SQLite blokuje zapisy, eventy questowe ustawiaja sie w kolejce
  • objective location sprawdza pozycje gracza co sekunde. 200 takich objectives przy 100 online to 20 tysiecy sprawdzen na sekunde. location na koncowe punkty, na strefy lepiej region z WorldGuard i warunkiem worldguard
  • objective delay chodzi po tickach tylko z ticks:true. Domyslnie liczy w czasie systemowym, przezywa restart i nie obciaza schedulera
  • debug w config.yml musi byc false na produkcji. Z true BetonQuest spamuje konsole na kazdej akcji, a aktywna linia questowa pucznie log o 100 MB na godzine
  • conversations z duzymi drzewami (100+ wezlow) parsuja sie sekundami przy /q reload. Rozbijaj po plikach w conversations/, plugin laczy automatycznie

Jezeli plugin pojawia sie w spark profilerze, popatrz na tickery WorldGuard i same objectives. Czesto winnym nie jest BetonQuest, tylko callback-pluginy (MythicMobs, Citizens), do ktorych on woła.

Typowe bledy adminow

  • Wszystkie questy w jednym pakiecie. Po pol roku w default/ siedzi 200 plikow i jedna edycja psuje sasiada. Pakiet na linie fabularna
  • Tagi zamiast objective-conditions. Jezeli da sie sprawdzic objective wprost (condition objective hunt_rats), nie mnoz tagow w stylu started_hunt_rats
  • Wpisane na sztywno koordynaty w YAML. Przesuwasz spawn i wszystkie location lecą. Wynies koordynaty do variables: i odwoluj sie do %spawn_x%
  • Brak wpisow w dzienniku. Gracz przeszedl przez 5 NPC, zapomnial, do kogo wraca, rzucil quest. Kazdy istotny krok ma dopisac linie do dziennika
  • Konflikt ID miedzy pakietami. Dialog start w trzech pakietach: BetonQuest bierze pierwszy zaladowany. Prefiksuj: city_innkeeper, dungeon_innkeeper
  • Brak inwersji !. Bez !quest_done NPC bedzie w nieskonczonosc oferowal quest juz wykonany
  • MySQL bez backupu. Postep questow to dane gracza, strata boli jak skasowane ekwipunki. Zrzut co godzine na osobny dysk

FAQ

Czy BetonQuest dziala na Folii? Oficjalnego wsparcia Folii nie ma. Czesc rzeczy chodzi, ale conversations i timery sie sypia na regionach. Tracker issues twierdzi, ze Folia jest w roadmapie bez daty. Do tego czasu Quests Plugin albo czekaj.

Czym BetonQuest rozni sie od Quests Plugin? Quests jest latwiejszy w starcie: konfigurator GUI, proste zadania. BetonQuest jest trudniejszy, ale daje rozgalezione dialogi, dowolna logike warunkow i prawdziwy graf questowy. Do "zabij 50 zombie, dostan diament" wystarczy Quests. Do lancucha w stylu Skyrim z 30 NPC i warunkami tylko BetonQuest dowiezie.

Jak zrobic questy dzienne? Eventem delay z ticks:false plus warunkiem objective. Gracz konczy quest -> event ustawia tag z TTL przez objective delay -> po 24 godzinach BetonQuest zdejmuje tag, quest jest dostepny ponownie.

Co zrobic, jezeli plugin crashuje przy starcie? W 90% przypadkow to popsuty YAML w jednym z pakietow. Zajrzyj w logs/latest.log, BetonQuest poda dokladna sciezke. Czesto pomaga przepuszczenie pliku przez yamllint.

Czy mozna zaimportowac gotowe questy? Tak, github.com/BetonQuest/Quest-Tutorials trzyma kolekcje przykladow pod 2.x. Folder do QuestPackages/ i /q reload. Przed uzyciem sprawdz wersje: pakiety 1.x bez migracji sie nie zaladuja.

Jak rozdzielic questy miedzy serwery w BungeeCord? W config.yml ustaw mysql: na jedna baze dla wszystkich serwerow. BetonQuest trzyma tagi po UUID gracza, postep jest wspolny. Pakiety zostaja rozne na kazdym serwerze: hub jeden zestaw, RPG inny, minigry kolejny.

Gdy questy sie rozkrecaja i serwer zaczyna lapac realna publike, w pamieci trzymaj ochrone DDoS pod premiery duzych eventow. Dobrze poprowadzony quest-event z masowym teleportem nie raz w naszej praktyce trafial sie razem z probami zdjecia serwera. BetonQuest sam tego nie zalatwi, ale filtr na wejsciu w takich szczytach warto miec na liscie.


Chroń swój serwer przed atakami DDoS

Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.

Wypróbuj za darmo


Powiązane artykuły