Mercantile

Changelog

Version history for Mercantile, in the Keep a Changelog format. Mercantile follows semantic versioning. For binaries, see GitHub Releases.

[Unreleased] / [0.1.0] — Initial Release

First public version. Full feature set across villager overhaul, trade GUI, reputation, and village defense.

Added

Infrastructure (E-001)

  • Config system with JSON persistence, hot reload, Cloth Config + Mod Menu integration (S-001).
  • Fabric attachment types for per-player and per-entity persistent data (S-002).
  • Custom packet payloads with StreamCodecs for all client-server traffic (S-003).
  • /mercantile command tree: reputation get/set/add, village, reload (S-004).
  • Profession-to-head-texture registry with Base64 skin values for all 16 vanilla professions (S-005).

Core Standalone Features (E-002)

  • Biome-themed villager names with datapack-overridable pools (S-006).
  • Profession lock on first completed trade with lock icon in trade GUI (S-007).
  • Splash/lingering healing + regen multiplier for villagers (S-008).
  • Client-side villager sound volume slider (S-009).
  • Pathfinding fixes: doors, stairs, ladders, water avoidance (S-010).

Trade GUI (E-003)

  • Bulk trading via shift-click on trade output, up to 64 iterations (S-011).
  • Restock timer + counter in merchant screen (S-012).
  • Demand pricing transparency with color-coded breakdown tooltip (S-013).
  • Villager info side panel with profession, level, reputation, trade count (S-014).

Villager Pickup (E-004)

  • Villager pickup with full NBT preservation, profession-styled head item, XP cost, raid/trade/follow denials (S-015).

Trade Cycling & Reputation (E-005)

  • Trade cycling with emerald cost, lock tracking, and per-profession lock preservation (S-016).
  • Five-tier reputation system with persistent score, gossip integration, exclusive trades via datapack (S-017).

Villager AI (E-006)

  • Follow mode: sneak-right-click with emerald, max 3 villagers per player, auto-release at distance (S-018).

Visualization (E-007)

  • Workstation link visualization while holding a bell, profession-colored particle lines (S-019).
  • Bell radius visualization with 48-block gold circle + ring highlight (S-020).

Mod Integrations (E-008)

  • Jade/WTHIT breeding information tooltips with cooldown, food inventory, baby growth (S-022).
  • Jade/WTHIT contextual state indicators (needs bed, hungry, panicking, trading-with) (S-023).
  • EMI/REI/JEI unified trade index with profession filters and tier badges for exclusive trades (S-024).

Sentry Pylon (E-009)

  • Sentry Pylon block with iron-block fuel, hostile detection, temporary golem spawning, redstone disable, comparator output, Jade/WTHIT fuel tooltip (S-025).

HUD & Client Polish (E-011)

  • Reputation HUD overlay near villagers, auto-stacks with rfizzle suite mods (S-036).

Website & Distribution (E-012)

  • Public website at mercantile.rfizzle.com with feature documentation, config reference, command reference, and getting-started guide (S-037).
  • Modrinth and CurseForge project listings with screenshots and feature documentation (S-038).

CI/CD & Automation (E-013)

  • GitHub Actions pipelines for build, test, release, GitHub Pages deployment, and Claude integrations (S-039).

Changed

  • Consolidated tier boundaries into a single ReputationTier enum used by commands, exclusive trades, and price modifiers (S-027).
  • Tier names made translatable via command.mercantile.tier.* language keys.
  • Migrated all static mutable state to thread-safe alternatives (ConcurrentHashMap, volatile, ThreadLocal) for integrated client safety (S-026).
  • Standardized offer identity hashing across pickup and trade cycling via shared OfferIdentityHash utility.
  • Renamed internal VillagerData to MercantileVillagerData to avoid collision with net.minecraft.world.entity.npc.VillagerData (S-028).

