v1.1.19  ·  Minecraft 1.21.11  ·  Fabric  ·  Java 21

AshenFall Mod

A D&D-themed Fabric mod — land ownership, coins, quests, mines, hazards and more.

⬇ Download mod v1.1.19

Installation

Requirements: Minecraft 1.21.11, Fabric Loader, Java 21. No extra mods are required — all dependencies are bundled in the JAR.
1
Download the mod JAR
Click the download button above. The file will be named ashenfall-1.1.19-client.jar.
2
Find your CurseForge mods folder
In the CurseForge app, find the modpack you use for this server. Click the (three-dot) menu in the modpack header and choose Open Folder, then open the mods subfolder.
3
Remove any old version
Delete any existing m8jmodstk10va-*.jar file from that folder before copying in the new one.
4
Copy the new JAR in
Move ashenfall-1.1.19-client.jar from your Downloads folder into the mods folder.
5
Restart Minecraft
Close any running Minecraft instance and launch it again from CurseForge.
6
(Optional) Better visuals
Install the Iris Shaders mod and a compatible shader pack for the best look.

Player Commands

Available to all players.

💰 Coins — /coins

CommandDescription
/coins balanceCheck your current coin balance.
/coins pay <player> <amount>Send coins to another player.
/coins drop <amount|all>Drop coins on the ground as a collectible pile.

🏡 Land — /land

CommandDescription
/land hereShow the name and type of the land section you're standing in.
/land buy <section>Purchase a land section that is listed for sale.
/land sell <section> <player> <price>Offer ownership of your land to another player for a set price.
/land acceptAccept a pending land sale offer directed at you.
/land declineDecline a pending land sale offer.

Adventure-mode interaction rule. While in adventure mode you can only use anvils, doors, and trapdoors inside land you personally own. Everywhere else — including dungeons, settlements, and unclaimed wilderness — those blocks are locked. The rule applies to everyone in adventure mode, ops included; only players in creative mode are unaffected. (Containers follow a similar rule; decorated pots are always read-only in adventure mode.)

⭐ XP & Level — HUD

A server-specific XP and level system, completely separate from Minecraft's enchanting XP.

🌟 Reputation — /reputation

CommandDescription
/reputation meShow your reputation with every NPC and settlement you've interacted with, plus your current tier in each.

Tiers (per NPC and per settlement): Stranger (≥ 0) · Acquainted (≥ 100) · Trusted (≥ 300) · Honored (≥ 600) · Revered (≥ 1000).

Adventure-mode rule. Reputation and XP rewards only apply while you are in adventure mode. Hitting or killing villagers / iron golems / animals inside a settlement costs you settlement reputation (player-tamed pets are exempt). Reputation can go negative; the floor is -1000. Coin rewards are unaffected by game mode.

🪙 Merchants & Shops

Some NPCs are merchants. Talk to one and pick the "Show me your wares" (or similar) option to open their shop. The shop has two tabs:

Some items only unlock once you've earned enough reputation with the merchant or their settlement — locked items appear greyed out until you qualify. There's no command; shops are always reached by talking to the NPC, and the screen closes if you walk away.

Some merchants also sell mounts (shown with a saddle icon). Buying one adds it to your collection of owned mounts rather than to your bag — you can only own one of each, and an already-owned mount shows as "Already owned". If a merchant offers a buy-back price you can sell a mount you own on the Sell tab.

Manage your mounts from the parchment on the right side of your inventory: it lists every mount you own (scroll if the list is long). Click one to make it your active mount (the active one is marked ◆; click it again to deactivate). Press the Recall Mount key (default R, rebindable under Options → Controls → Gameplay) anywhere to summon your active mount to your side — recalling always destroys any previously-summoned copy, so there's only ever one of your mount in the world. Your mount is yours alone: other players can't ride or harm it, and it vanishes when you log out (recall it again next time).

Admin Commands Requires op (level 4)

All admin commands require the executor to be in Creative mode.

🏡 Land — /land

CommandDescription
/land select Gives you a land selection stick. Right-click a block to set corner 1, Left-click to set corner 2.
/land create <name> <type> Create a rectangular land section from the two selected corners.
Types: landmark settlement dungeon house quest_area mine territory
/land fill <name> <type> Create a section by flood-filling from your position through passable blocks (air, fluids, doors, trapdoors, iron bars, copper grates, spider webs — cap 2 000 000 blocks). Useful for irregular rooms and caves.
Footprint: the section's footprint is the exact set of 3D cells visited by the flood-fill plus a one-block expansion in all six directions (so the immediate floor, ceiling, and wall blocks are claimed for adventure-mode protection). Non-convex shapes don't bulge outward to claim adjacent open terrain, and walking on top of any ceiling — even a low side tunnel inside a larger dungeon — falls outside the section.
Visualiser: the filled area is temporarily marked with ochre frog-light blocks for 2 minutes, then automatically restored (even after a server restart). On success the interior is highlighted so you can verify the captured area. On overflow (not fully enclosed) up to 100k frontier positions are marked showing the leak; fly in spectator mode to locate the gap.
/land transfer <section> <player> Transfer full ownership of a section to another player, immediately removing all previous owners. All affected players are notified.
/land set <section> purchasable <true|false> Mark a section as available (or unavailable) for player purchase.
/land set <section> price <amount> Set the coin price for purchasing a section.
/land delete <section> Permanently delete a land section.
/land info <section> Display full details: ID, world, footprint (polygon vertices, or XZ column count for fill-created sections), Y-range, price, owners, parent section.
/land list List all defined land sections.
/land shimmer on [section]
/land shimmer off [section]
Toggle the translucent boundary glow on all sections or a specific one. Useful when setting up land areas.

