Feature Villager Trading - bh679/dungeon-train-mc GitHub Wiki

Villager Trading β€” Trade Anything + beyond-Master progression

Since: v0.504.0 (PR #828)

Two systems shipped together in v0.504.0: the Trade Anything slot (powered by the new companion mod Trade Everything, bundled inside DT via jarJar) and carriage-scaled trade progression (DT-side, difficulty/TradeGearScaler).

⚠️ Balancing status: exchange rates and scaling curves are first-pass and under active review β€” values below describe the mechanism, not final tuning.

The Trade Anything slot (Trade Everything mod)

Every villager (and wandering trader, config-toggleable) gains one extra trade at the top of its list, shown as a chest named Trade Anything. Put any item in and the offer rewrites itself live: N Γ— your item β†’ M Γ— something the villager buys.

Pricing is integer fixed-point in sixteenths of an emerald:

  • Base value from vanilla rarity (COMMON=1 β†’ 16 items/emerald) with a shipped override table (ores, gear materials, uncraftable gear like tridents/saddles/anvil states…)
  • Recipe derivation: craftable items are worth their cheapest crafting or smithing recipe, solved recursively at recipe-load time (netherite gear derives from diamond gear + ingot + template)
  • Durability scales value 10%β†’100% (full at β‰₯90% durability); enchantments add 2^(levelβˆ’1) per enchant (Sharpness V = 16Γ— Sharpness I); DT values narrative books flat via the TE API
  • Payout ladder: villager's buy-item β†’ emeralds β†’ emerald blocks when one input item exceeds a stack of the payout; payout items the villager itself trades are valued at the villager's own exchange rate
  • Payouts are 75% of value (merchant margin, result_multiplier)

Exemptions & buy-back: emeralds/emerald blocks and items the villager buys are refused (they belong to the real trade rows). The villager's own stock buys back at its value, capped at 10% under its live (discount-adjusted) sell price β€” so gossip/hero discounts can never be looped into profit, but returns are always possible. Since Trade Everything 0.14.0 the villager pays whichever of the two is lower; before that it always paid the 90% buy-back, which is how a librarian (who sells a bookshelf for 9 emeralds) paid 8 emeralds for one.

Emerald blocks as currency: clicking an emerald-priced trade row breaks just enough emerald blocks in your inventory to cover the cost; change stays as emeralds.

Space-bar refill (Trade Everything 0.4.0, DT v0.593.0): pressing space in the villager screen puts the last item traded through the Trade Anything slot back into it β€” as many as you are carrying, up to a full stack. It is the repeat-trade shortcut vanilla gives its own trades, which the synthetic slot cannot reuse: vanilla matches the offer's ItemCost against the inventory, and an empty synthetic slot advertises a deliberately unmatchable barrier placeholder, so vanilla finds nothing to move. The client instead replays the two clicks a player would make by hand (PICKUP source β†’ PICKUP onto payment slot 0), so every mutation stays on the ordinary server-validated ServerboundContainerClickPacket path β€” no custom packet, no server-side counterpart. Client-side only: on a server it works for players who have the mod installed; vanilla clients keep filling the slot by hand. The handler claims space only when nothing is focused, so a Tab-focused trade button still treats space as "activate".

Obsidian (Trade Everything 0.5.0) is pinned at 4 sixteenths β€” 4 obsidian to one emerald's worth. It previously had no override and no crafting recipe, so it fell through to the COMMON default of 1 sixteenth, quoting 22 obsidian per emerald; the new value lines it up with shipped peers like quartz and amethyst_shard.

Bookshelves (Trade Everything 0.14.0, DT PR #1758) trade four for 1 emerald. DT values one at 5.5 sixteenths β€” set in 256ths (88) through TradeEverythingApi.setItemOverride256ths, because no whole sixteenth quotes a 4 β†’ 1 row (5 gives 9 β†’ 2, 6 gives 11 β†’ 3; the pricer skips a batch that rounds away more than 10%). A villager that pays in goods pays the same value in those goods β€” a librarian gives 4 paper per shelf. This raised DT's Trade Everything floor to 0.14.0.

Hand-set villager stock (DT PR #1760). With buy-back now a ceiling, things villagers sell pay their value β€” and most default to next to nothing (a 36-emerald bell sold back for about a twentieth of an emerald). TradeEverythingBridge.VILLAGER_STOCK_VALUES_256THS sets nine by hand; prices are emeralds each, after the 75% margin:

Item Price Row at an emerald-paying villager
Bell 2 1 β†’ 2
Name tag 1 1 β†’ 1
Globe banner pattern 1 1 β†’ 1
Iron chestplate 5 1 β†’ 5
Leather tunic 3 1 β†’ 3
Ender pearl 2 1 β†’ 2
Item frame 0.4 5 β†’ 2
Empty map 0.5 2 β†’ 1
Blue ice 0.3 7 β†’ 2

Gear prices are for an undamaged item; worn gear scales down. Blue ice is valued at 0.30 but 7 β†’ 2 is the first batch inside the pricer's 10% rounding tolerance. Other villager stock (the rest of the iron and leather armour, clocks, saddles, wandering-trader goods…) still pays its default value.

Config: config/tradeeverything.json (rarity values, per-item overrides, multiplier, caps, recipe derivation, wandering trader). Java API: games.brennan.tradeeverything.api.TradeEverythingApi (value providers, runtime overrides, payout selectors) β€” DT's compat/TradeEverythingBridge uses it for book pricing.

Carriage-scaled trade progression (beyond Master)

Train villagers key entirely off their own carriage (positionTier of the pIdx baked into their contents tag) β€” not player progress:

  • Level: cap = dominant mob weapon stage + 1 (Novice β†’ Master at ~carriage 520 with default 20 carriages/tier); spawns at the cap or one below, 50/50
  • Enchants (from carriage 30): sold gear is stripped and re-enchanted at power 15/25/35/45… (+1 step per 5 tiers, cap 60 β€” past vanilla's 30-level table by ~carriage 220)
  • Stats: AIS stats roll for tier + rand(0..max(1, tier/5)) β€” shop gear sits slightly ahead of the local difficulty curve
  • Costs: emerald prices grow by the enchant premium (2^(levelβˆ’1) emeralds per enchant β€” the same curve TE values enchants at, so buy and sell prices agree); totals past 64 emeralds charge emerald blocks
  • Sold gear is AIN-named, matching mob gear and chest loot

Config (dungeontrain-server.toml β†’ difficulty): villagerTradeScalingEnabled, villagerTradeScalingMinCarriage (30), villagerTradeScalingTiersPerStep (5).

Notes

  • Offers are pre-baked once per villager (dungeontrain_trades_rerolled tag) β€” no restock.
  • Synthetic Trade Anything offers grant no villager XP, never persist to NBT, and never trigger restock.
  • Trade Everything is currently bundled (jarJar) while its Modrinth/CurseForge listings await approval; it will later become an external required download like AIN/AIS/PMOB/ECP.