You are viewing a potentially older version of this package. View all versions.
expDARE-Barter-0.1.2 icon

Barter

ExtraPotions Meadworks trader overhaul: per-trader buy and sell lists, custom currencies, a trader purse that moves prices, and a sell list. Required on all peers.

Date uploaded 4 days ago
Version 0.1.2
Download link expDARE-Barter-0.1.2.zip
Downloads 29
Dependency string expDARE-Barter-0.1.2

This mod requires the following mods to function

ValheimModding-Jotunn-2.30.2 icon
ValheimModding-Jotunn

Jötunn (/ˈjɔːtʊn/, 'giant'), the Valheim Library was created with the goal of making the lives of mod developers easier. It enables you to create mods for Valheim using an abstracted API so you can focus on the actual content creation.

Preferred version: 2.30.2
denikson-BepInExPack_Valheim-5.4.2351 icon
denikson-BepInExPack_Valheim

BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.

Preferred version: 5.4.2351
expDARE-Crucible-0.3.32 icon
expDARE-Crucible

Meadworks shared library: product registration, server authority, the shared interface kit, localization and logging. Adds no gameplay. Required on all peers.

Preferred version: 0.3.32

README

Barter

Traders you can shape: per-trader buy and sell lists, custom currencies, prices that follow the trader's purse, and a sell list built on the Meadworks interface kit.

Version 0.1.2. Requires Crucible 0.3.28 / Crucible.UI 0.3.20. Changes are in CHANGELOG.md.

Features

  • Trade lists: write what each trader sells (Buy lists) and what each trader pays for (Sell lists) in YAML, JSON or CSV. Lists can name a lot size, a price, a quality, a currency, and the world keys or player keys that decide when an entry is offered. A common list applies to every trader.
  • Currencies: pay in any item. A trader can have its own currency, and an entry can name another one.
  • Trader purse: Haldor, Hildir and the Bog Witch (and traders you add) have a balance that falls when they pay you, rises when you buy, and refills each morning. A poor trader charges more and pays less; a rich one the opposite. The purse and what it does to prices show beside the trader's window.
  • Sell list: a list beside the trader's window of what you carry that the trader pays for, with a filter, the lot size and quality, the price and its currency, and a Sell button. Worn and hotbar gear stays out of the list by default. With the sell panel turned off in the settings, the game's own Sell button works as in vanilla.
  • Discovery: a trader does not offer items you have not discovered yet, unless you list them as always offered.
  • The lists are checked as a whole: a file with a mistake is rejected with a message and the previous lists stay in force.

The mechanics follow shudnal's TradersExtended (public domain), so lists written for it read here unchanged. Barter's panels, settings, server authority and text come from Crucible.

