The Villager Economy

Wren the scout visits the base with a menu of deals: hand over raw materials for food, buy supplies and rare materials with gold, buy tools and cosmetics, gamble on the Scout's Wager, or convert one material into another. Every deal is priced in data/trades.json, with one shared "exchange rate" tuned in data/balance.json. Here's each trade and its numbers.

In plain terms

The visit popup holds five deal boards, each tuned on its own:

  1. Material-for-food trades — dump cheap dug materials (dirt, clay, stone) straight into the food bar.
  2. Gold trades — spend gold for supplies (food/water) or for materials delivered to inventory.
  3. Tool offers — buy the starter axe/pickaxe with dug materials, or buy higher-tier tools (iron axe/pickaxe, stockable as spares) and dynamite with gold once you can craft them yourself.
  4. Cosmetic offers — buy digger cosmetics with gold.
  5. The Scout's Wager — an optional gold gamble for exotic materials or rare cosmetics.

A sixth board, Material Exchange, isn't in trades.json at all. It prices off a single "efficiency" knob in balance.json plus each material's trade_value (see The Economy Model).

VillagerVisitPopup loads everything below. The values hardcoded in that script are fallbacks only; the JSON is the tuning surface. If the file goes missing or a section is absent, those built-in defaults take over.

Material-for-food trades

File: trades.jsonmaterial_food_trades. Each entry means "cost units of the material buys food_per food." A dirt entry of cost 3, food_per 1 reads in the UI as (3 : 1) and gives 1 food per 3 dirt handed over.

Material Where it lives cost food_per Effect
dirt trades.jsonmaterial_food_trades 3 1 3 dirt → 1 food. The lowest-value dump.
clay trades.jsonmaterial_food_trades 1 1 1 clay → 1 food.
stone trades.jsonmaterial_food_trades 1 2 1 stone → 2 food. The best rate on the board, and the one that keeps the trade alive past depth 27.

The player trades in multiples of cost; food granted is (quantity / cost) × food_per. The steppers snap to whole lots, so a partial lot can never be stranded.

The rate improves with depth, on purpose. Measured in trade_value per food, the ladder runs 3 (dirt) → 3 (clay) → 1.5 (stone). Stone was priced at food_per 1 until September 2026, which put all three on a flat 3 trade-value per food. That read as consistent, but it made stone the worst deal on the board by effort — 5 seconds of digging per food against clay's 2 — and since stone is most of what a digger cuts past depth 27, the whole board went quiet exactly when a run gets dangerous. Doubling stone's payout fixes the late-game deadness without touching the early game, where stone is out of reach anyway.

For scale when tuning: the food bar runs 0–100 and drains 0.04/second, doubled to 0.08/second while working, so 1 food buys 12.5 seconds of digging. Against each material's dig_time that gives a return on effort of 4.2× for dirt, 6.3× for clay, and 5.0× for stone. The competing gold path (5 food for 10 gold) is a flat 2 gold per food.

These three are the player's main hunger safety valve before farms and lodges come online, so nudge gently. Want early food to come easier? Turn cost down or food_per up on dirt or clay — stone won't move the early game either way.

One thing this board does not do: the Trading skill multiplier and the Silver Tongue capstone apply only to the Material Exchange, never to these food ratios (see Skill and class modifiers). A maxed Merchant hands over the same 3 dirt as a day-one digger.

Gold trades

File: trades.jsongold_trades. type: "supply" pours the reward straight into the food or water bar; type: "item" delivers the material to inventory. gold_cost is the price for gives_amount units.

Gives Where it lives gives_amount gold_cost type Notes
food trades.jsongold_trades 5 10 supply Emergency food top-up.
water trades.jsongold_trades 5 10 supply Emergency water top-up.
wood trades.jsongold_trades 20 15 item Bulk surface fuel/building stock.
coal trades.jsongold_trades 20 20 item Bulk mid-tier fuel.
deep_coal trades.jsongold_trades 8 40 item Higher-grade fuel.
strange_root trades.jsongold_trades 5 25 item Only appears during the Black Rot challenge (challenge: black_rot). Hidden in normal runs.
iron trades.jsongold_trades 2 25 item Buy your way past an iron shortage.
ancient_clay trades.jsongold_trades 1 220 item Exotic; premium price.
prismatic_shard trades.jsongold_trades 1 380 item Exotic; premium price.
void_iron trades.jsongold_trades 1 450 item Exotic; premium price.
ember_essence trades.jsongold_trades 1 600 item Exotic; the most expensive single buy.