💰 Coins — /coins

CommandDescription
/coins balance <player>Check another player's balance.
/coins give <player> <amount>Add coins to a player's balance.
/coins take <player> <amount>Remove coins from a player's balance.
/coins add <amount> [delaySeconds]Spawn a coin pile entity at your position. If delaySeconds is given, the pile respawns automatically after that many seconds.
/coins add random <min> <max> [delaySeconds]Spawn a coin pile with a random amount rolled from the inclusive [min, max] range. Values above the pile cap (40) are clamped silently. The rolled amount is not revealed, and a fresh value is rolled on every respawn.
/coins removeRemove the respawn timer from the respawning coin pile you are looking at.

⚔️ Dungeon Zones — /dungeon zone

All subcommands require op level 4 (or the tk10va.dungeon.admin permission) and Creative mode.

CommandDescription
/dungeon zone add <name> <radius> Create a proximity-triggered spawn zone at your current position. The dungeon is inferred from where you stand. name must be unique within the dungeon. radius is the Euclidean trigger distance in blocks.
/dungeon zone addmob <zone-name> <entity-type> [count] Add a mob spawn entry to a zone in the dungeon you are standing in. Zone names and entity types have tab-completion. The mob spawns at your current position. count defaults to 1.
/dungeon zone list List all zones for the dungeon you are standing in, showing each zone's name, trigger position, radius, and number of mob entries.
/dungeon zone list <dungeon> List all zones for an explicitly named dungeon section (tab-completable).
/dungeon zone remove <zone-name> Permanently delete a zone from the dungeon you are standing in. Zone names are tab-completable.
/dungeon zone remove in <dungeon> <zone-name> Permanently delete a zone from an explicitly chosen dungeon. Both dungeon and zone name are tab-completable.
/dungeon zone test <zone-name> Instantly spawn all mobs for a zone in the current dungeon without triggering its activation flag — useful for testing placement in creative mode.

💰 Dungeon Coins — /dungeon coins

Register persistent coin piles inside a dungeon. Each pile respawns automatically 5 seconds after the dungeon resets (when all players leave or die).

CommandDescription
/dungeon coins add <amount> Register a coin pile at your current position in the dungeon you are standing in. The pile spawns immediately and will respawn after every dungeon reset. amount is the number of coins in the pile.
/dungeon coins add random <min> <max> Register a coin pile that rolls a fresh random amount from the inclusive [min, max] range on every spawn — including after each dungeon reset. Players raiding the same dungeon repeatedly see a different payout each run.
/dungeon coins list List all registered coin piles for the dungeon you are standing in, showing each pile's ID, coordinates, and coin amount (or the random range for ranged piles).
/dungeon coins list <dungeon> List all registered coin piles for an explicitly named dungeon (tab-completable).
/dungeon coins remove Remove the coin pile registration nearest to your position (within the current dungeon). The live entity is also removed immediately.

🧩 Dungeon Puzzles — /dungeon puzzle

Define interactive puzzle areas inside a dungeon. When all targets are activated the reward chest behind the iron bars becomes accessible and a custom message is displayed on-screen in purple to every player in the dungeon. Long messages wrap automatically — all lines appear simultaneously with a fade-in/stay/fade-out animation. Bars and block states are automatically restored when the dungeon resets.

Puzzle types: CANDLES — light every candle in the area  |  LEVERS — flip every lever to ON  |  HEADS — right-click every custom head block in the area

Setup workflow
  1. Stand inside the dungeon section.
  2. Look at one corner of the puzzle room and run /dungeon puzzle pos1.
  3. Look at the opposite corner and run /dungeon puzzle pos2.
  4. Run /dungeon puzzle area define <id> <type> <message> to create the area.
  5. Look at each iron-bar block in front of the reward chest and run /dungeon puzzle bar add <id>.
