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",
"tags": ["gathering", "beginner"],
"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": [
{
"type": "COMMAND",
"command": "/give {player} Tool_Pickaxe_Iron --quantity=1",
"displayName": "Iron Pickaxe",
"description": "A sturdy pickaxe for your efforts"
},
{
"type": "XP",
"skill": "MINING",
"amount": 200,
"displayName": "+200 Mining XP"
}
]
}
]
}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) |
tags | String[] | [] | Tags for filtering and organization (e.g., ["epic", "combat", "chapter-2"]) |
variables | Object | {} | Key-value metadata for custom data (e.g., { "difficulty": "hard", "region": "mountains" }) |
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) |
npcViewId | String | null | NPC identifier that surfaces this quest. When set, the quest is hidden from the quest log until accepted and only appears in the NPC quest UI |
npcDisplayName | String | null | Display name for the NPC shown in the NPC quest UI header |
npcRequiredToAccept | Boolean | false | When true, the quest can only be accepted through the NPC quest page, not from the quest log |
incompleteMarkdown | String | null | NPC dialogue shown before the quest is accepted. Supports # headers, **bold**, and *italic* |
activeMarkdown | String | null | NPC dialogue shown while the quest is in progress |
completeMarkdown | String | null | NPC dialogue shown when the quest is complete |
Requirements
The requirements field gates who can accept the quest. It accepts either a single object or an array of objects. All conditions must be met before the quest becomes available.
Single Object (one skill)
The simplest format — a single object with an optional total level gate and one skill requirement:
"requirements": {
"minLevel": 25,
"minSkill": "MINING",
"minSkillLevel": 15
}| 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 |
Array Format (multiple skills)
To require multiple skills, use an array of requirement objects. Each entry can specify a minLevel, a minSkill/minSkillLevel pair, or both. The highest minLevel across all entries is used as the total level gate, and every skill requirement must be met.
"requirements": [
{ "minLevel": 25 },
{ "minSkill": "MINING", "minSkillLevel": 15 },
{ "minSkill": "CRAFTING", "minSkillLevel": 20 }
]In this example, the player needs total level 25, Mining level 15, and Crafting level 20 to accept the quest. All skill requirements are displayed in the quest log's “Requires:” line.
Both formats are fully supported. Use the single object when you only need one skill gate, and the array when you need multiple.
Prerequisites
Prerequisites control which quests must be completed before this quest becomes available. There are two formats: a simple array (AND-all) and a structured object (AND/OR grouping).
Simple Format (AND)
A plain array of quest IDs — all must be completed:
"prerequisites": ["mining_beginner", "combat_initiate"]Branching Format (AND/OR)
For branching storylines, use an object with mode and nested groups. This lets you create quest paths where players can choose between different branches:
"prerequisites": {
"mode": "AND",
"quests": ["quest_intro"],
"groups": [
{
"mode": "OR",
"quests": ["quest_path_warrior", "quest_path_mage"]
}
]
}In this example, the player must complete quest_intro AND either quest_path_warrior OR quest_path_mage.
| Field | Type | Description |
|---|---|---|
mode | String | "AND" (all must pass) or "OR" (any one must pass) |
quests | String[] | Quest IDs evaluated directly with this group's mode |
permissions | String[] | Permission nodes evaluated with this group's mode. In AND mode all must be held; in OR mode any one suffices |
groups | Array | Nested prerequisite groups, each with their own mode, quests, permissions, and groups |
Groups can be nested to any depth. The simple array format is fully backward compatible and equivalent to { "mode": "AND", "quests": [...] }.
The quest UI displays branching prerequisites with "OR" labels so players can see which paths are available. Permission requirements display as "Permission: node.name".
Permission Prerequisites
Add a permissions array to any prerequisite group to require permission nodes alongside quest completions. Permissions and quests can be freely mixed in AND/OR logic:
"prerequisites": {
"mode": "AND",
"quests": ["first_blood"],
"permissions": ["rank.vip", "server.quest.unlock"]
}In this example, the player must have completed first_blood AND hold both rank.vip and server.quest.unlock permissions. In OR mode, completing any quest or holding any permission in the group would be enough.
Permissions work at any nesting level, so you can create complex gates like "complete quest_a AND (have rank.vip OR complete quest_b)".
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. Objective ordering can be controlled in two ways:
sequential: true— All objectives must be completed top-to-bottom (legacy behavior, still supported)- Per-objective
orderfield — Group objectives into stages for mixed sequential/parallel completion
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 |
CATCH_FISH | Catching a fish (via fishing mod or fish mob kill) | Salmon, Lobster, or "" (any fish) |
REACH_LEVEL | Reaching a skill level | MINING (skill name) or TOTAL |
TALK_TO_NPC | Interacting with an NPC (requires HyCitizens) | Citizen ID, or """" (any NPC) |
TURN_IN | Player clicks "Turn In" button in quest UI | Ore_Iron (item ID to remove from inventory) |
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 |
qualifier | String | none | Secondary filter that must also match for progress to count. Case-insensitive exact match when set. Omit or null to match any event. Use "" (empty string) to only match events with no qualifier. Primary use: elite mob tier (e.g., "Legendary") |
order | Integer | 0 | Ordering stage for mixed sequential/parallel objectives (see below) |
detailMarkdown | String | null | Per-objective NPC dialogue text shown in the NPC quest detail panel when this objective is the current active objective |
Objective Ordering
The order field lets you create quests with mixed sequential and parallel objectives. Objectives with the same order value can be completed in any order (parallel). Objectives with a higher order value are locked until all lower-order objectives are complete.
"objectives": [
{ "id": "gather_ore", "type": "BREAK_BLOCK", "target": "Ore_Iron", "amount": 10, "order": 1 },
{ "id": "craft_ingots", "type": "CRAFT_ITEM", "target": "Ingot_Iron", "amount": 5, "order": 1 },
{ "id": "kill_boss", "type": "KILL_ENTITY", "target": "Skeleton", "amount": 3, "order": 2 }
]In this example, the first two objectives (order 1) can be done in any order. The third objective (order 2) only becomes active after both order-1 objectives are complete. The quest UI groups objectives by stage and shows which are currently active.
order: 0or omitted — No ordering constraint (parallel with everything)- Using
sequential: trueauto-assigns incrementing order values for backward compatibility
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 |
Qualifier (Secondary Filter)
The qualifier field adds a secondary filter beyond target. When set, both the target and qualifier must match for progress to count. This is useful for filtering by elite mob tier, weapon type, or other event metadata.
{
"id": "kill_legendary_bears",
"type": "KILL_ENTITY",
"target": "Bear",
"qualifier": "Legendary",
"amount": 3,
"displayText": "Defeat 3 Legendary Bears"
}- Omitted or
null— matches any event (backward compatible) - Empty string
""— only matches events with no qualifier (e.g., normal mobs) - Any other value — case-insensitive exact match against the event qualifier
Currently, the elite mobs system provides the mob tier name (e.g., Legendary, Epic, Rare) as the qualifier for KILL_ENTITY and DEAL_DAMAGE objectives.
Rewards
Quest rewards are delivered when the quest is completed (or claimed, if autoClaimRewards is false). Each quest can have multiple rewards. Rewards support four types: commands, XP grants, boost tokens, and currency.
Reward Types
| Type | Description | Required Fields |
|---|---|---|
COMMAND | Execute a server command | command |
XP | Grant skill XP directly | skill, amount |
BOOST_TOKEN | Activate a timed XP multiplier boost | skill, multiplier, durationMinutes |
CURRENCY | Grant currency (gold) | amount |
If type is omitted, the reward defaults to COMMAND for backward compatibility. Existing command-based rewards continue to work unchanged.
Reward Examples
"rewards": [
{
"type": "COMMAND",
"command": "/give {player} Tool_Pickaxe_Iron --quantity=1",
"displayName": "Iron Pickaxe"
},
{
"type": "XP",
"skill": "MINING",
"amount": 500,
"displayName": "+500 Mining XP"
},
{
"type": "BOOST_TOKEN",
"skill": "ALL",
"multiplier": 2.0,
"durationMinutes": 30,
"displayName": "2x All XP (30m)"
},
{
"type": "CURRENCY",
"amount": 100,
"displayName": "100 Gold"
}
]Common Reward Fields
| Field | Type | Default | Description |
|---|---|---|---|
type | String | COMMAND | Reward type: COMMAND, XP, BOOST_TOKEN, or CURRENCY |
displayName | String | "" | Shown in the quest UI and completion notification |
description | String | "" | Additional description shown in the quest UI |
Command Reward Fields
| 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 |
Command Placeholders
| Placeholder | Replaced With |
|---|---|
{player} | Player name |
{questId} | The quest ID |
XP Reward Fields
| Field | Type | Description |
|---|---|---|
skill | String | Skill name (e.g., MINING, SWORDS, or a custom skill ID) |
amount | Integer | XP amount to grant |
Boost Token Reward Fields
| Field | Type | Description |
|---|---|---|
skill | String | Skill to boost (e.g., MINING) or ALL for all skills |
multiplier | Double | XP multiplier (e.g., 2.0 for double XP) |
durationMinutes | Integer | How long the boost lasts in minutes |
Currency Reward Fields
| Field | Type | Description |
|---|---|---|
amount | Integer | Currency amount to grant |
Tags & Variables
Quests can include tags for categorization and variables for custom metadata. Tags are displayed as chips below the quest description in the quest UI and are also used for filtering on the docs site Quest Gallery.
{
"id": "dragon_slayer",
"displayName": "Dragon Slayer",
"tags": ["epic", "combat", "chapter-2"],
"variables": {
"difficulty": "hard",
"region": "mountains"
}
}Variables are stored as key-value pairs and are available for future conditional logic and filtering on the docs site quest gallery.
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"
}
]
}Multi-Skill Requirements
This quest requires both Mining 30 and Crafting 20 before it can be accepted. The array format lets you gate quests behind any combination of skills:
{
"id": "master_smith",
"displayName": "Master Smith",
"description": "Only a skilled miner and crafter can forge the ultimate blade.",
"category": "main",
"sortOrder": 20,
"requirements": [
{ "minSkill": "MINING", "minSkillLevel": 30 },
{ "minSkill": "CRAFTING", "minSkillLevel": 20 }
],
"objectives": [
{
"id": "craft_blade",
"type": "CRAFT_ITEM",
"target": "Weapon_Longsword",
"amount": 1,
"displayText": "Craft a Longsword"
}
],
"rewards": [
{
"command": "/give {player} XpToken_Crafting_Token --quantity=2",
"queueIfOffline": true,
"displayName": "2 Crafting XP Tokens",
"description": "A reward for the master smith"
}
]
}Branching Prerequisites
A quest that requires completing an intro quest AND choosing one of two class paths. Players who completed either the warrior or mage path can continue to this quest:
{
"id": "chapter2_start",
"displayName": "Chapter 2: The Convergence",
"description": "Both paths lead here. Your journey continues.",
"category": "main",
"sortOrder": 10,
"tags": ["chapter-2", "epic"],
"prerequisites": {
"mode": "AND",
"quests": ["chapter1_intro"],
"groups": [
{
"mode": "OR",
"quests": ["path_warrior_complete", "path_mage_complete"]
}
]
},
"objectives": [
{
"id": "talk_elder",
"type": "KILL_ENTITY",
"target": "Elder_NPC",
"amount": 1,
"displayText": "Speak with the Elder"
}
],
"rewards": [
{
"type": "BOOST_TOKEN",
"skill": "ALL",
"multiplier": 2.0,
"durationMinutes": 60,
"displayName": "2x All XP (1hr)"
}
]
}Mixed Sequential/Parallel Objectives
Objectives with the same order value can be completed in any order. Higher order values unlock after lower ones are done:
{
"id": "forge_master",
"displayName": "Forge Master",
"description": "Gather materials, then forge the blade.",
"category": "main",
"sortOrder": 15,
"objectives": [
{
"id": "mine_ore",
"type": "BREAK_BLOCK",
"target": "Ore_Iron",
"amount": 20,
"displayText": "Mine 20 Iron Ore",
"order": 1
},
{
"id": "chop_wood",
"type": "BREAK_BLOCK",
"target": "Wood",
"amount": 10,
"displayText": "Gather 10 Wood",
"order": 1
},
{
"id": "craft_blade",
"type": "CRAFT_ITEM",
"target": "Weapon_Longsword_Iron",
"amount": 1,
"displayText": "Forge an Iron Longsword",
"order": 2
}
],
"rewards": [
{
"type": "XP",
"skill": "CRAFTING",
"amount": 1000,
"displayName": "+1000 Crafting XP"
},
{
"type": "CURRENCY",
"amount": 50,
"displayName": "50 Gold"
}
]
}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"
}
]
}NPC Quest with Turn In
Quests can be tied to NPCs using npcViewId. Players discover these quests through NPC interaction (opened via /mmoquestui). The TURN_IN objective type removes items from the player's inventory when they click the Turn In button. Partial turn-in is supported — players can submit what they have and return later with more.
Hyronix NPC Dialog Integration
To open the NPC quest UI when players interact with an NPC, add mmoquestui as a command in your Hyronix NPC Dialog configuration at mods/Hyronix_NPC Dialog/. Configure the NPC's dialog to run mmoquestui <player> <npc_id> so that interacting with the NPC opens the quest page for that player.
{
"id": "blacksmith_delivery",
"displayName": "The Blacksmith's Order",
"description": "Gorrath needs iron ore for his forge.",
"category": "main",
"npcViewId": "blacksmith_01",
"npcDisplayName": "Gorrath the Blacksmith",
"npcRequiredToAccept": true,
"incompleteMarkdown": "# The Blacksmith's Request\n\n**Gorrath** looks up from his anvil.\n\n\"I need iron ore. Can you help?\"",
"activeMarkdown": "\"Still gathering? I'll be here.\"",
"completeMarkdown": "\"Excellent work! These will do nicely.\"",
"objectives": [
{
"id": "deliver_iron",
"type": "TURN_IN",
"target": "Ore_Iron",
"amount": 10,
"displayText": "Deliver 10 Iron Ore",
"matchMode": "EXACT",
"detailMarkdown": "\"Bring me **10 Iron Ore** from the northern mines.\""
}
],
"rewards": [
{
"type": "XP",
"skill": "MINING",
"amount": 500,
"displayName": "500 Mining XP"
}
]
}