Quest System Documentation

Complete guide to SkyzerFusionCore quest system

System Overview

The SkyzerFusionCore quest system is a comprehensive progression framework featuring:

  • 9 Goal Types - Collect, Craft, Smelt, Break, Place, Kill, Walking, Explore Biome, Explore Dimension
  • 6 Reward Types - Money, XP, Items, Commands, Reward Tables
  • Automatic Progression - Goals tracked via Minecraft events
  • Dependency System - Complex quest unlock requirements
  • Chapter/Group Organization - Hierarchical quest structure
  • 7 Visual Shapes - Square, Circle, Diamond, Triangle, Gear, Star, Hexagon
Important: All quest data is stored in world/skyzerquest/ directory in JSON format.

Architecture

The quest system uses a centralized singleton manager (QuestManager) that handles:

  • Loading/saving quest data from JSON files
  • Tracking player quest progress
  • Auto-starting quests when dependencies are met
  • Processing goal completion events
  • Managing reward distribution
QuestManager (Singleton)
├── quests: Map<String, Quest>
├── chapters: Map<String, QuestChapter>
├── groups: Map<String, QuestGroup>
├── rewardTables: Map<String, RewardTable>
└── config: QuestConfig

File Structure

world/skyzerquest/
├── config.json                 # Global settings
├── shop.json                   # Shop system
├── groups/                     # Group definitions
│   └── *.json
├── chapters/                   # Chapter folders
│   └── chapter_id/
│       ├── chapter.json        # Chapter metadata
│       └── quests/
│           └── *.json          # Quest files
└── reward_tables/              # Loot tables
    └── *.json

Quest JSON Format

Complete quest file example:

{
  "id": "001_welcome",
  "title": "Welcome to the World",
  "description": "Complete your first objectives",

  "icon": {
    "item": "minecraft:log:1",         // Item with metadata (Spruce)
    "fallback_texture": "optional_path"
  },

  "shape": "square",
  "colors": {
    "background": "#667eea",
    "border": "#7dd3fc"
  },

  "position": {
    "x": 0,
    "y": 0
  },

  "chapter_id": "01_getting_started",

  "dependencies": [],
  "dependency_type": "all_required",

  "goals": [
    {
      "type": "break",
      "block": "minecraft:log",
      "amount": 16
    }
  ],

  "rewards": [
    {
      "type": "money",
      "amount": 100.0
    }
  ],

  "repeatable": false,
  "cooldown": 0,
  "hidden_until_unlocked": false
}

Quest Properties

Property Type Required Description
id String Yes Unique quest identifier
title String Yes Display name
description String Yes Quest text
icon Object No Item-based icon (see Icon Object)
shape String No square, circle, diamond, triangle, gear, star, hexagon
colors Object No background and border hex colors
position Object Yes Canvas coordinates {x, y}
chapter_id String Yes Parent chapter ID
dependencies Array No Quest IDs that must be completed first
dependency_type String No all_required or any (default: all_required)
goals Array Yes Quest objectives (see Goal Types)
rewards Array Yes Quest rewards (see Reward Types)
repeatable Boolean No Can be completed multiple times (default: false)
cooldown Number No Ticks between repeats (default: 0)
hidden_until_unlocked Boolean No Hide until dependencies met (default: false)

Dependencies

Quests can require other quests to be completed before they become available.

Dependency Types

  • all_required - ALL dependency quests must be completed
  • any - At least ONE dependency quest must be completed
// Require ALL quests to be completed
{
  "dependencies": ["quest_1", "quest_2", "quest_3"],
  "dependency_type": "all_required"
}

// Require ANY quest to be completed
{
  "dependencies": ["quest_a", "quest_b"],
  "dependency_type": "any"
}
Warning: Circular dependencies will prevent quests from being unlockable!

Goal Types

All goals in a quest must be completed (AND logic). Progress is tracked automatically.