CommandDescription
/dungeon puzzle pos1 Mark the first bounding-box corner of the puzzle area (the block you are looking at).
/dungeon puzzle pos2 Mark the second bounding-box corner.
/dungeon puzzle area define <id> <type> <message> Create a puzzle area from the two selected corners in the dungeon you are standing in.
id — unique name (e.g. puzzle1).
typeCANDLES, LEVERS, or HEADS.
message — completion text shown to all players in purple. Can be long — text wraps automatically and all lines display at once.
/dungeon puzzle area remove <id> Permanently delete a puzzle area definition.
/dungeon puzzle area list List all puzzle areas defined in the dungeon you are standing in.
/dungeon puzzle bar add <id> Register the block you are looking at as an iron-bar position for the puzzle. Repeat for each bar block.
/dungeon puzzle bar remove <id> Remove the bar position nearest to your current location from the puzzle's list.
/dungeon puzzle solved <id> Manually mark a puzzle as solved — removes bars and triggers the completion message. Safe to call from a command block.
/dungeon puzzle reset <id> Reset a single puzzle mid-run: restores bars and clears progress for that puzzle only.

🎁 Dungeon Chests — /dungeon chest

Register reward chests inside a dungeon with a vanilla loot table. On every dungeon reset each registered chest is cleared and its loot table is re-seeded so the next player to open it gets fresh randomised contents.

CommandDescription
/dungeon chest add <loot-table> Register the chest you are looking at in the current dungeon with the given loot table resource location (e.g. minecraft:chests/simple_dungeon or a custom datapack table). The chest is cleared and re-seeded automatically on every reset.

Custom loot tables bundled with this mod:
  • tk10va:dungeons/lost_cathedral — enchanted golden apple, diamonds, skeleton skull, enchanted iron armour (chestplate/boots), enchanted iron sword, wild armour trim, looting/silk touch books
  • tk10va:dungeons/reyville_sewers — golden apple, amethyst shards, enchanted iron armour (helmet/leggings), enchanted iron axe, wayfinder armour trim, protection/mending books
  • tk10va:dungeons/forgotten_reach — enchanted iron hoe, dune armour trim, ghast tear, blaze rod, lapis lazuli
/dungeon chest list List all registered chests for the dungeon you are standing in, showing each chest's loot table and coordinates.
/dungeon chest list <dungeon> List all registered chests for an explicitly named dungeon (tab-completable).
/dungeon chest remove Unregister the chest nearest to your position in the current dungeon. The chest itself is not affected — only the registration is removed.

🏁 Dungeon End Zone — /dungeon endzone

Mark a set of contiguous floor tiles at the very end of a dungeon. When a player steps on any registered tile, they earn XP — once per dungeon run. The triggered state clears when the dungeon empties and resets.

CommandDescription
/dungeon endzone set <xp> Create (or replace) the end zone for the current dungeon. The floor tile you are looking at becomes the first tile. The <xp> value is awarded to each player who steps on the zone for the first time during a run.
/dungeon endzone tile add Add the floor tile you are looking at to the end zone. The new tile must be face-adjacent (touching) to at least one already-registered tile — tiles must form a single connected group.
/dungeon endzone tile remove Remove the registered end-zone tile nearest to your position.
/dungeon endzone remove Delete the entire end zone for the current dungeon.
/dungeon endzone list Show all registered tiles and the XP reward for the current dungeon's end zone.

🔄 Dungeon Reset — /dungeon reset-dungeon

Forces a full dungeon reset from the admin side without waiting for all players to leave.

CommandDescription
/dungeon reset-dungeon Immediately triggers a full reset of the dungeon you are standing in: removes all mobs, restores pots and puzzle blocks, restores iron bars, clears puzzle progress, re-seeds all registered reward chests, and respawns dungeon coin piles after 5 seconds. Useful for testing without needing to leave the dungeon.

🧑‍🌾 NPC — /npc

All subcommands require permission tk10va.npc.admin + creative mode. Two NPC kinds coexist:

Villager binding commands

CommandDescription
/npc bind <name>Bind the looked-at villager as an NPC. Rejects when <name> is already taken — re-run with /npc bind <name> confirm to move the binding to the new villager.
/npc bind <name> confirmConfirmed move of an existing binding — preserves UUID (all quest/dialogue/rep references survive).
/npc unbind <name>Remove a villager binding. Works whether the entity is loaded or not.
/npc rebind <newName>Rename the looked-at villager NPC. UUID is unchanged.

Custom NPC entity commands

CommandDescription
/npc spawn <name> <texture> [stationary|wander <radius>|patrol]Spawn a custom NPC at your feet. <texture> is the bare skin filename without extension (e.g. aldric for assets/tk10va/textures/entity/npc/aldric.png). Tab-complete shows all available skins. Default behavior is stationary.
/npc remove <name>Kill the custom NPC entity and remove its registry entry. Use /npc unbind for villager-kind NPCs.
/npc texture <name> <texture>Swap the skin on a live custom NPC. <texture> is the bare skin filename (e.g. aldric). Tab-complete shows available skins. Change takes effect immediately.
/npc behavior <name> stationarySet the NPC to stand still and look at nearby players.
/npc behavior <name> wander <radius>Set the NPC to wander within <radius> blocks of its current position (radius ≥ 1).
/npc behavior <name> patrolSwitch to patrol mode with an empty waypoint list. Add waypoints with /npc waypoint <name> add.
/npc waypoint <name> addAppend your current block position as the next patrol waypoint. NPC must already be in patrol mode.
/npc waypoint <name> clearRemove all patrol waypoints for the NPC (it will stand still until new waypoints are added).
/npc namevisible <name> showMake the NPC's name tag always visible, floating above its head.
/npc namevisible <name> hideHide the NPC's name tag. The name is still stored internally; restore it with show.

