Skip to main content
Table of Contents
Print

03. Visiting Villagers – Trade Configuration Guide (JSON)

This page details the structure of the Visiting Villagers trade JSON files, explaining the syntax of fixed items, dynamic families (family), random lists (one_of), special types, and the reload system without restarting the game.


📂 File Location and Structure

The visitor trade catalogs are stored in the folder: config/visitingvillagers/trades/

  • 23 Default Files: On first startup, the mod copies 23 default .json files (one for each adult visitor and wanderer variant) into this folder.
  • Edition Preservation: The mod never overwrites an existing file in the config/ folder. To restore a variant’s default, simply delete its corresponding .json file and restart the game.

✅ Valid Variant Keys (file names)

The file name (without .json) must match one of the 23 keys known to the mod. Files with names outside this list are discarded on load (the mod falls back without applying the catalog):

Adult VisitorsWanderers
minerwandering_plains
beekeeperwandering_forest
lumberjackwandering_cave
good_pillagerwandering_mountain
glassworkerwandering_snow
railwrightwandering_swamp
relic_scavengerwandering_desert
piglin_traderwandering_master
beachcomber
enchant_smith
redstone_engineer
pyrotechnic
mycologist
hunter
default (profession-less variant)

📄 Internal JSON Structure

Each .json file represents a variant and is divided into two independent pools: buys (NPC purchases) and sells (NPC sales).

{
  "variant": "miner",
  "buys": {
    "select": 3,
    "trades": [
      {
        "cost": { "id": "minecraft:dandelion", "count": 12 },
        "result": { "id": "minecraft:emerald", "count": 1 },
        "max_uses": 8,
        "xp": 2,
        "price_multiplier": 0.05
      }
    ]
  },
  "sells": {
    "select": 3,
    "trades": [
      {
        "cost": { "id": "minecraft:emerald", "count": 10 },
        "result": { "id": "minecraft:diamond", "count": 1 }
      }
    ]
  }
}

📋 Main Fields

FieldRequiredDescription
variantNoVariant ID. If omitted, the mod uses the file name itself (without .json).
typeNoDefines a special type with a random result (in place of result).
buys / sellsNoIndependent offer pools whose directions are defined by cost / result.
selectNoNumber of offers rolled per visit (0 disables; omitted uses the entity’s default).
costYes*Item required by the visitor and delivered by the player.
cost_bNoSecond cost item for trades that require two items.
resultYes*Item delivered by the visitor to the player.
max_usesNoUsage limit before the offer runs out (Default: 4).
xpNoExperience granted to the player on the vanilla scale (Default: 2).
price_multiplierNoPrice change multiplier (Default: 0.05).

*Note: For special types (type), the type field replaces result.


📦 Item Formats in Offers (cost, cost_b and result)

A) Fixed Item (id)

Defines a specific item with an exact quantity (from 1 to 99) with support for native 1.21.1 Data Components:

{
  "id": "minecraft:diamond_sword",
  "count": 1,
  "components": {
    "minecraft:custom_name": "Ancient Relic",
    "minecraft:damage": 120
  }
}
  • Costs with Components: In buy offers (cost), the player must deliver exactly the item with the specified components (same name, enchantment, or damage).

B) Dynamic Families (family)

Instead of listing dozens of items individually, the family selector rolls one concrete item from the family per offer at each restock:

{ "family": "log", "count": 16 }
{ "family": "wool", "colors": ["white", "black"], "count": 16 }
{ "family": "sapling", "variant": "cherry", "count": 1 }
  • No Filter: The mod uses the automatic default list (e.g.: the 16 colors for wool/dye/stained_glass, registered wood types for log/planks, 7 species for sapling, or it scans the registry for pottery_sherd and armor_trim_smithing_template).
  • With Filter: Allows restricting the roll using color / colors (color families) or variant / variants (wood/species families).

How the mod validates a family (all possible families)

There is no fixed list of family names — validation is dynamic against the game’s item registry using the naming pattern minecraft:<prefix>_<family>:

  • Color families: the family is valid if minecraft:<color>_<family> exists for all 16 dye colors (e.g.: wool, carpet, bed, banner, terracotta, stained_glass, candle, shulker_box, dye, concrete_powder etc.).
  • Wood/species families: valid if minecraft:<type>_<family> exists for the requested types — the 11 vanilla wood sets (oak, spruce, birch, jungle, acacia, dark_oak, mangrove, cherry, bamboo, crimson, warped) or the 7 sapling species (oak, spruce, birch, jungle, acacia, dark_oak, cherry).
  • Other groups (pottery_sherd, armor_trim_smithing_template): resolved by scanning all registered items ending with _<family>.

💡 Tip: if a family name does not follow the naming pattern, use the one_of selector with full IDs — that is the recommended escape hatch. A missing item in a family (missingColor/missingVariant) causes a validation error in the log.


C) Random Selection Without Suffix (one_of)

For item groups that do not share a common name suffix (such as foods, flowers or seeds), define a list of full IDs:

{
  "cost": {
    "one_of": [
      "minecraft:dandelion",
      "minecraft:poppy",
      "minecraft:blue_orchid",
      "minecraft:lily_of_the_valley"
    ],
    "count": 12
  },
  "result": { "id": "minecraft:emerald", "count": 1 }
}
  • Rolls a single item from the list per generated offer and supports items from other mods registered at runtime.

🎲 Special Types (Results Generated on Sale)

Four original types roll the resulting item at the exact moment of the transaction. For these types, the type field replaces result and the cost must be in emeralds:

typeResult Description
random_enchanted_bookBook with random enchantment and level (price calculated like vanilla).
random_suspicious_stewSuspicious stew with a random beneficial effect.
random_firework_starFirework star with random shape, color, and effects.
random_rocketFirework rocket with random duration, shape, and effects.
{
  "type": "random_enchanted_book",
  "cost": { "id": "minecraft:emerald", "count": 5 },
  "max_uses": 12,
  "xp": 15
}

🔄 Real-Time Trade Reload

To apply changes to the JSON files without restarting the server or the game:

  1. Edit or create the .json files in the config/visitingvillagers/trades/ folder.
  2. In the in-game chat, run the administrator command (permission level 2):/visitors reloadtrades
  • Effect: The mod reloads the files, validates the syntax, and clears the offer cache of loaded visitors that are not in an open trading session. New offers will be generated on the next interaction with the NPC.

🛡️ Early Validation and Fallback System

All JSON file validation is performed during server loading (ServerStartingEvent):

  • Rigorous Checking: The loader (TradeJsonLoader) validates whether IDs exist in the game registry, whether the quantity (count) is within the allowed range (1–99), whether the color/variant filters are valid, and blocks property conflicts (e.g.: defining id and family in the same object).
  • Crash Protection (Fallback): If any JSON file contains a syntax error or invalid ID, the mod prints a clear log message (WARNING) indicating the error and performs an automatic reversal (fallback) to the original file embedded in the .jar, ensuring the server keeps running safely.