Type Description Tracking Method
collect Gather items in inventory Inventory scan (every 20 ticks)
craft Craft specific items PlayerEvent.ItemCraftedEvent
smelt Smelt items in furnace PlayerEvent.ItemSmeltedEvent
break Break specific blocks BlockEvent.BreakEvent
place Place specific blocks BlockEvent.PlaceEvent
kill Kill entity types LivingDeathEvent
walking Walk distance in blocks PlayerTickEvent
explore_biome Visit specific biomes PlayerTickEvent (every 20 ticks)
explore_dimension Visit dimensions PlayerTickEvent (every 20 ticks)

Collect Goal

Requires player to have items in their inventory. Can optionally consume items. Supports metadata and NBT.

{
  "type": "collect",
  "item": "minecraft:diamond",
  "amount": 10,
  "consume": true,              // Optional: Remove items when collected
  "display_name": "Diamonds"    // Optional: Custom display name
}

// With metadata (for item variants)
{
  "type": "collect",
  "item": "minecraft:log:1",    // Spruce Wood specifically
  "amount": 16
}

// With NBT (for enchanted/special items)
{
  "type": "collect",
  "item": "minecraft:diamond_sword",
  "amount": 1,
  "nbt": "{Enchantments:[{id:\"sharpness\",lvl:5}]}"
}
If consume is true, items are removed from inventory when goal is met. Supports metadata for variants and NBT for enchanted/special items.

Craft Goal

Tracks items crafted by the player. Supports metadata for item variants and NBT for special items.

{
  "type": "craft",
  "item": "minecraft:crafting_table",
  "amount": 1
}

// With metadata
{
  "type": "craft",
  "item": "minecraft:planks:1",  // Spruce Planks specifically
  "amount": 32
}

// With NBT (enchanted books, special items)
{
  "type": "craft",
  "item": "minecraft:enchanted_book",
  "amount": 1,
  "nbt": "{StoredEnchantments:[{id:\"fortune\",lvl:3}]}"
}

Smelt Goal

Tracks items smelted by the player in a furnace. Supports metadata for item variants and NBT.

{
  "type": "smelt",
  "item": "minecraft:iron_ingot",
  "amount": 32
}

// With metadata
{
  "type": "smelt",
  "item": "minecraft:coal:1",     // Charcoal specifically
  "amount": 16
}
The item tracked is the output of the furnace, not the input.

Break Goal

Tracks blocks broken by the player. Supports metadata for block variants.

{
  "type": "break",
  "block": "minecraft:stone",
  "amount": 100
}

// With metadata for specific block variant
{
  "type": "break",
  "block": "minecraft:log:1",    // Spruce Wood specifically
  "amount": 64
}
Use block registry names (e.g., "minecraft:stone", "minecraft:log"). See Item Metadata for variants.

Place Goal

Tracks blocks placed by the player. Supports metadata for block variants.

{
  "type": "place",
  "block": "minecraft:torch",
  "amount": 50
}

// With metadata for specific block variant
{
  "type": "place",
  "block": "minecraft:wool:14",   // Red Wool specifically
  "amount": 20
}

Kill Goal

Tracks entities killed by the player.

{
  "type": "kill",
  "entity": "minecraft:zombie",
  "amount": 20
}
Use entity registry names (e.g., "minecraft:zombie", "minecraft:skeleton")

Walking Goal

Tracks total distance walked in blocks.

{
  "type": "walking",
  "distance": 1000
}

Explore Biome Goal

Requires player to visit a specific biome.

{
  "type": "explore_biome",
  "biome": "minecraft:forest"
}
Progress checked every 20 ticks (1 second). Use biome registry names.

Explore Dimension Goal

Requires player to visit a specific dimension.

{
  "type": "explore_dimension",
  "dimension": -1
}
Dimension ID Name
0Overworld
-1Nether
1The End

Reward Types

Rewards are given when the player claims the completed quest (not automatically).

