Quests
Configure the quest system
Overview
The quest system lets you create tasks for players to complete — gathering resources, reaching skill levels, killing entities, and more. Quests are defined as JSON files in mods/mmoskilltree/quests/ and loaded automatically on startup.
Quests are organized into categories (e.g., main, daily, misc) and can have prerequisites, level requirements, and permission gates. Players interact with quests via the Quests UI tab or /quest, and admins manage them with /mmoquestadmin.
Default Quests & Customization
On every server start, default quests are written to mods/mmoskilltree/quests/_defaults/default-quests.json. This file is always overwritten, so defaults stay up-to-date with new mod versions automatically.
To customize quests, create your own .json files anywhere in the quests/ folder (or subdirectories). If any user files exist outside of _defaults/ and backups/, the default quests are ignored entirely. The generated default file remains as a reference you can copy and customize.
Servers upgrading from older versions will have their example-quests.json automatically moved to quests/backups/.
After editing quest files, run /mmoquestadmin reload to apply changes without restarting the server.
File Structure
Each JSON file in the quests/ directory contains a schemaVersion and a quests array. You can split quests across multiple files (e.g., one per category). The directory is scanned recursively.
{
"schemaVersion": 1,
"quests": [
{
"id": "mining_beginner",
"displayName": "Novice Miner",
"description": "Prove your mining skills by breaking some stone.",
"category": "main",
"enabled": true,
"sortOrder": 1,
"autoAccept": true,
"sequential": false,
"repeatable": false,
"cooldownSeconds": 0,
"autoClaimRewards": true,
"permission": null,
"prerequisites": [],
"requirements": {
"minLevel": 0,
"minSkill": null,
"minSkillLevel": 0
},
"objectives": [
{
"id": "mine_stone",
"type": "BREAK_BLOCK",
"target": "Stone",
"amount": 150,
"displayText": "Mine 150 Stone blocks",
"matchMode": "CONTAINS"
}
],
"rewards": [
{
"command": "/give {player} Tool_Pickaxe_Iron --quantity=1",
"runAs": "CONSOLE",
"delayTicks": 0,
"queueIfOffline": false,
"displayName": "Iron Pickaxe",
"description": "A sturdy pickaxe for your efforts"
}
]
}
]
}Quest Fields
Basic Fields
| Field | Type | Default | Description |
|---|---|---|---|
id | String | required | Unique quest identifier. Cannot contain | = : , characters |
displayName | String | id | Human-readable name shown in the UI and notifications |
description | String | "" | Quest description shown in the quest log |
category | String | "misc" | Category for grouping (e.g., main, daily, misc) |
enabled | Boolean | true | Whether the quest is active. Disabled quests are not indexed or offered |
sortOrder | Integer | 0 | Sort position within category (lower = first) |
Behavior Fields
| Field | Type | Default | Description |
|---|---|---|---|
autoAccept | Boolean | false | Automatically start the quest when a matching event fires (no manual accept needed) |
sequential | Boolean | false | Objectives must be completed in order (top to bottom) |
repeatable | Boolean | false | Quest can be completed multiple times |
cooldownSeconds | Long | 0 | Seconds before a repeatable quest can be accepted again (e.g., 86400 for daily) |
autoClaimRewards | Boolean | true | Rewards are given automatically on completion. If false, player must use /quest claim |
permission | String | null | Permission node required to accept the quest (e.g., mmoskilltree.quest.vip) |
Requirements
The requirements object gates who can accept the quest. All conditions must be met before the quest becomes available.
| Field | Type | Default | Description |
|---|---|---|---|
minLevel | Integer | 0 | Minimum total level across all skills |
minSkill | String | null | Skill name for the skill-level requirement (e.g., MINING) |
minSkillLevel | Integer | 0 | Minimum level in the specified skill |
The prerequisites array lists quest IDs that must be completed before this quest becomes available:
"prerequisites": ["mining_beginner", "combat_initiate"]Visibility
The optional visibility object controls whether a quest appears in the quest log. By default, all quests are visible. Hidden quests remain invisible until their conditions are met — but once a quest is started (active, completed, or on cooldown), it is always visible regardless of visibility settings.
| Field | Type | Default | Description |
|---|---|---|---|
hidden | Boolean | false | Master switch. When true, the quest is hidden until conditions below are met |
permission | String | null | Quest only visible to players with this permission |
requirePrerequisites | Boolean | false | Quest only visible after all prerequisite quests are completed |
requireLevel | Boolean | false | Quest only visible when the player meets the level/skill requirements |
When multiple conditions are set, all must pass for the quest to be visible. If hidden is true with no other conditions, the quest falls back to the standard acceptance check — it becomes visible when the player meets all requirements and prerequisites.
"visibility": {
"hidden": true,
"requirePrerequisites": true
}This is useful for quest chains where you don't want players to see future quests until they've completed the current step.
Objectives
Each quest has one or more objectives. When sequential is enabled, objectives must be completed in the order they are listed.
Objective Types
| Type | Triggered By | Target Example |
|---|---|---|
BREAK_BLOCK | Breaking a block | Stone, Ore_Iron |
PLACE_BLOCK | Placing a block | Plank |
CRAFT_ITEM | Crafting an item | Plank |
KILL_ENTITY | Killing an entity | Trork |
DEAL_DAMAGE | Dealing damage to an entity | Trork |
PICKUP_ITEM | Picking up an item | Coin |
REACH_LEVEL | Reaching a skill level | MINING (skill name) or TOTAL |
Objective Fields
| Field | Type | Default | Description |
|---|---|---|---|
id | String | required | Unique ID within the quest. Cannot contain | = : , characters |
type | String | required | One of the objective types above |
target | String | "" | What to match against (block ID, entity type, skill name, etc.) |
amount | Integer | 1 | How many times the objective must be triggered. For REACH_LEVEL, this is the required level |
displayText | String | auto-generated | Text shown to the player (e.g., "Mine 150 Stone blocks") |
matchMode | String | CONTAINS | How the target is matched against event identifiers |
Match Modes
| Mode | Behavior | Example |
|---|---|---|
CONTAINS | Target string appears anywhere in the identifier | "Stone" matches Stone, Cobblestone, Sandstone |
EXACT | Identifier must match the target exactly | "Stone" matches only Stone |
PREFIX | Identifier must start with the target | "Ore_" matches Ore_Iron, Ore_Gold |
Rewards
Quest rewards are commands executed when the quest is completed (or claimed, if autoClaimRewards is false). Each quest can have multiple rewards.
| Field | Type | Default | Description |
|---|---|---|---|
command | String | required | The command to execute |
runAs | String | CONSOLE | CONSOLE or PLAYER |
delayTicks | Integer | 0 | Delay in ticks before executing the command |
queueIfOffline | Boolean | false | If the player is offline, queue the reward for next login |
displayName | String | "" | Shown in the quest UI and completion notification |
description | String | "" | Additional description shown in the quest UI |
Command Placeholders
| Placeholder | Replaced With |
|---|---|
{player} | Player name |
{questId} | The quest ID |
Quest States
Each quest tracks a per-player state:
| State | Description |
|---|---|
NOT_STARTED | Quest has not been accepted |
ACTIVE | Quest is in progress, objectives being tracked |
COMPLETED_UNCLAIMED | All objectives done, rewards not yet claimed (autoClaimRewards: false) |
COMPLETED | Quest finished and rewards delivered |
ON_COOLDOWN | Repeatable quest waiting for cooldown to expire |
Flow: NOT_STARTED → ACTIVE → COMPLETED (auto-claim) or COMPLETED_UNCLAIMED → COMPLETED (manual claim). For repeatable quests, the cycle resets after the cooldown period.
Admin Commands
The /mmoquestadmin command requires OP or mmoskilltree.admin permission. Arguments are pipe-separated.
| Command | Description |
|---|---|
/mmoquestadmin reload | Reload all quest files from disk |
/mmoquestadmin list [category] | List all quests, optionally filtered by category |
/mmoquestadmin give --args=player|questId | Give a quest to a player (use * for all players) |
/mmoquestadmin reset --args=player|questId | Reset a quest for a player (use all to reset all quests) |
/mmoquestadmin complete --args=player|questId | Force-complete a quest and execute rewards (queues rewards if player is offline) |
/mmoquestadmin status --args=player[|questId] | View quest states and objective progress for a player |
Player Commands
The /quest command is available to all players.
| Command | Description |
|---|---|
/quest accept <questId> | Accept a quest (checks prerequisites, level requirements, and permissions) |
/quest claim <questId|all> | Claim rewards for completed quests (checks inventory space for /give rewards) |
/quest abandon <questId> | Abandon an active quest and reset its progress |
/quest status [questId] | View your active quests and objective progress |
Examples
Simple Gathering Quest
A beginner quest that auto-accepts and rewards an iron pickaxe:
{
"id": "mining_beginner",
"displayName": "Novice Miner",
"description": "Prove your mining skills by breaking some stone.",
"category": "main",
"sortOrder": 1,
"autoAccept": true,
"objectives": [
{
"id": "mine_stone",
"type": "BREAK_BLOCK",
"target": "Stone",
"amount": 150,
"displayText": "Mine 150 Stone blocks"
}
],
"rewards": [
{
"command": "/give {player} Tool_Pickaxe_Iron --quantity=1",
"displayName": "Iron Pickaxe",
"description": "A sturdy pickaxe for your efforts"
}
]
}Sequential Quest with Prerequisites
Requires the mining_beginner quest to be completed first and Mining level 5. Objectives must be completed in order:
{
"id": "mining_journeyman",
"displayName": "Journeyman Miner",
"description": "Advance your mining career with harder materials.",
"category": "main",
"sortOrder": 2,
"autoAccept": true,
"sequential": true,
"prerequisites": ["mining_beginner"],
"requirements": {
"minSkill": "MINING",
"minSkillLevel": 5
},
"objectives": [
{
"id": "mine_iron",
"type": "BREAK_BLOCK",
"target": "Ore_Iron",
"amount": 25,
"displayText": "Mine 25 Iron Ore"
},
{
"id": "reach_mining_10",
"type": "REACH_LEVEL",
"target": "MINING",
"amount": 10,
"displayText": "Reach Mining level 10"
}
],
"rewards": [
{
"command": "/give {player} XpToken_Unarmed_Shard --quantity=2",
"queueIfOffline": true,
"displayName": "Unarmed XP Shards x2"
}
]
}Repeatable Daily Quest
Repeatable every 24 hours (86400 seconds). Not auto-accepted — players must start it manually or via admin command:
{
"id": "daily_woodcutting",
"displayName": "Daily Lumber",
"description": "Chop some wood for daily rewards.",
"category": "daily",
"sortOrder": 100,
"autoAccept": false,
"repeatable": true,
"cooldownSeconds": 86400,
"objectives": [
{
"id": "chop_logs",
"type": "BREAK_BLOCK",
"target": "Wood",
"amount": 30,
"displayText": "Chop 30 logs"
}
],
"rewards": [
{
"command": "/give {player} XpToken_Woodcutting_Fragment --quantity=2",
"queueIfOffline": true,
"displayName": "2 Woodcutting XP Fragments",
"description": "Daily woodcutting payment"
}
]
}Hidden Quest Chain
This quest is invisible until the player completes mining_journeyman. The visibility object with requirePrerequisites: true prevents spoilers for future quest steps:
{
"id": "mining_expert",
"displayName": "Mining Expert",
"description": "Prove yourself as a true mining expert.",
"category": "main",
"sortOrder": 3,
"sequential": true,
"prerequisites": ["mining_journeyman"],
"requirements": {
"minSkill": "MINING",
"minSkillLevel": 15
},
"visibility": {
"hidden": true,
"requirePrerequisites": true
},
"objectives": [
{
"id": "mine_gold",
"type": "BREAK_BLOCK",
"target": "Ore_Gold",
"amount": 50,
"displayText": "Mine 50 Gold Ore"
},
{
"id": "reach_mining_20",
"type": "REACH_LEVEL",
"target": "MINING",
"amount": 20,
"displayText": "Reach Mining level 20"
}
],
"rewards": [
{
"command": "/give {player} XpToken_Mining_Token --quantity=3",
"queueIfOffline": true,
"displayName": "3 Mining XP Tokens",
"description": "A reward for the dedicated miner"
}
]
}Quest with Manual Claim
With autoClaimRewards: false, the quest enters the COMPLETED_UNCLAIMED state when objectives are done. Players must use /quest claim to receive rewards — useful when inventory space matters:
{
"id": "boss_bounty",
"displayName": "Boss Bounty",
"description": "Defeat a powerful boss. Return to claim your reward.",
"category": "main",
"sortOrder": 6,
"autoClaimRewards": false,
"objectives": [
{
"id": "slay_boss",
"type": "KILL_ENTITY",
"target": "Trork_Chieftain",
"amount": 1,
"displayText": "Defeat the Trork Chieftain",
"matchMode": "EXACT"
}
],
"rewards": [
{
"command": "/give {player} Diamond_Sword --quantity=1",
"queueIfOffline": true,
"displayName": "Diamond Sword",
"description": "A legendary blade for the champion"
}
]
}