Shared commands

CommandDescription
/npc inspectPrint the UUID, kind, and display name of the looked-at villager or custom NPC entity (or "unbound").
/npc listList every registered NPC (both kinds) with kind tag and last-known position.

Name rules. Case-sensitive; letters / digits / spaces / hyphens / underscores. Reserved literals (cannot be used as NPC names): bind, unbind, rebind, inspect, list, route, reload, test, validate, confirm, spawn, remove, texture, behavior, waypoint, namevisible.

Name tag. Custom NPCs spawn with their registry display name shown as a floating name tag (show by default). Use /npc namevisible <name> hide to suppress it for background characters. The visibility state persists across server restarts via the entity's own NBT.

Skin workflow. Place a 64×64 PNG in src/main/resources/assets/tk10va/textures/entity/npc/, run ./gradlew buildResourcePack, deploy, restart the server. The filename without the .png extension is the value you pass to /npc spawn and /npc texture (e.g. file aldric.png → command arg aldric). A grey placeholder (default) is always available as a fallback.

Immortality. All bound NPCs (both kinds) cannot be killed. Attacking a custom NPC entity costs NPC reputation equal to a kill (50 by default) when the attacker is in adventure mode.

🌟 Reputation — /reputation

All admin variants require permission tk10va.reputation.admin. The add subcommand bypasses the adventure-mode gate (admin override path); event-driven rep changes still respect the gate. <player> accepts offline players (game-profile lookup).

CommandDescription
/reputation show <player>Dump every NPC and settlement reputation entry for the given player.
/reputation settlement <settlement> <player>Show the player's score and tier for one settlement. <settlement> is a SETTLEMENT-typed land display name.
/reputation npc <npcId> <player>Show the player's score and tier with one NPC. Until the NPC registry ships, <npcId> must be a raw UUID.
/reputation add npc <npcId> <player> <amount>Adjust an NPC reputation directly (clamped at -1000). Bypasses the adventure-mode gate.
/reputation add settlement <settlement> <player> <amount>Adjust a settlement reputation directly (clamped at -1000). Bypasses the adventure-mode gate.

⭐ XP & Level — /level

Permission node: tk10va.xp.admin. All subcommands require Creative mode.

CommandDescription
/level reset <player> Resets the target player's XP and level back to 0. The HUD and tab-list name update immediately if the player is online.

🔒 Block Ownership — /owner

Requires op level 4 and Creative mode.

CommandDescription
/owner Claim the block you are looking at (ray-traces up to 5 blocks). Useful for fine-grained per-block protection within a land section.

Quest System

📋 Player Quest Commands

Available to all players in adventure mode.

CommandDescription
/quest detail <quest-name>Open the quest detail screen for an active quest — shows collected clue pages and completion hint. Tab-completes only your active quests.
/quest detail <quest-name> cancelCancel an active quest. Collectible entities despawn and trinkets are swept from inventory.

📜 Collectible Anchors — /quest collectible

All subcommands require Creative mode and tk10va.quest.admin.

Anchors are config-only placement records stored in config/tk10va/collectibles/<questName>.json. They define where collectible entities will spawn for each player who accepts the quest. An admin-preview entity is spawned immediately at the anchor position so placement can be verified in creative mode — right-click it to inspect its data. The preview is invisible to adventure-mode players.

Slot: "trinket" for trinket anchors; the clue's id string for readable anchors. Placing again on the same slot overwrites. Each READ_COLLECTIBLE clue and each Trinket objective must have exactly one anchor — missing anchors mark the quest unavailable at startup.

CommandDescription
/quest collectible place parchment <quest-name> <clueId> "title" content…Place a parchment anchor for a READ_COLLECTIBLE clue. <clueId> is tab-completed from the quest's clue list. Look at a block within 10 blocks to set the position.
/quest collectible place book <quest-name> <clueId> "title" content…Same as above, using the book collectible type.
/quest collectible place trinket <quest-name> "title" "content" ["visual-item"]Place the trinket anchor for the quest's Trinket objective. title and content must be quoted. Optional visual-item is the bare name of a quest item graphic (tab-completed from the PNGs in the mod's textures/item/, e.g. quest_trinket, quest_parchment, quest_fang) rendered on the pedestal — it resolves to the tk10va:<name> item model and defaults to quest_trinket. Right-clicking the placed collectible opens a confirmation dialog before granting the item.
/quest collectible list [<quest-name>]List all anchors, optionally filtered to one quest. Shows type, slot, and world coordinates.
/quest collectible remove <quest-name> <slot>Remove one anchor by quest and slot. Also kills the admin-preview entity. <slot> is tab-completed.