Type Description
moneyCurrency reward
xpExperience points
xp_levelExperience levels
itemItems with optional NBT
commandExecute server command
reward_tableRandom reward from loot table

Money Reward

Give currency (fixed or random amount).

// Fixed amount
{
  "type": "money",
  "amount": 100.0
}

// Random range
{
  "type": "money",
  "min": 50.0,
  "max": 150.0
}

XP Reward

Give experience points or levels.

// Experience points
{
  "type": "xp",
  "amount": 500
}

// Experience levels (fixed)
{
  "type": "xp_level",
  "amount": 5
}

// Experience levels (random range)
{
  "type": "xp_level",
  "min": 1,
  "max": 3
}

Item Reward

Give items with optional metadata, custom name, and NBT data.

// Basic item
{
  "type": "item",
  "item": "minecraft:diamond",
  "amount": 5
}

// With metadata for item variants
{
  "type": "item",
  "item": "minecraft:log:1",     // Spruce Wood
  "amount": 32
}

// With custom name
{
  "type": "item",
  "item": "minecraft:apple",
  "amount": 1,
  "display_name": "Golden Apple of Destiny"
}

// With metadata and custom name
{
  "type": "item",
  "item": "minecraft:wool:14",   // Red Wool
  "amount": 10,
  "display_name": "Victory Banner Wool"
}

// With NBT (advanced)
{
  "type": "item",
  "item": "minecraft:diamond_sword",
  "amount": 1,
  "nbt": "{Enchantments:[{id:\"minecraft:sharpness\",lvl:5}]}"
}
See Item Metadata for details on item variants (wood types, wool colors, etc.)

Command Reward

Execute a server command. Use %player% as player name placeholder.

{
  "type": "command",
  "command": "say %player% completed the quest!"
}

{
  "type": "command",
  "command": "give %player% minecraft:diamond 10"
}
Warning: Commands execute with server permissions. Use with caution!

Reward Table

Reference a reward table for random rewards.

{
  "type": "reward_table",
  "table_id": "common_loot",
  "rolls": 1                    // Number of times to draw from table
}

Chapters

Chapters group related quests together in the UI. Icons support metadata for item variants.

{
  "id": "01_getting_started",
  "name": "Getting Started",
  "description": "Learn the basics",

  "icon": {
    "item": "minecraft:book"          // or "minecraft:wool:14" for variants
  },

  "parent_group": "main_quest_line",
  "order": 1,

  "unlocked_by_default": true,

  "unlock_requirements": {
    "required_quests": [],
    "required_chapters": []
  }
}

Groups

Groups provide hierarchical folder structure for organizing chapters.

{
  "id": "main_quest_line",
  "name": "Main Quest Line",
  "description": "Primary progression",

  "icon": "📖",
  "parent_group": null,
  "order": 0,

  "collapsed_by_default": false,

  "children": [
    {
      "type": "chapter",
      "id": "01_getting_started"
    },
    {
      "type": "group",
      "id": "side_quests"
    }
  ]
}

Reward Tables

Define weighted random loot pools. Entries support metadata for item variants.

{
  "id": "common_loot",
  "name": "Common Loot",
  "description": "Basic reward pool",

  "entries": [
    {
      "item": "minecraft:diamond",
      "amount": 1,
      "weight": 10          // 10% chance (10/60 total weight)
    },
    {
      "item": "minecraft:emerald",
      "amount": 2,
      "weight": 20          // 20/60 = 33%
    },
    {
      "item": "minecraft:gold_ingot",
      "amount": 5,
      "weight": 30          // 30/60 = 50%
    }
  ]
}