How trades are settled

  • The server checks every trade: price, currency, lot, quality, world keys and how close you stand to the trader. Two players trading with the same trader at once are served one at a time, and a repeated request is refused.
  • Trader purses live in authenticated files on the server. Remote trades use trusted cooperative accounting: the server verifies the price and trusts the connected client's reported inventory outcome, like Valheim's client-owned inventories. A successful purchase credits the purse, a sale debits it, and a reported failure refunds a reserved sale debit, each once. A modified client can lie about its outcome; authenticated receipts do not prove inventory changes. Duplicate reports cannot settle again. If no report arrives within 120 seconds, the reservation unlocks with its debit retained; later reports cannot credit or refund it.
  • Before your inventory changes, Barter writes the trade down. If the game or the connection drops in the middle of a trade, your next visit settles it without repeating the item change. A trade whose outcome is not known stays blocked with its record kept; use Resolve pending trade in Trader Services to ask the server to settle it.
  • A purchase needs free inventory slots after paying, and a sale needs room for the payment; the Sell button is disabled when the payment would not fit.
  • Equipped gear and protected extra-slot items are never taken as payment or sold. Hide Equipped Items also controls the hotbar filter; turn it off to let unequipped hotbar gear appear.
  • Trader Services (from the purse card, or the controller's Y button) holds buyback, paid repairs and pending-trade recovery. Buyback and paid repairs work only for the host's own character, because a server cannot see another player's inventory. Hosts and admins can edit the lists in game; an edit made against an older copy of a list is refused.
  • Purchases that pay in keys or inventory rows, and offers gated on another player's personal keys or discoveries, are refused where the server cannot check them.

Requirements

  • BepInExPack Valheim 5.4.2351
  • Jotunn 2.30.2
  • Crucible 0.3.28 or a later 0.3.x, which includes Crucible.UI 0.3.20 (the shared Meadworks interface kit)

Installation

  • Mod manager (recommended): install Barter with r2modman, Gale or the Thunderstore Mod Manager; the dependencies above are installed for you.
  • Manual: install BepInExPack Valheim, then Jotunn and Crucible, then copy the plugins/Barter folder from this package into BepInEx/plugins/.
  • Install Barter on the server too, and on every client.

Trade lists

The first time Barter runs (when no Barter list file exists) it writes seven files to BepInEx/config/: Barter.common.Buy.yml, an explained example with every entry commented out, and a buy and sell list each for Haldor, Hildir and the Bog Witch. They keep the game's own stock of all three traders. Haldor's buy list adds a few raw materials (some behind boss keys); Hildir's and the Bog Witch's buy lists are empty for you to fill; each trader's sell list pays a modest price per lot for materials (hides, metals, swamp ingredients). Trophies and valuables are not listed because they already sell at the game's own value through Common Valuables. The shipped prices are Barter's own modest scale. Edit or delete any file; nothing is written again while a Barter list file exists. Barter reads these files, and reads them again within a couple of seconds whenever one changes:

  • BepInEx/config/Barter.<trader>.<Buy|Sell>[.<anything>].<yml|yaml|json|csv>, for example Barter.Haldor.Buy.yml, Barter.common.Sell.csv or Barter.Hildir.Buy.food.yml.
  • Any file in the folder BepInEx/config/Barter/ named <trader>.<buy|sell>[.<anything>].<extension> without the Barter. prefix, for example haldor.buy.json. This is how TradersExtended names its files, so you can copy its lists there.

All files of the same trader and kind are added together in file name order. common lists apply to every trader first; a trader's own entries follow, and in a Sell list a trader's entry replaces a common one for the same item, quality and lot size. Trader names are the trader's prefab name without case: Haldor, Hildir, BogWitch.

# Barter.Haldor.Buy.yml
- prefab: DragonEgg
  price: 500
  requiredGlobalKey: defeated_dragon
- prefab: RawMeat
  stack: 10
  price: 2
  currency: Ruby

Every field except prefab is optional: stack (items per lot, default 1), price (per lot, default 1), quality, currency, requiredGlobalKey and notRequiredGlobalKey (comma lists of world keys), requiredPlayerKey and notRequiredPlayerKey (comma lists of player keys). In a Buy list quality is the quality you get; in a Sell list it is the quality the price is for (0 for any). An entry with a price or a lot below one is skipped with a warning. A JSON list is read as YAML, which is a superset of JSON. A CSV list has a header row with at least prefab.

Configuration

  • Settings file: BepInEx/config/com.meadworks.barter.cfg (Barter 0.1.1 and earlier used com.extrapotions.barter.cfg; its values are carried over on the first start and the old file is kept as com.extrapotions.barter.cfg.bak). Edit it in game with Almanac (the Meadworks settings book) or any ConfigurationManager.
  • Trader Purse: on by default for every trader that has a Barter list (Haldor, Hildir and the Bog Witch with the shipped lists, the Custom Traders setting, and any trader you write a list for); traders from other mods without a list keep the game's prices. Settings: on or off, flexible pricing, minimum and maximum balance, daily increase and decrease, discount and markup, refill interval and the morning message.
  • Trade Lists: sell only discovered items, items always offered, remove the game's items or other mods' items from buy lists, quality price multiplier for sold gear, common valuables (every valued item sells at its value), custom traders and trader currencies (Haldor:Coins,Hildir:SilverCoin).
  • Interface: the sell panel, the purse card and hiding worn gear are your own choices.
  • In multiplayer the server's values win for everything that shapes a trade, and those settings show as read-only on your side.

Multiplayer

  • Required on all peers: install it on the server and on every client, same major.minor version. Trader lists and currencies change shared rules, so the server's lists and settings are the ones in force for everybody; lists on a client's own disk are ignored while it is on a Barter server.
  • Trader purses are shared and stored in authenticated files alongside the world: Barter.Authority/<world UID>/ inside a chunked world directory, or <world>.db.Barter.Authority/<world UID>/ beside a legacy world database. Cloud worlds use the game's cloud storage backend. Include the entire authority directory and its key when backing up or transferring a world; native backup/conversion tools can omit additional directories. Existing records under BepInEx/config/Barter.Authority/ are authenticated and copied without deleting the original. Trader ZDO values are display mirrors. The server refills purses each morning.
  • A missing authority key on an existing world stops trading rather than creating a fresh purse. Restore the matching authority directory from backup. To deliberately initialize an otherwise empty authority directory, place a file named allow-new-authority-key containing the exact world UID in its UID directory. Existing records without their matching key still require restoration. Interrupted writes recover valid pending records or backups and retain damaged files as quarantine evidence.
  • Joining a server without Meadworks: Crucible waits for the server's reply (10 seconds by default), then treats it as a vanilla server; Barter turns off for that session.
  • Cheats: Barter 0.1.0 has none. A cheat added later would be controlled by the server's admins like the other Meadworks products.

Replaces / compatibility

  • Step-aside: with TradersExtended installed, Barter stays off and says so once. Barter reads TradersExtended list files, but not its per-trader settings files or its editor.
  • Existing unsigned trader balances are preserved as migration evidence, but cannot become trusted balances automatically. A fresh authority ledger uses the configured initial balance.
  • Still deferred: changing the coin item and buying several lots at once.
  • Version 0.1.0 was tested in a hosted game and on a dedicated server with two clients. Not tested side by side with other trader mods.

Compatibility & notes

  • Languages: English, Spanish, Simplified Chinese, Russian, French, German and Korean, including setting names and help. List-file comments stay English; translations await a native review.
  • Listed under Thunderstore's AI Generated category; tested in-game.
  • Based on: TradersExtended 2.0.5 by shudnal (Unlicense).
  • Source: https://github.com/ExtraPotions/Meadworks/tree/main/Barter

Changelog

See the Changelog tab (CHANGELOG.md).

License

Code: GPL-3.0-or-later (LICENSE-CODE.md, licenses/GPL-3.0.txt). Original documentation: CC BY-NC-SA 4.0 (LICENSE-ASSETS.md). Adopted public-domain source and its notice: licenses/Unlicense-TradersExtended.txt, SOURCE_NOTICE.md, LICENSE_SCOPE.md. Product author: expDARE.

CHANGELOG

0.1.4

  • Restore native currency when a trader currency prefab is unavailable.
  • Guard trader world snapshots during scene teardown.

Changelog

Unreleased

  • If legacy settings cannot be copied, initialization stops before saving defaults and retries on the next start. Existing settings and backups are preserved.

  • Reuse proven authority-record paths during receipt scans and direct reads. Every fresh key read, record authentication, recovery and durable prune remains in place.

  • Read small authority records without allocating the full 4 MB size limit. File bounds, authentication and durable trade/refill writes remain enforced.

  • Resolve repeated world prefabs once per morning purse-refill pass. Each trader's current rules, pending balance and durable refill commits are still checked separately.

  • 0.1.3: Add Debug-only morning refill timing for the world scan, authenticated authority reads and writes, local and cloud storage, forced flushes and cloud completion. Refill rules, durable commits and the morning trigger are unchanged.

0.1.2 (2026-10-22)

  • 0.1.2. Barter is now a MeadWorks plugin everywhere: its plugin ID is com.meadworks.barter (was com.extrapotions.barter). Almanac lists it under Meadworks, and Crucible treats it like every other MeadWorks product.
  • Your settings carry over. On the first start, com.extrapotions.barter.cfg is copied to com.meadworks.barter.cfg and the old file is kept as com.extrapotions.barter.cfg.bak. An existing com.meadworks.barter.cfg is never overwritten. Trade lists, purse data and trade receipts keep their files.
  • Update every player and the server together: a 0.1.1 client and a 0.1.2 server (or the reverse) do not see the same plugin ID and cannot join.

0.1.1 (2026-10-21)

  • 0.1.1. The sell list stays on screen at 800x600, 1280x720, 1600x900 and 1920x1080. It sits to the right of the store when that fits, otherwise to the left, otherwise below, and it does not cover the purse. It moves again when the resolution changes while the store is open. Requires Crucible 0.3.28 / Crucible.UI 0.3.20.

0.1.0 (2026-10-21)

  • First release. Requires Crucible 0.3.27 / Crucible.UI 0.3.20.
  • Per-trader buy and sell lists in YAML, JSON or CSV (TradersExtended lists read unchanged), custom currencies, a trader purse that moves prices and refills each morning, and a sell list beside the trader's window. Default lists for Haldor, Hildir and the Bog Witch.
  • Server-checked trades with a server purse ledger, a trade journal that survives a crash or disconnect, Resolve pending trade, buyback, paid repairs, price tips, an in-game list editor for hosts and admins, per-trader policies and controller navigation.
  • Checked in the game: hosted two-player 17/17 and dedicated server with two clients 15/15 (trades, full inventory, concurrent trades, editor, reconnect, store close and reload, lost sale and buy reports, crash recovery, old character profile restore, a trader spawned by a client, Hildir and the Bog Witch), then receipt-marker pruning on a hosted game and a dedicated server.
  • The trader purse stays on screen. It keeps its place to the left of the store when that fits, and moves to the right of the sell list, or below the store, when the left side would run off the screen.

Development history:

  • Prune character receipt markers after the authority has acknowledged the trade and its journal entry is gone, once the authority session or the sale's buyback day no longer needs them. Keep at most the newest 64 retired markers, and prune markers already stored on existing profiles when the character loads.
  • Use trusted cooperative purse accounting for remote trades at server-verified prices: credit successful buys, keep one sale debit and refund a reported failure once. Preserve duplicate receipt handling and timeout quarantine; remote buyback and repairs still require authority inventory checks.
  • Save completed trade receipts with the character before returning, bind markers to the authority quote, and retain consumed evidence on save failure. Old or ambiguous profiles never receive the same payout again through recovery.
  • Stop unresolved receipts from serializing inventory every frame. Remove the 4,096-reservation session cutoff, rotate settled receipts from prior sessions, and count recovery capacity separately for each world.
  • Verify trader identities against server-known, allowlisted spawn anchors before reading authority state. Keep authenticated state alongside the world, migrate existing records, and recover interrupted writes from valid pending files or backups.
  • Translate all purse, list and interface settings in all seven languages. Refuse list drafts that exceed the encoded transport limit before sending, and explain unavailable remote buyback before a sale.
  • Validate dedicated-server trades against the trader ZDO position and registered prefab stock, using that ZDO's authoritative purse for current prices without requiring a live trader instance.
  • Track Barter's store open/close state through logout and isolate UI refresh failures from host list publication.
  • Check sale payout room before reserving the trader's purse and disable Sell when payment cannot fit. Preserve space freed by sold stacks and show the existing recovery reason on blocked trades.
  • Populate native offer names, icons, tooltips and reward/key fields so StoreGui can open and reload its list safely. Keep native full item tooltips and add deletion/default-regeneration coverage.
  • Version item snapshots with a byte header and preserve Int32 world levels, including existing version-1 snapshots and their inventory evidence comparisons. Preserve world levels above 255 when creating purchased items.
  • Finalize authenticated remote finish reports immediately and unlock the trader without waiting for timeout. Retain the existing restriction against unverified purse credits, refunds or buyback escrow; only missing reports need the 120-second quarantine.
  • Add Resolve pending trade in Trader Services. Ask the authority to reconcile the receipt and retry proven outcomes without repeating item changes; keep uncertain mutation records and character-save evidence.
  • Name Burrow inventory holds in trade refusals and add recovery text in all seven languages. Include full reload exception traces for any remaining native failure. Keep the plugin ID unchanged to preserve configurations.
  • Declare reserve, finish and list-edit operations at Crucible's remote protocol 1.0 so Barter modules can start. Test the production descriptors against the built Crucible.Core registry with the real peer transport version, including rejection of the old declarations.
  • Reserve and hide canonical buyback escrow before a permit instead of deleting it. Consume it only after verified success; verified rollback clears the reservation, while unknown outcomes keep item evidence past expiry. Explain the local-host-only service limit and disable remote offers, with text in all seven languages.
  • Correct authority settlement: a remote success/failure report cannot credit/refund the shared purse or mint buyback escrow. Retain remote sale debits; confirmed reports release trader serialization immediately, and genuinely missing reports release it after 120 seconds without inventing an outcome. Remote purchases do not replenish the purse, and remote buyback/paid repair remain unavailable pending a verifiable inventory participant.
  • Store canonical world/trader purse, escrow and receipt state in server files authenticated with a server-only HMAC key. Ignore unsigned ZDO balances/escrow as authority input and preserve legacy bytes as migration evidence.
  • Retain completed journals until loaded character-save evidence confirms persistence; reconcile only exact before-images or matching loaded markers, retain uncertain mutation records and treat receipt mismatch as nonterminal. Persist per-token settlement outcomes to prevent replay after intervening trades.
  • Run native store close checks before custom focus handling, keep a single Barter window/input owner and use the established kit art for sell rows. Preflight sale payloads against the 16,384-byte operation cap, including finish overhead, with an oversized-data refusal translated in all seven languages.
  • Add trader/player-bound buyback escrow, paid repairs, server-priced item tips and a Crucible.UI list editor with server authorization, revision checks and durable file replacement. These paths remain development candidates pending native acceptance.
  • Add validated per-trader policies and explicit configuration conversion, optional inventory-slot protection and controller navigation for the sell list and trader services. Preserve existing configuration keys and local preferences under server overlays.
  • Persist interrupted trade evidence before inventory mutation and validate settlement against the reserved quote fingerprint. Ambiguous outcomes remain blocked for reconciliation; independent player/world saves are not atomic.
  • Route list and native item trades through checked stack exchanges and authenticated server purse reservations. Refused removals, partial deliveries and full inventories compensate exact owned changes; uncertain inventory results block further exchanges for recovery.
  • Replace client purse ownership claims with a canonical server ledger and a legacy display mirror. Revalidate price, currency, lot, quality, world requirements and sender proximity; serialize concurrent trades and reject replayed reservations.
  • Preserve the native first-valuable-stack action when the sell panel is hidden. Native key/inventory-row rewards and remote personal discovery/key requirements fail closed until their authority and recovery paths are qualified.
  • Add a translated trade refusal message in all seven languages and an explicit dry-run list importer that preserves source files and refuses overwrites or invalid lists.

Scaffold (2026-10-09):

  • First scaffold, 2026-10-09: repository, Barter.Core with 183 portable tests, Barter.Plugin that builds against Crucible 0.3.12 and Crucible.UI 0.3.7, seven localization catalogs (English plus six translations), README, notices and provenance record.
  • Adopted from TradersExtended 2.0.5 (shudnal, Unlicense): the list model and file names, CSV reading, availability rules, currency rule, price curve, purse refill, lot arithmetic and sell offer grouping; the trader hooks, purchase and sale flow and panel layout were written with the upstream as reference.
  • New: lists synchronized from the server through Crucible and hot reloaded, YAML and JSON reading, the list set rejected as a whole on a mistake, quality and currency kept in a side table, the purse card and the sell panel on the Crucible.UI kit, step-aside when TradersExtended is installed.
  • Default lists written on first run for Haldor, Hildir and the Bog Witch (buy and sell), checked by a test that they parse cleanly and name only vanilla items (against the game's item manifest when VALHEIM_DIR is set). The trader purse is on by default for every trader with a Barter list; unlisted modded traders keep vanilla prices.
  • Not run in the game yet. The package icon is a coin purse, drawn in code in the Meadworks icon style (approved 2026-10-10).