⚙️ Quest Admin Commands

All require Creative mode and tk10va.quest.admin.

CommandDescription
/quest delete <quest-name>Delete a quest: cancels it for all online players, removes collectible anchors, and deletes the JSON file.
/quest reload allRebuild all quest definitions, collectible anchors, and dialogue graphs from disk in one shot — no restart. Does not cancel active player quests; use this after creating/editing content in the web-admin so it goes live. (Identical effect to /dialogue reload.)
/quest reload <quest-name>Preview: shows how many active players and trinkets would be affected.
/quest reload <quest-name> confirmCancel all active players and reload a single quest JSON from disk.
/quest rename <old-name> <new-name>Rename a quest — updates the display name, moves the JSON file, updates in-memory record.
/quest export <quest-name>Print quest UUID, giver NPC UUID, settlement UUID, clue list, and ready-to-paste dialogue showIf/action lines.
/quest log show <player>Show active quests and completion counts for an online player.
/quest log start <player> <quest-name>Force-start a quest for an online player.
/quest log complete <player> <quest-name>Force-complete a quest for an online player. Applies rewards gated by the player's actual game mode.
/quest log cancel <player> <quest-name>Force-cancel a quest for an online player.
/quest log discover <player> <land-name>Force-record a land discovery for an online player, resolving any matching DiscoverLand clues.

💬 Dialogue — /dialogue

All subcommands require permission tk10va.dialogue.admin + op 4 + creative. Dialogue graphs live in config/tk10va/dialogues/<npcDisplayName>.json (one file per NPC). Right-clicking a bound NPC opens its dialogue at the start node; ESC or moving >6 blocks away closes it.

CommandDescription
/dialogue reloadReload all dialogue JSON files from disk without restarting the server. Also rebuilds the quest registry + collectible anchors, since a dialogue's START_QUEST/COMPLETE_QUEST action is resolved live against the quest registry and the two must stay in sync. (Identical effect to /quest reload all.)
/dialogue validateRun structural validation on every loaded graph and print warnings (broken node refs, unparseable actions/conditions).
/dialogue test <npc-name>Open a dry-run session. showIf conditions evaluate against your real state so you see what an adventure-mode player would see — but no quests start, no rep changes, and no clues are recorded. <npc-name> is tab-completed from bound NPCs.

🪙 Merchant — /merchant

All subcommands require permission tk10va.merchant.admin + op 4 + creative. Merchant catalogues live in config/tk10va/merchants/<npcDisplayName>.json (one file per NPC). Players open a shop from that NPC's dialogue via an option carrying the OPEN_MERCHANT action (guarded by the HAS_MERCHANT condition). Catalogues are authored in the web-admin.

CommandDescription
/merchant reloadReload all merchant JSON files from disk without restarting the server. (Merchants are also reloaded by /quest reload all and /dialogue reload.)
/merchant listList every loaded merchant and its offer count.
/merchant validateRun structural validation on every catalogue and print warnings (empty offers, dead lines with no buy/sell price, negative prices).
/merchant open <npc-name>Open a merchant's shop screen for yourself to test it. Not a dry-run — purchases and sales are real. <npc-name> is tab-completed from bound NPCs.

🐎 Mount — /mount

All subcommands require permission tk10va.mount.admin + op 4 + creative. Mount definitions live in config/tk10va/mounts/<id>.json (one file per mount). A mount is sold to players as a synthetic mount:<id> merchant offer, so its price and reputation gates live on the merchant offer, not the mount file; a mount is resellable only if that offer sets a sell price. Players own many mounts but only one is active, chosen from an inventory parchment, and summoned anywhere by the recall keybind. Definitions are authored in the web-admin.

CommandDescription
/mount reloadReload all mount JSON files from disk without restarting the server. (Mounts are also reloaded by /quest reload all and /dialogue reload.)
/mount listList every loaded mount definition with its display name and render kind (vanilla entity type or custom model key).
/mount validateRun structural validation on every mount definition and print warnings (blank id, id containing :, non-namespaced vanilla entity type, non-positive stats).

Collectible types

Collectible entities are placed in the world by admins and collected once per player. All collectibles must be bound to a quest.

📜
Parchment
type: parchment

Clue trigger. Right-click adds the content as a new page in /quest detail <name>. No inventory item granted.

📖
Book
type: book

Same as Parchment — clue trigger only, no inventory item.

💎
Trinket
type: trinket

Deliverable. Right-click adds the trinket to inventory for return to the quest-giver NPC. Cannot be dropped or stored in containers.

All quest items visible only to players who have the relevant quest active. Trinkets survive death and cannot leave the player's inventory until the quest is completed or cancelled.

Quest JSON schema

Each quest lives in config/tk10va/quests/<displayName>.json. The filename must match the name field exactly. All IDs are raw UUIDs — use /npc inspect for NPC UUIDs, and the land section UUID appears in /land info <name>.