Add a challenge key to gate any gold trade to a challenge, the way strange_root does. Without that key the trade is always offered. Raise the exotic prices and gold becomes a slower route to post-Astrolabe materials; lower them and a gold-rich player can skip mining for them.

Tool offers

File: trades.jsontool_offers. Wren's tool board sells two kinds of goods: starter tools bartered for dug materials (one-time), and gold-priced tools/consumables that appear once the player could craft them and are bought by quantity up to a stack cap.

Tool Where it lives Price Kind Gate
Axe (axe) trades.jsontool_offers 30 dirt, 10 clay one-time barter always shown
Pickaxe (pickaxe) trades.jsontool_offers 50 dirt, 25 clay one-time barter always shown
Iron Axe (iron_axe) trades.jsontool_offers 500 🪙 each up to 5 spares (→ ToolState) recipe iron_axe unlocked
Iron Pickaxe (iron_pickaxe) trades.jsontool_offers 750 🪙 each up to 5 spares (→ ToolState) recipe iron_pickaxe unlocked
Dynamite (dynamite) trades.jsontool_offers 250 🪙 each repeatable (→ Inventory), capped to max_stack (5) recipe dynamite unlocked

Optional fields on a tool_offer:

All gold consumers on the visit board — gold trades, gold tools, and consumables — draw on one shared gold budget, so no combination of selections can overspend when the player hits TRADE. Mining charge is deliberately not sold here; it stays craft-only so it remains a progression reward.

The starter barter offers are a fallback path to the axe/pickaxe for a player who hasn't crafted them, so keep those costs in cheap surface materials. The gold prices are pure sinks — raise them if gold is flowing too freely, lower them to make the shortcut cheaper.

Cosmetic offers

File: trades.jsoncosmetic_offers. Gold-priced digger cosmetics. Ownership is account-wide — it lives in config.json, not the save slot — so a player buys each of these once across all runs. The whole board disappears once the player owns everything on it (nothing left to sell).

Cosmetic id Where it lives gold_cost Notes
tunic_furtrim trades.jsoncosmetic_offers 400 "Fur-trimmed Tunic". Body garment, no effect.
tunic_robe trades.jsoncosmetic_offers 350 "Robe". Body garment, no effect.
boots_ironshod trades.jsoncosmetic_offers 300 "Iron-shod Boots". Footwear, no effect.
extra_gloves trades.jsoncosmetic_offers 2500 "Berry-picking Gloves". The only ware on this board that carries gameplay traits: berry_speed_mult 1.6 (+60% picking speed) and berry_yield_mult 1.2 (+20% food per harvest), both in cosmetics.jsoneffect.
dye_slate trades.jsoncosmetic_offers 200 A dye.

The id must match an entry in cosmetics.json, and the row label is that entry's name — so a rename in cosmetics.json changes what Wren's board reads. Any traits on the item are printed as a line beneath the name, so a priced ware explains itself before the player commits the gold. gold_cost is pure sink pricing for the looks; where a cosmetic also carries an effect, that effect is the real reason to save for it. These were repriced up (from 20–1000 gold) once gold started flowing freely enough that the old prices meant little.

On the gloves' two traits. Picking speed is the weaker half by a wide margin: a bush holds 20 berries and then rests a full day, so the +60% saves a few seconds per bush cycle while bush stock and regrowth set the real ceiling. The yield multiplier raises that ceiling instead — it scales the food granted, never the berries deducted (scaling the deduction would strip bushes faster for the same total, a net zero). Tune the yield figure if the gloves feel over- or under-priced at 2500; the speed figure barely moves the needle.

The Scout's Wager

File: trades.jsonwager. An optional once-per-visit gold gamble. A win returns an exotic material or, some of the time, a rare wager-exclusive cosmetic. A loss returns a small "consolation" pile of common materials, so the stake is never a total loss.

Wager tuning values

Setting Where it lives Default What it controls
cost trades.jsonwager 25 Base ante in gold (the starting stake before population scaling).
cost_pop_interval trades.jsonwager 50 Every this-many of peak population adds one price step.
cost_step_first trades.jsonwager 5 Gold added by the first price step.
cost_step_growth trades.jsonwager 1 Extra gold each later step adds on top of the previous one.
success_chance trades.jsonwager 0.05 Win chance before the first Astrolabe ritual (5 in 100).
success_chance_post_astrolabe trades.jsonwager 0.15 Win chance once the ritual has seeded exotics (15 in 100).
cosmetic_chance trades.jsonwager 0.6 On a win, the share that pays a rare cosmetic instead of an exotic — but only while un-owned wager cosmetics remain; after that a win is always an exotic.