// With metadata for item variants
{
  "id": "wood_loot",
  "name": "Wood Variety Pack",
  "entries": [
    {
      "item": "minecraft:log:0",    // Oak
      "amount": 16,
      "weight": 25
    },
    {
      "item": "minecraft:log:1",    // Spruce
      "amount": 16,
      "weight": 25
    },
    {
      "item": "minecraft:log2:0",   // Acacia
      "amount": 16,
      "weight": 25
    },
    {
      "item": "minecraft:log2:1",   // Dark Oak
      "amount": 16,
      "weight": 25
    }
  ]
}
Higher weight = higher chance of selection. Total weight is sum of all entry weights. See Item Metadata for variant support.

Web API Overview

SkyzerFusionCore provides a RESTful web API for accessing quest and shop data from external applications.

Base URL

http://localhost:8080/api

Authentication

All API endpoints require Bearer token authentication:

Authorization: Bearer YOUR_TOKEN_HERE
Tokens are managed via in-game commands. Each player has a unique token.

Available Endpoints

Endpoint Method Description
/api/shop/categoriesGETGet all shop categories with items
/api/shop/itemsGETGet all shop items
/api/questsGETGet all quests
/api/quests/:idGETGet specific quest details
/api/player/inventoryGETGet player inventory
/api/items/icon/:itemGETGet item icon (PNG)

Shop API

GET /api/shop/categories

Returns all shop categories with their items.

Response Format:

{
  "categories": [
    {
      "id": "blocks",
      "name": "Blocs de Construction",
      "icon": "minecraft:stone",
      "icon_meta": 0,              // Metadata for icon
      "display_order": 0,
      "items": [
        {
          "id": "minecraft:log:1",   // Auto-generated ID
          "item": "minecraft:log",   // Registry name
          "meta": 1,                 // Metadata (0 for Oak, 1 for Spruce, etc.)
          "display_name": "Spruce Wood",  // Localized client name
          "buy_price": 1.0,
          "sell_price": 0.5,
          "stock": -1                // -1 = unlimited
        }
      ]
    }
  ],
  "total": 5
}

GET /api/shop/items

Returns all shop items across all categories.

Response Format:

{
  "items": [
    {
      "id": "minecraft:log:1",
      "item": "minecraft:log",
      "meta": 1,
      "display_name": "Spruce Wood",
      "buy_price": 1.0,
      "sell_price": 0.5,
      "stock": -1,
      "category": "Blocs de Construction",
      "category_id": "blocks"
    }
  ],
  "total": 25
}
display_name is the localized name from the client's language. Use this for display instead of the item ID.

Quest API

GET /api/quests

Returns all quests with player progress.

Goals include localized_name:

{
  "goals": [
    {
      "type": "collect",
      "item": "minecraft:log",
      "meta": 1,
      "amount": 16,
      "consume": true,
      "localized_name": "Spruce Wood"  // Client localized name
    },
    {
      "type": "break",
      "block": "minecraft:stone",
      "meta": 0,
      "amount": 100,
      "localized_name": "Stone"
    }
  ]
}

Rewards include localized_name:

{
  "rewards": [
    {
      "type": "item",
      "item": "minecraft:diamond",
      "meta": 0,
      "amount": 5,
      "localized_name": "Diamond"  // Client localized name
    },
    {
      "type": "money",
      "amount": 100.0
    }
  ]
}
Format recommendation: Display as "modid:id:meta (LocalizedName)"
Example: minecraft:log:1 (Spruce Wood)

Item Icons API

GET /api/items/icon/:item

Returns a 32x32 PNG icon of the item, rendered exactly like in-game.

Parameters:

Parameter Type Required Description
item Path Yes Item registry name (e.g., "minecraft:log")
meta Query No Metadata value (0-15, default: 0)
nbt Query No NBT data (URL-encoded JSON format)

Examples:

// Oak Wood (default metadata 0)
GET /api/items/icon/minecraft:log

// Spruce Wood (metadata 1)
GET /api/items/icon/minecraft:log?meta=1

// Red Wool (metadata 14)
GET /api/items/icon/minecraft:wool?meta=14