{
  "id":            "<quest-uuid>",
  "name":          "Wolf Fang Necklace",
  "settlementId":  "<settlement-land-uuid>",   // optional — null/omit when the giver belongs to no settlement
  "giverNpcId":    "<npc-uuid>",
  "repeatable":    false,

  "objective": {
    "type":         "TRINKET",
    "trinketTitle": "Wolf Fang Necklace"
  },

  "clues": [
    {
      "id":     "wolf_lore",
      "page":   "The alpha hunts the Ash Cairns when the moon is high.",
      "trigger": { "type": "TALK_NPC", "npcId": "<npc-uuid>", "nodeId": "wolf_lore" }
    },
    {
      "id":     "branns_note",
      "trigger": { "type": "READ_COLLECTIBLE" }
    },
    {
      "id":     "ruined_shrine",
      "page":   "A bronze-wrapped fang lies on the altar.",
      "trigger": { "type": "DISCOVER_LAND", "landSectionId": "<land-uuid>" }
    }
  ],

  "prerequisites": [
    { "type": "MIN_NPC_REP", "npcId": "<npc-uuid>", "amount": 50 }
  ],

  "npcRepReward":        50,
  "settlementRepReward": 20,
  "xpReward":           150,
  "coinReward":          10,

  "rareRewards": [
    { "itemId": "minecraft:dragon_head", "chancePercent": 2.5 },
    { "itemId": "minecraft:nether_star", "chancePercent": 0.05 }
  ]
}

A quest carries no dialogue-node pointers. Acceptance and completion are wired entirely through the giver NPC's dialogue — a START_QUEST action (guarded by CAN_ACCEPT) lets the player accept, and a COMPLETE_QUEST action (guarded by ACTIVE + OBJECTIVE_COMPLETE) turns it in. This is identical for every objective type. The quest validator warns when either action is missing from the giver's dialogue.

Objective types
typeExtra fieldsCompleted when
TRINKETtrinketTitle (string)Player returns to the giver NPC while carrying the bound trinket and selects the completion dialogue option. The trinket is consumed on completion.
DISCOVERYlandSectionId (UUID)Player enters the named land section then returns to the giver NPC and selects the completion dialogue option. Must also have a DISCOVER_LAND clue for the same land.
GATHERitems — array of { "itemId", "count" }Player carries all required items, then returns to the giver NPC and selects the completion dialogue option. The items are consumed from the inventory on completion. Each itemId is a full registry id, e.g. minecraft:stick.
HUNTmobs — array of { "entityId", "count" }Player kills the required number of each mob while in adventure mode (progress is tracked per kill), then returns to the giver NPC and selects the completion dialogue option. Each entityId is a full registry id, e.g. minecraft:zombie. Works for hostile or passive mobs.

Every objective type completes the same way: through the giver NPC's dialogue. The giver's dialogue must contain a COMPLETE_QUEST action; guard that option with ACTIVE:<uuid> + OBJECTIVE_COMPLETE:<uuid> so it only appears once the player can actually hand the quest in. The quest validator warns if the giver's dialogue is missing the START_QUEST or COMPLETE_QUEST action.

Rare item rewards

In addition to the fixed npcRepReward / settlementRepReward / xpReward / coinReward, a quest may grant probabilistic decorative item rewards via the optional rareRewards array. Each entry is { "itemId", "chancePercent" } where itemId is a full registry id (any vanilla or mod item, e.g. minecraft:dragon_head) and chancePercent is the drop chance in the range (0, 100] — values as small as 0.001 make the item exceptionally rare. The roll happens on every completion, so a repeatable quest can be farmed for the drop. If the inventory is full the item is dropped at the player's feet.

Clue trigger types
typeExtra fieldsFires when
TALK_NPCnpcId, nodeIdPlayer opens the matching dialogue node on the matching NPC.
READ_COLLECTIBLEnonePlayer right-clicks a bound parchment/book entity in the world. Page text comes from the entity's content, not from the JSON page field.
DISCOVER_LANDlandSectionIdPlayer enters the named land section for the first time.
Prerequisite types
typeExtra fields
COMPLETED_QUESTquestId — player must have completed this quest at least once.
NOT_COMPLETED_QUESTquestId — player must NOT have completed this quest.
MIN_NPC_REPnpcId, amount — minimum NPC reputation required.
MIN_SETTLEMENT_REPsettlementId, amount — minimum settlement reputation required.
MIN_LEVELlevel — minimum player XP level required.

Dialogue JSON schema

Each dialogue lives in config/tk10va/dialogues/<npcDisplayName>.json. The filename must match the displayName field exactly. All IDs are raw UUIDs — use /npc inspect to get the NPC's UUID. "END" is a reserved next value that closes the session.

