⚡ QuestEngine — Easy Guide for New Developers
(A simple yet powerful quest system)
What This Plugin Does
QuestEngine is an event-based quest system.
In plain words, it’s an automatic tracker that updates quests whenever players do certain actions.
Think of it like this:
Breaking stone → progress in “Mine Stone” quest +1
Killing a mob → progress in “Monster Hunter” quest +1
Talking or crafting → updates related quests automatically
Everything happens automatically as players play.
⚙️ How It Works (Simple Explanation)
EventDispatcher
Think of this as the brain that senses player actions.
It listens to almost every Minecraft action (called “events”) and passes them to the Quest Engine.
Examples of detected events:
Block breaking (BlockBreakEvent)
Mob killing (EntityDeathEvent)
Crafting (CraftItemEvent)
Chatting (AsyncPlayerChatEvent)
Walking or moving (PlayerMoveEvent)
Whenever something happens, it runs a line like:
engine.handle(player, "BLOCK_BREAK", e);
That tells the Engine, “Hey, this player just broke a block!”
Engine (Main Logic)
This is where the actual quest logic lives.
It checks which quests are waiting for that event and updates progress or rewards when conditions are met.
QuestPapiExpansion
This part connects QuestEngine to PlaceholderAPI —
so you can show quest info on your HUD, scoreboard, or GUI using placeholders like:
%questengine_progress_stone_break%
How a Quest Actually Works
Every quest is just a YAML file — no coding needed!
Here’s a real example
Example Quest — “Mine Stone”
Code (Text):
name: "Template Quest"
id: template_quest
event: BLOCK_BREAK
targets:
- STONE
amount: 10
points: 5
repeat: 0
public: false
party: false
type: vanilla
start_mode: AUTO
reset:
policy: DAILY
time: "04:00"
display:
title: "&aTemplate Quest Title"
description:
- "&7Break 10 stones to test all features."
- "&eThis is a sample quest file."
progress: "&fProgress: &a%value%/%target%"
reward: "&eReward: 100 Coins"
category: "&6General"
difficulty: "&aEasy"
icon: DIAMOND_PICKAXE
hint: "&7Try mining around the spawn area."
customModelData: 12345
conditions:
start:
- "%player_level% >= 1"
success:
- "%block_type% == STONE"
fail:
- "%world_name% == nether"
actions:
start:
- msg{t="&7Quest started: &aMine 10 stones!"} @self
success:
- msg{t="&aYou completed the mining quest!"} @self
- command{c="eco give %player% 100"} @server
cancel:
- msg{t="&cQuest canceled."} @self
fail:
- msg{t="&cQuest failed because you went to the Nether."} @self
next:
- command{c="quest start next_quest"} @self
chain:
next: next_quest
custom_event_data:
event: org.bukkit.event.player.PlayerToggleSneakEvent
player_variable: getPlayer()
variables_to_capture:
- "%is_sneaking%;isSneaking()"
- "%world%;getPlayer().getWorld().getName()"
Step-by-Step Example
Player accepts the quest
→ runs actions.accept
Player breaks a block
→ EventDispatcher detects it
→ runs engine.handle(player, "BLOCK_BREAK", e)
- → if the block type is STONE, progress +1→ shows message “Mine 10 stones!”
After 10 stones
→ actions.success triggers
- Next day at 4 AM
→ reset.policy: DAILY resets progress automatically→ player gets message + 100 coins
- Why It’s Fast and Stable
This plugin isn’t just “lots of events” —
it’s optimized for performance, so it stays smooth even on large servers.
In simple terms:
It only runs when neededTiny movements don’t trigger constant updates.The setting player-walk-min-dist-sq controls how far a player must move before the plugin reacts.Smart mathIt uses
squared distance (x²+y²+z²) instead of slow sqrt() calculations.
No dependency crashesIf MythicMobs or Paper isn’t installed, the plugin quietly skips those features.It automatically connects only if the plugin exists.Cached performanceThe PlaceholderAPI data is cached for 1 second,
so even hundreds of scoreboard updates per second won’t lag the server.
How the Cache Works
Example:
%questengine_current_progress% → "7/10"
First request → calculated and stored (“7/10”)Within 1 second → reused instantly (no recalculation)
After 1 second → recalculated again
Even if 100 players have scoreboards, it barely affects performance.
Server Config Tip
In your config.yml, you’ll see something like:
performance:
player-walk-min-dist-sq: 0.64
This controls how sensitive the movement detection is.
Higher value → fewer checks, better performance
Lower value → more precise tracking
For example:
Survival servers → 0.64 or higher (less lag)
Parkour / RPG servers → 0.25–0.49 (more precise)
Expanding Made Simple
Let’s say you want a Fishing Quest.
Just create a new file fishing.yml and change the event type:
name: "Fishing Master"
id: fishing_master
event: FISHING
amount: 5
display:
title: "&bFishing Master"
description:
- "&7Catch 5 fish to prove your skills!"
reward: "&eReward: 200 Coins"
actions:
success:
- cmd{c=eco give %player% 200} @server
That’s it — you just made a completely new quest!
Summary
Feature Description
Core Structure EventDispatcher → Engine → PlaceholderAPI
Performance Fast detection, low CPU, high scalability
Configuration Everything defined in simple YAML
Conditions Player level, block type, biome, permissions
Rewards Vault commands, messages, repeatable quests
Integrations MythicMobs, PlaceholderAPI (auto detect)
Caching 1-second PAPI cache, zero GC overhead
Final Thoughts
QuestEngine is
“A performance-focused quest engine that turns any player action into a quest.”
You don’t need to know Java —
just write a few lines of YAML and you can build daily, weekly, or repeatable quests easily.
It’s fast, stable, and friendly for both new and advanced server owners.