// Diamond (no metadata needed)
GET /api/items/icon/minecraft:diamond

// Enchanted Diamond Sword (with NBT)
GET /api/items/icon/minecraft:diamond_sword?nbt=%7BEnchantments%3A%5B...%5D%7D

// AE2 Facade (NBT-based item)
GET /api/items/icon/appliedenergistics2:facade?nbt=%7Bitem%3A...%7D
NBT Support: Items with NBT data (enchantments, custom names, AE2 facades, etc.) will render correctly with their NBT applied. The display name also respects NBT (enchantments, renamed items).

Response:

  • Content-Type: image/png
  • Size: 32x32 pixels
  • Cache: 24 hours (max-age=86400)

JavaScript Usage:

// Helper function with NBT support
function getIconUrl(itemId, metadata, nbt) {
    const cleanId = itemId.replace('minecraft:', '');
    const params = [];

    if (metadata !== undefined && metadata !== 0) {
        params.push(`meta=${metadata}`);
    }

    if (nbt && nbt !== 'null' && nbt !== null) {
        params.push(`nbt=${encodeURIComponent(nbt)}`);
    }

    const queryString = params.length > 0 ? '?' + params.join('&') : '';
    return `/api/items/icon/${cleanId}${queryString}`;
}

// Usage examples
const iconUrl1 = getIconUrl('minecraft:log', 1);
// Returns: /api/items/icon/log?meta=1

const iconUrl2 = getIconUrl('minecraft:diamond_sword', 0, '{Enchantments:[...]}');
// Returns: /api/items/icon/diamond_sword?nbt=%7BEnchantments%3A%5B...%5D%7D

Item Metadata

Minecraft 1.12.2 uses metadata (also called damage values) to distinguish item and block variants.

What is Metadata?

Metadata is a number (0-15 typically) that represents different variants of the same item or block:

  • minecraft:log:0 - Oak Wood
  • minecraft:log:1 - Spruce Wood
  • minecraft:log:2 - Birch Wood
  • minecraft:log:3 - Jungle Wood

Supported Formats

The quest system supports three metadata formats in JSON files:

// 1. Colon-separated format (recommended)
{
  "item": "minecraft:log:1",        // Spruce Wood
  "amount": 10
}

// 2. Separate "meta" field
{
  "item": "minecraft:log",
  "meta": 1,                        // Spruce Wood
  "amount": 10
}

// 3. Separate "metadata" field
{
  "item": "minecraft:log",
  "metadata": 1,                    // Spruce Wood
  "amount": 10
}
All three formats work identically. Use whichever you find most readable.

Where Metadata is Supported

Feature Supports Metadata Example
Quest Icons ✅ Yes "icon": {"item": "minecraft:log:1"}
Chapter Icons ✅ Yes "icon": {"item": "minecraft:wool:14"}
Collect Goals ✅ Yes "item": "minecraft:log:1"
Craft Goals ✅ Yes "item": "minecraft:planks:1"
Break Goals ✅ Yes "block": "minecraft:log:1"
Place Goals ✅ Yes "block": "minecraft:planks:1"
Item Rewards ✅ Yes "item": "minecraft:log:1"
Reward Tables ✅ Yes "item": "minecraft:log:1"
Shop Items ✅ Yes "item": "minecraft:log:1"
Shop Category Icons ✅ Yes "icon": "minecraft:wool:14"

Common Examples

// Wool colors (minecraft:wool)
"minecraft:wool:0"   // White
"minecraft:wool:1"   // Orange
"minecraft:wool:14"  // Red
"minecraft:wool:11"  // Blue

// Wood types (minecraft:log)
"minecraft:log:0"    // Oak
"minecraft:log:1"    // Spruce
"minecraft:log:2"    // Birch
"minecraft:log:3"    // Jungle

// Wood types (minecraft:log2)
"minecraft:log2:0"   // Acacia
"minecraft:log2:1"   // Dark Oak