{
  "npcId":       "<npc-uuid>",
  "displayName": "Elder Durn",
  "start":       "greet",

  "nodes": {

    "greet": {
      "text":    "Welcome, traveler. The woods are restless of late.",
      "onEnter": ["AWARD_REP_NPC:1"],
      "options": [
        { "label":  "Any work for me?",
          "next":   "quest_board",
          "showIf": ["NOT_ACTIVE:<quest-uuid>",
                     "COMPLETED_NEVER:<quest-uuid>"] },
        { "label":  "I found the wolf's fang.",
          "next":   "wolf_return",
          "showIf": ["ACTIVE:<quest-uuid>",
                     "OBJECTIVE_COMPLETE:<quest-uuid>"] },
        { "label":  "Just passing through.",
          "next":   "END" }
      ]
    },

    "quest_board": {
      "text": "There's a wolf alpha prowling the Ash Cairns. I'd pay well for its fang.",
      "options": [
        { "label":  "Tell me more.",
          "next":   "wolf_brief",
          "showIf": ["CAN_ACCEPT:<quest-uuid>"] },
        { "label":  "Not today.",
          "next":   "END" }
      ]
    },

    "wolf_brief": {
      "text": "The alpha haunts the Cairns at dusk. Speak to Brann — he left notes there. Bring me the fang when it's done.",
      "options": [
        { "label":   "I'll hunt it.",
          "next":    "wolf_accepted",
          "actions": ["START_QUEST:<quest-uuid>"] },
        { "label":  "Maybe later.",
          "next":   "END" }
      ]
    },

    "wolf_accepted": {
      "text": "Good. Return once you have the fang. Safe travels.",
      "options": [
        { "label": "I'll be back.", "next": "END" }
      ]
    },

    "wolf_return": {
      "text": "You found it! The Cairns are safer already. Here is your reward.",
      "options": [
        { "label":   "Here it is.",
          "next":    "END",
          "actions": ["COMPLETE_QUEST:<quest-uuid>",
                      "AWARD_REP_NPC:50",
                      "AWARD_REP_SETTLE:<settlement-uuid>:20"] }
      ]
    }

  }
}
Dialogue actions
Action stringEffect
START_QUEST:<uuid>Calls QuestLog.start. No-ops silently when CAN_ACCEPT would fail at runtime.
COMPLETE_QUEST:<uuid>Completes the quest and triggers all configured rewards.
AWARD_REP_NPC:<n>Add n NPC rep with the NPC currently being talked to.
AWARD_REP_SETTLE:<settleUuid>:<n>Add n reputation with the named settlement.
GIVE_ITEM:<itemId>:<count>Give an item stack to the player (e.g. minecraft:golden_apple:1).
OPEN_MERCHANTOpen the shop screen for this NPC (no argument). Requires a merchant catalogue bound to the NPC — pair it with the HAS_MERCHANT condition. Opening the shop ends the dialogue (the shop takes over the screen and closes back to the game), so the option's next is ignored — set it to "END".
showIf conditions

Multiple conditions are ANDed. Options whose any condition fails are hidden. Duplicate the option to express OR.

Condition stringTrue when
ACTIVE:<uuid>Quest is currently active for the player.
NOT_ACTIVE:<uuid>Quest is not active.
COMPLETED_BEFORE:<uuid>Quest completed at least once.
COMPLETED_NEVER:<uuid>Quest never completed.
CAN_ACCEPT:<uuid>Compound: not active + fewer than 3 active quests + all prerequisites met + player in adventure mode.
OBJECTIVE_COMPLETE:<uuid>The quest's objective requirement is satisfied and the player is ready to turn it in — the single "quest can be completed" condition, generic across every objective type: trinket held · all clues collected (discovery) · all items carried (gather) · all kill counts reached (hunt). Use this (with ACTIVE) to gate the COMPLETE_QUEST option so it only shows when the quest can actually be handed in. (CLUES_COMPLETE is a deprecated alias kept for older dialogue files.)
DISCOVERED_LAND:<uuid>Player has entered the named land section at least once.
NOT_DISCOVERED_LAND:<uuid>Player has never entered that land section.
REP_NPC_GTE:<n>NPC reputation with the current NPC is ≥ n.
REP_SETTLE_GTE:<settleUuid>:<n>Settlement reputation ≥ n.
TIER_NPC_GTE:<tier>NPC rep tier ≥ the named tier: HOSTILE / UNFRIENDLY / NEUTRAL / FRIENDLY / HONORED.
HAS_ITEM:<itemId>Player carries at least one of this item (e.g. tk10va:quest_trinket).
HAS_MERCHANTA merchant catalogue is bound to this NPC (no argument). Use it to gate the "Show me your wares" option so the shop button only appears when a shop actually exists.

Clue recording. There is no RECORD_CLUE action. TALK_NPC clues record automatically when the player opens the matching node on the matching NPC — no extra authoring needed.

Authoring tips

🪙 Merchant / Shop JSON schema

Each merchant lives in config/tk10va/merchants/<npcDisplayName>.json (one file per NPC, keyed by npcId). Author them in the web-admin's Merchants tab. A player opens the shop from the NPC's dialogue via an option with the OPEN_MERCHANT action, guarded by the HAS_MERCHANT condition.