How the ante scales. Each visit re-derives the effective stake from the run's peak (high-water) population, so it never drops when villagers are lost. With n = peak population ÷ cost_pop_interval, the cost is cost + n × cost_step_first + cost_step_growth × (n−1) × n ÷ 2. On the defaults that runs 25 → 30 → 36 → 43 … as population crosses each 50-villager mark. Worn "luck" cosmetics like the Lucky Amulet, the Trading capstone Silver Tongue, and the Chieftain wager handicap all multiply the win chance on top of the base rate (see Skill and class modifiers below).

Wager prize pools

Pool Where it lives Contents
exotic_pool trades.jsonwager ember_essence, void_iron, ancient_clay, prismatic_shard — the four exotics a pre-ritual win can return.
exotic_pool_post_astrolabe trades.jsonwager The four above plus root_amber, pale_chalk, wavellite, magnetite, obsidian, chromite — ten exotics once the ritual has seeded the world. The larger pool is why the post-ritual win rate is raised: any one specific exotic stays about as findable.
consolation_pool trades.jsonwager The common-material payouts on a loss, each with a min/max count (see below).

Consolation pool (loss payout). Each entry pays a random amount between min and max.

Material min max
stone 8 15
iron 3 8
wood 5 12
coal 4 10
clay 6 14
quartz 2 5
fossil 1 3
strange_root 1 2
deep_coal 2 4
limestone 4 10

One wager-only constant lives outside the JSON: the dice-reveal animation delay (WAGER_REVEAL_DELAY, 2.6 seconds) is a script constant in VillagerVisitPopup, pure presentation. Everything that touches odds or payouts sits in trades.json.

Material Exchange efficiency

The Material Exchange board converts one dug material into another at a loss. It isn't in trades.json; it prices off each material's trade_value and one efficiency knob.

Setting Where it lives Default What it controls
basic_efficiency balance.jsontrading 0.45 The Wren-visit exchange rate. Output = floor(input_qty × trade_value_in ÷ trade_value_out × 0.45 × trade_mult). A player recovers about 45% of the value they put in, before any skill/class multiplier.
astrolabe_efficiency balance.jsontrading 0.85 The Astrolabe machine's auto-trade rate (read by MachineController, not the Wren popup). The machine converts far more efficiently than a scout visit — about 85% of value.
astrolabe_auto_interval balance.jsontrading 30.0 Seconds between the Astrolabe machine's automatic conversions.

trade_value for each material lives in materials.json (Materials and Mining Yield). Both efficiencies multiply that value, so editing one material's trade_value shifts every exchange and every price anchored to it. Turn basic_efficiency up and hand exchanges get more generous, closer to break-even. Turn it down and mining the right material directly beats converting.

Skill and class modifiers

On top of the JSON prices, the run's Trading skill and chosen class shift trade value and wager luck. These are skill-system knobs, not trades.json values — the tuning lives in balance.json → skills and the capstone magnitudes are code constants. Full detail in Skills, Classes, and Handicaps.

Modifier Source Effect Where applied
Trading skill bonus balance.json → skills node ladder Multiplies the material-exchange trade_mult by 1.0 + node bonus (up to +45% at node 5, +75% for a Merchant champion at node 7). VillagerVisitPopup._calc_exchange
Silver Tongue (Trading capstone, node 5) code constant Adds a flat +0.25 to the trade multiplier and multiplies Scout's Wager luck by ×1.25. Shared — any run that trains Trading to node 5 earns it. VillagerVisitPopup (exchange + wager)
Chieftain handicap class_info.chieftain.handicap.mults The Chieftain has "no head for coin": trade value ×0.85 (−15%) and wager luck ×0.50 (−50%). The wager hit is the deeper of the two because it's dodgeable (a Chieftain who never wagers pays nothing). Applied after the skill bonus, so even a Chieftain who trains Trading trades below par. SkillManager.class_penalty("trade") / ("wager")

Every modifier in this table reaches the Material Exchange and the Wager only. The material-for-food ratios and the gold prices are flat for every class and every skill level.

The Merchant is the trade specialist (champion of Trading, no trade penalty, and the trade-value strength), while the Chieftain is its deliberate opposite — strong village growth bought with weak trades and wagers. Silver Tongue stacks additively with the Trading skill's bonus, then the Chieftain penalty (if any) multiplies the result.

Safe to change or handle with care

Any edit to trades.json or balance.json needs the data validator and a smoke test before it ships — see The Safe Change Workflow.