// Stone variants (minecraft:stone)
"minecraft:stone:0"  // Stone
"minecraft:stone:1"  // Granite
"minecraft:stone:2"  // Polished Granite
"minecraft:stone:3"  // Diorite
"minecraft:stone:4"  // Polished Diorite
"minecraft:stone:5"  // Andesite
"minecraft:stone:6"  // Polished Andesite

// Planks (minecraft:planks)
"minecraft:planks:0" // Oak
"minecraft:planks:1" // Spruce
"minecraft:planks:2" // Birch
"minecraft:planks:3" // Jungle
"minecraft:planks:4" // Acacia
"minecraft:planks:5" // Dark Oak
Important: Without metadata, goals and rewards will use the default variant (meta 0). Always specify metadata for non-default variants!

Web API Metadata

Item icons in the web interface support metadata via query parameter:

// Get Spruce Wood icon
GET /api/items/icon/minecraft:log?meta=1

// Get Red Wool icon
GET /api/items/icon/minecraft:wool?meta=14

Inventory Display

Player inventory API includes metadata for each item:

// Inventory response includes "meta" field
{
  "slot": 0,
  "item": "minecraft:log",
  "meta": 1,                    // Spruce variant
  "count": 64,
  "displayName": "Spruce Wood"
}

Item NBT

NBT (Named Binary Tag) is Minecraft's data format for storing complex item information like enchantments, custom names, and mod-specific data.

What is NBT?

NBT allows items to have rich, complex data beyond just metadata. Common uses include:

  • Enchantments - Sharpness V, Fortune III, etc.
  • Custom Names - Renamed items via anvil
  • Lore Text - Custom item descriptions
  • Mod Data - AE2 facades, custom tools, etc.
  • Potion Effects - Custom potion data
  • Books - Written book content, enchanted books

NBT Format

NBT is written in JSON-like syntax as a string:

{Enchantments:[{id:"minecraft:sharpness",lvl:5}]}
Important: NBT strings must be valid Minecraft NBT format. Invalid NBT will be ignored.

Where NBT is Supported

Feature Supports NBT Example
Quest Icons ✅ Yes "icon": {"item": "minecraft:diamond_sword", "nbt": "{...}"}
Collect Goals ✅ Yes "nbt": "{Enchantments:[...]}"
Craft Goals ✅ Yes "nbt": "{StoredEnchantments:[...]}"
Item Rewards ✅ Yes "nbt": "{display:{Name:\"...\"}}"
Reward Tables ✅ Yes "nbt": "{...}"
Shop Items ✅ Yes "nbt": "{...}"
Item Icons API ✅ Yes /api/items/icon/diamond_sword?nbt=...
Break Goals ❌ No Blocks don't use NBT (use metadata)
Place Goals ❌ No Blocks don't use NBT (use metadata)

Common Examples

Enchanted Items

// Sharpness V Diamond Sword
{
  "type": "collect",
  "item": "minecraft:diamond_sword",
  "amount": 1,
  "nbt": "{Enchantments:[{id:\"minecraft:sharpness\",lvl:5}]}"
}

// Fortune III Diamond Pickaxe
{
  "type": "item",
  "item": "minecraft:diamond_pickaxe",
  "amount": 1,
  "nbt": "{Enchantments:[{id:\"minecraft:fortune\",lvl:3}]}"
}

// Multiple enchantments
{
  "type": "item",
  "item": "minecraft:diamond_sword",
  "amount": 1,
  "nbt": "{Enchantments:[{id:\"minecraft:sharpness\",lvl:5},{id:\"minecraft:looting\",lvl:3}]}"
}

Enchanted Books

// Fortune III Book
{
  "type": "craft",
  "item": "minecraft:enchanted_book",
  "amount": 1,
  "nbt": "{StoredEnchantments:[{id:\"minecraft:fortune\",lvl:3}]}"
}