Fixed

  • Atomic config writes via tmp-file + Files.move with ATOMIC_MOVE to prevent corruption mid-write (S-028).
  • Expanded numeric clamp() coverage to every field, matching Cloth Config screen bounds (S-028).
  • Reputation price modifier now sets absolute value on specialPriceDiff instead of compounding on each trade screen open (S-027).
  • Kill-event reputation penalty corrected from accidental −35 to spec'd −25 by guarding the AFTER_DAMAGE handler against already-dead entities (S-027).
  • Entity-duplication and emerald-loss windows in pickup and follow flows closed by reordering irreversible actions last (S-032).
  • Bulk trading refillSlot refills to cost.count(), not maxStackSize (S-031).
  • Trade cycling syncs offers after exclusive trade injection so clients see the full updated list immediately (S-031).
  • Door-mixin reentrancy guard and pathfinding fence-gate tracking fixed to prevent stack overflow and leaked gate refs (S-030).
  • Phantom client-side follow particles cleared by routing UUID-based stop through ENTITY_UNLOAD on the live Villager instance (S-032).
  • Network payload size guards added to ConfigSyncS2CPayload and WorkstationMapS2CPayload; per-player cooldowns on C2S request packets (S-029).
  • Build cleanup: deduplicated loom {} blocks, added timeout to runGitDescribe.proc.waitFor() (S-035).
  • Reputation HUD overlay now actually renders near villagers — initial scan-tick value overflowed and suppressed every frame's proximity scan (S-046).
  • EMI villager-trade category now shows its translated name instead of the raw emi.category.mercantile.villager_trades key (S-046).
  • Merchant info panel splits profession and level onto separate lines so long localized names no longer overflow the 98px content area (S-046).
  • Reputation and config now sync to the client on player join, so the HUD and config-gated client features no longer show stale state at login (S-047).
  • Jade plugin is now discovered at load time — all Jade tooltips (villager breeding, state indicators, sentry pylon fuel) were silently broken because the jade entrypoint was missing from fabric.mod.json (S-048).
  • Trade-screen info overlay (the centered panel that opens via the [i] icon when the window is too narrow for the inline side panel) no longer lets merchant-screen icons, slots, and the XP bar ghost through the panel surface — the overlay panel background is now fully opaque and the surrounding dim is deeper, so text rows read cleanly instead of overlapping background art (S-053, B-099).
  • Nitwit profession head no longer ships a watermarked third-party user skin — the trade index now renders the nitwit entry with a clean villager face (reused from the unemployed skin, since vanilla nitwits have no head overlay) (S-054, B-097).
  • Trade screen lock badge and Re-roll Trades button now refresh live on trade completion — previously the open merchant screen kept showing the unlocked badge and an active re-roll button after the first purchase that flipped the villager to locked, only updating on close→reopen or level-up (S-056, B-102).
  • Bedless villager tooltip no longer shows two lines for the same condition — the redundant yellow Needs a bed state-indicator icon was removed; the breeding tooltip's red Breeding: Needs bed line now stands alone. The state-indicator stream's remaining icons are Trading, Panicking, and Needs workstation (S-060, B-103).
  • Trade-screen info-panel overlay (the centered modal opened by the [i] button on narrow windows) no longer has inventory and hotbar item icons rendering on top of it — the panel, dim layer, Re-roll Trades button, and close x now sit above slot items, while button tooltips still appear on top of the overlay (S-064, B-106).
  • Trade-screen [i] info button and overlay close [x] button now use dedicated sprites with the glyphs pre-baked, so the icons are visually centered in their boxes instead of sitting one pixel off (S-064, B-104).
  • Trade tooltip mod-id line (added by Mod Menu's mod-id-tooltip feature) now sits at the bottom of the tooltip — below Final: — instead of between the item name and the price breakdown. The extra blank row above Base: was removed so the tooltip layout matches every other vanilla tooltip (S-064, B-105).

Added

  • Jade/WTHIT tooltip for sentry golems showing parent pylon coordinates, despawn countdown, and a "No Drops" indicator (S-048).
  • Small-screen fallback for the villager info panel: when the window is too narrow to fit the side panel, an i icon appears in the merchant screen header and opens the info as a centered overlay (Esc or x to close) (S-049).
  • EMI/REI/JEI trade-index entries now show the workstation block that unlocks the profession as a catalyst slot, and each workstation (lectern, composter, smoker, …) is registered as a recipe catalyst so players can click it to list every trade for that profession (S-043).
  • Sentry Pylon now accepts hopper and modded-pipe input on every face. Hoppers feed iron blocks in one at a time up to the fuel cap, reject non-iron items so mixed inventories don't deadlock, and cannot extract (fuel is consumed, not stored as items). Modded item pipes (Pipez, etc.) work via the Fabric Transfer API. Input pathway is gated on enableSentryPylon (S-057).
  • Wandering traders can now be picked up like villagers — same sneak-right-click + empty-hand interaction, same pickupXpCost, gated by the same enableVillagerPickup config. The despawn timer is frozen while the trader is held as an item and resumes on placement, so players can park traders in known spots without losing them. Each leashed trader llama drops its lead and stops pathing toward the captured trader; llamas are not bundled onto the held item. Traders get biome-themed names on first encounter that persist across pickup/place cycles (S-062).

Removed

  • Double-door / fence-gate sync removed — the feature was out of scope for the villager/trade overhaul and overlaps with dedicated QoL mods. The enableDoubleDoorSync config key no longer exists (S-058).
  • Hotbar / offhand stack refill removed — out of scope for the villager/trade overhaul; overlaps with dedicated QoL mods players already install. The enableStackRefill config key no longer exists (S-058).
  • Village boundary visualization removed — the debug-overlay centroid column, AABB outline, and POI dust markers were out of scope for the villager/trade overhaul and shipped a buggy sky-spire rendering at the village centroid. The enableVillageBoundaryVis config key and /mercantile village command no longer exist (S-059).

Changed

  • Trade-cycling button renamed from "Cycle Trades" to "Re-roll Trades" and redrawn as a labeled text button inside the villager info panel — no more separate icon sprite, and the button is hidden entirely when the villager's profession is locked (S-049).
  • Price-breakdown tooltip (demand transparency) no longer overlaps the trade-cycling button tooltip or the info panel — hit-testing now sits on the trade-offer button itself instead of approximating slot bounds (S-049).
  • Jade/WTHIT villager tooltip slimmed down: breeding state is now a single color-coded line (Ready / Hungry / Needs bed / Cooldown / Growing) with a Food: have/needed progress line only when hungry. Removed the redundant Hungry state icon (the breeding line already covers it) and the Profession: Locked/Unlocked line (lock state lives in the in-game trade screen) (S-051, B-095).
  • EMI/REI/JEI trade-index rows redesigned to a clean three-row layout: icon strip with uniform 20px slot pitch on row 1, trade level on row 2, and a Requires <tier> line on row 3 for reputation-locked trades. Removed the stacked "Sold by" / "Workstation" / tier-badge labels below the strip (the same context is in the slot hover tooltips). The profession head item now shows the profession name on hover instead of vanilla's "'s head" fallback (S-051, B-096).
  • Reputation HUD chip near villagers downscaled to sit more naturally next to vanilla HUD chrome — icon shrinks from 16px to 12px and inner padding tightens, producing a box ~16px tall instead of ~20px. Text remains at vanilla 9px height (S-053, B-100).

Sprint-level breakdowns are tracked in .plan/DONE.md. Story IDs (S-XXX, B-XXX) cross-reference .plan/BACKLOG.md.