{
  "npcId": "<npc-uuid>",
  "displayName": "Aldric",
  "offers": [
    { "itemId": "minecraft:iron_sword", "buyPrice": 120, "sellPrice": 40,
      "minNpcRep": 25,
      "minSettlementRep": { "settlementId": "<settlement-uuid>", "amount": 50 } },
    { "itemId": "minecraft:bread", "buyPrice": 3, "sellPrice": 1 }
  ]
}
FieldMeaning
itemIdFull registry id of any Minecraft (or mod) item, e.g. minecraft:iron_sword. Use mount:<mountId> to sell a mount — buying grants the mount entitlement (not an item), and it can only be bought once. The item picker lists mounts automatically.
buyPriceCoins the player pays to buy one. 0 or omitted → the item can't be bought (sell-only).
sellPriceCoins the NPC pays when buying one back from the player. 0 or omitted → the item can't be sold (buy-only).
minNpcRepOptional. Minimum reputation with this NPC required to buy the item. Selling is never gated.
minSettlementRepOptional { "settlementId", "amount" }. Minimum reputation with the named settlement required to buy the item. Omit for no settlement gate.

Set a buy price, a sell price, or both per line. Stock is unlimited. The shop screen has Buy and Sell tabs and a cart: players adjust quantities per line and confirm once to buy or sell everything in the cart. Reputation-locked buy lines are shown greyed out with a reason. The server re-checks coins, reputation, and (when selling) inventory on every checkout — client prices are never trusted. The web-admin flags a merchant whose NPC has no dialogue OPEN_MERCHANT option (players couldn't open it) and a dialogue that uses OPEN_MERCHANT/HAS_MERCHANT with no matching merchant file.

🐎 Mount JSON schema

Each mount lives in config/tk10va/mounts/<id>.json (one file per mount). A mount is sold to players by adding a merchant offer whose itemId is mount:<id> — so price and reputation gates live on the merchant offer, not here, and a mount is resellable only when that offer sets a sellPrice. Players own many mounts but keep only one active, chosen from an inventory parchment and summoned anywhere with the recall keybind.

{
  "id": "swift_horse",
  "displayName": "Swift Horse",
  "render": { "kind": "vanilla", "entityType": "minecraft:horse" },
  "stats":  { "moveSpeed": 0.3, "jumpStrength": 0.6, "maxHealth": 30, "stepHeight": 1.0 }
}
FieldMeaning
idUnique mount id. Must not contain : (it becomes the merchant offer mount:<id>). This is the file name.
displayNameName shown in the shop and the mount selection parchment.
render.kindvanilla — spawn an existing entity type; set render.entityType to a namespaced id (e.g. minecraft:horse, minecraft:sheep). Or custom — spawn the mod's mount; set render.modelKey to a hand-authored model (beast = generic quadruped, canine = large dog/wolf, feline = large lion/tiger/big cat) and optional render.skin (canine coats: black_wolf, white_wolf, grey_wolf, brown_wolf; feline coats: black_cat, white_cat, grey_cat, brown_cat). An unknown model key falls back to beast. Either way the mount is fully steerable (look to turn, W to go).
stats.moveSpeedMovement speed attribute (> 0; horse-like ≈ 0.1–0.35).
stats.jumpStrengthJump strength attribute (≥ 0; 0 = no boosted jump).
stats.maxHealthMax health in half-hearts×2 (> 0; e.g. 30 = 15 hearts).
stats.stepHeightBlock step height (≥ 0; 1.0 walks up a full block).

Omitting stats (or any field within it) falls back to sensible defaults. Author mounts in the web-admin's Mounts tab. Validate with /mount validate; reload with /mount reload (or /quest reload all). Every mount type is steerable — you look to turn and press forward to move — whether it's an equine, another vanilla mob (sheep, cow, …), or a custom mount. stats.moveSpeed sets how fast it goes; stats.jumpStrength its jump height.

World Hazards

Admins can place hazard blocks in the world to create environmental dangers for encounters and exploration.

☠ Poison Water — tk10va:poison_water

A custom fluid that looks and flows like normal water but with a sickly green tint. Players who enter it are afflicted with Poison II, which starts draining health immediately on entry and reduces it down to half a heart — but cannot kill on its own. The effect lingers for 15 seconds after leaving the water.

🏊
Full water physics

You can swim and drown in it. Respiration and Aqua Affinity enchantments work normally.

💚
Green tint

Visually distinct from normal water — the green colour clearly signals danger to players.

Lingering poison

The Poison II effect persists for 15 seconds after exiting — escaping the pool is not an instant cure.

Placement (Creative mode)

The Poison Water Bucket is available in the Tools & Utilities creative tab — right-click to place it like any other bucket. For larger areas use the fill command:

/fill x1 y1 z1 x2 y2 z2 tk10va:poison_water

Scooping placed poison water with an empty bucket returns a Poison Water Bucket. The fluid obeys the waterSourceConversion game rule for infinite-source behaviour.