// Mending Book
{
  "type": "item",
  "item": "minecraft:enchanted_book",
  "amount": 1,
  "nbt": "{StoredEnchantments:[{id:\"minecraft:mending\",lvl:1}]}"
}

Custom Named Items

// Renamed item
{
  "type": "item",
  "item": "minecraft:diamond_sword",
  "amount": 1,
  "nbt": "{display:{Name:\"Legendary Blade\"}}"
}

// With lore text
{
  "type": "item",
  "item": "minecraft:diamond",
  "amount": 1,
  "nbt": "{display:{Name:\"Perfect Diamond\",Lore:[\"Flawless clarity\",\"Priceless gem\"]}}"
}

Potions

// Speed II Potion (extended)
{
  "type": "item",
  "item": "minecraft:potion",
  "amount": 1,
  "nbt": "{Potion:\"minecraft:long_swiftness\"}"
}

// Custom potion effects
{
  "type": "item",
  "item": "minecraft:potion",
  "amount": 1,
  "nbt": "{CustomPotionEffects:[{Id:1,Amplifier:1,Duration:6000}]}"
}

Applied Energistics 2 (AE2) Items

// AE2 Facade (Oak Planks)
{
  "type": "item",
  "item": "appliedenergistics2:facade",
  "amount": 1,
  "nbt": "{item:\"minecraft:planks\",meta:0}"
}

// Quest icon with AE2 facade
{
  "icon": {
    "item": "appliedenergistics2:facade",
    "nbt": "{item:\"minecraft:stone\",meta:0}"
  }
}

Written Books

// Written book with content
{
  "type": "item",
  "item": "minecraft:written_book",
  "amount": 1,
  "nbt": "{title:\"Quest Guide\",author:\"Skyzer\",pages:[\"Page 1 text\",\"Page 2 text\"]}"
}

NBT with Metadata

Items can have both metadata AND NBT:

// Enchanted Spruce Logs (metadata + NBT)
{
  "type": "item",
  "item": "minecraft:log:1",      // Spruce variant (metadata 1)
  "amount": 16,
  "nbt": "{display:{Name:\"Magical Spruce\"}}"
}

Web API with NBT

The item icons API supports NBT via URL-encoded query parameter:

// Get icon of Sharpness V Diamond Sword
GET /api/items/icon/minecraft:diamond_sword?nbt=%7BEnchantments%3A%5B%7Bid%3A%22sharpness%22%2Clvl%3A5%7D%5D%7D

// JavaScript helper automatically encodes NBT
function getIconUrl(itemId, metadata, nbt) {
    const params = [];
    if (metadata !== 0) params.push(`meta=${metadata}`);
    if (nbt) params.push(`nbt=${encodeURIComponent(nbt)}`);
    const queryString = params.length > 0 ? '?' + params.join('&') : '';
    return `/api/items/icon/${itemId}${queryString}`;
}

// Usage
const iconUrl = getIconUrl(
    'minecraft:diamond_sword',
    0,
    '{Enchantments:[{id:"sharpness",lvl:5}]}'
);

Getting NBT from Game

To get NBT data from items in-game:

// Hold the item and run command:
/nbt get

// Or use F3+H to enable advanced tooltips
// Then hover over the item to see NBT data
Tip: You can copy NBT from existing items using /data get entity @p SelectedItem in Minecraft 1.13+, or use NBT editors for 1.12.2.

Localized Names with NBT

Items with NBT automatically get their display name from the NBT data if present:

  • Enchanted items show enchantment glint
  • Renamed items show custom name (not "Diamond Sword")
  • Potion names reflect their effects
  • Books show their title
// Goal with renamed item
{
  "type": "collect",
  "item": "minecraft:diamond_sword",
  "nbt": "{display:{Name:\"Legendary Blade\"}}",
  "amount": 1
}

// API response includes localized_name:
{
  "type": "collect",
  "item": "minecraft:diamond_sword",
  "nbt": "{display:{Name:\"Legendary Blade\"}}",
  "amount": 1,
  "localized_name": "Legendary Blade"  // From NBT, not default name
}

NBT Validation

Invalid NBT is silently ignored. Common mistakes:

  • ❌ Missing quotes: {id:sharpness,lvl:5}
  • ✅ Correct: {id:"sharpness",lvl:5}
  • ❌ Wrong brackets: (Enchantments:...)
  • ✅ Correct: {Enchantments:[...]}
  • ❌ Invalid namespace: {id:"sharp",lvl:5}
  • ✅ Correct: {id:"minecraft:sharpness",lvl:5}
Debug: If NBT doesn't work, check server logs for NBT parsing errors. The system will log warnings for invalid NBT data.

Performance Note

NBT matching is more expensive than metadata matching. For performance:

  • Use metadata when possible (wood types, wool colors)
  • Use NBT only when necessary (enchantments, special items)
  • Avoid complex nested NBT structures in goals

Progression System

Quest Lifecycle

  1. Locked - Dependencies not met
  2. Available - Can be started (auto-started on login)
  3. Active - Player is working on goals
  4. Completed - All goals finished
  5. Claimed - Rewards received

Auto-Start Behavior

When a player logs in, all quests with met dependencies are automatically started. This happens via:

QuestManager.autoStartAvailableQuests(player)

Progress Tracking

Player quest data is stored in SQLite database:

  • skyzerCompletedQuests - Set of completed quest IDs
  • skyzerActiveQuests - Map of QuestProgress objects
  • skyzerClaimedRewards - Set of claimed quest IDs

Java API

Quest Manager

QuestManager manager = QuestManager.getInstance();

// Get quest
Quest quest = manager.getQuest("quest_id");

// Start quest
manager.startQuest(player, "quest_id");

// Check if player can start
boolean canStart = manager.canStartQuest(player, quest);

// Update progress
manager.updateQuestProgress(player, "quest_id");

// Complete quest
manager.completeQuest(player, "quest_id");

// Claim rewards
manager.claimRewards(player, "quest_id");

Player Data

PlayerData data = DatabaseManager.getInstance().getPlayerData(playerUUID);

// Check completion
boolean completed = data.getSkyzerCompletedQuests().contains("quest_id");

// Get active progress
QuestProgress progress = data.getSkyzerActiveQuests().get("quest_id");

// Check goals
for (GoalProgress goal : progress.getGoalsProgress()) {
    int current = goal.getCurrent();
    int required = goal.getRequired();
    boolean done = goal.isCompleted();
}

Creating Custom Goals

public class QuestGoalCustom implements IQuestGoal {

    @Override
    public String getType() {
        return "custom";
    }

    @Override
    public int getRequiredProgress() {
        return 100;
    }

    @Override
    public int updateProgress(EntityPlayer player, int current, Object... context) {
        // Your custom logic here
        return current + 1;
    }

    @Override
    public boolean isCompleted(EntityPlayer player, int current) {
        return current >= getRequiredProgress();
    }

    // ... other interface methods
}

Event Handling

Quest progress is updated automatically via QuestEventHandler:

@SubscribeEvent
public void onBlockBreak(BlockEvent.BreakEvent event) {
    if (event.getPlayer() instanceof EntityPlayerMP) {
        EntityPlayerMP player = (EntityPlayerMP) event.getPlayer();
        // Update all active quests with break goals
        updateAllQuestsForPlayer(player, QuestGoalBreak.class, event.getState().getBlock());
    }
}

Supported Events

  • BlockEvent.BreakEvent - Break goals
  • BlockEvent.PlaceEvent - Place goals
  • LivingDeathEvent - Kill goals
  • PlayerEvent.ItemCraftedEvent - Craft goals
  • TickEvent.PlayerTickEvent - Walking, biome, dimension goals