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:
- Material-for-food trades — dump cheap dug materials (dirt, clay, stone) straight into the food bar.
- Gold trades — spend gold for supplies (food/water) or for materials delivered to inventory.
- 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.
- Cosmetic offers — buy digger cosmetics with gold.
- 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.json → material_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.json → material_food_trades |
3 |
1 |
3 dirt → 1 food. The lowest-value dump. |
clay |
trades.json → material_food_trades |
1 |
1 |
1 clay → 1 food. |
stone |
trades.json → material_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.json → gold_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.json → gold_trades |
5 |
10 |
supply |
Emergency food top-up. |
water |
trades.json → gold_trades |
5 |
10 |
supply |
Emergency water top-up. |
wood |
trades.json → gold_trades |
20 |
15 |
item |
Bulk surface fuel/building stock. |
coal |
trades.json → gold_trades |
20 |
20 |
item |
Bulk mid-tier fuel. |
deep_coal |
trades.json → gold_trades |
8 |
40 |
item |
Higher-grade fuel. |
strange_root |
trades.json → gold_trades |
5 |
25 |
item |
Only appears during the Black Rot challenge (challenge: black_rot). Hidden in normal runs. |
iron |
trades.json → gold_trades |
2 |
25 |
item |
Buy your way past an iron shortage. |
ancient_clay |
trades.json → gold_trades |
1 |
220 |
item |
Exotic; premium price. |
prismatic_shard |
trades.json → gold_trades |
1 |
380 |
item |
Exotic; premium price. |
void_iron |
trades.json → gold_trades |
1 |
450 |
item |
Exotic; premium price. |
ember_essence |
trades.json → gold_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.json → tool_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.json → tool_offers |
30 dirt, 10 clay |
one-time barter | always shown |
Pickaxe (pickaxe) |
trades.json → tool_offers |
50 dirt, 25 clay |
one-time barter | always shown |
Iron Axe (iron_axe) |
trades.json → tool_offers |
500 🪙 each |
up to 5 spares (→ ToolState) |
recipe iron_axe unlocked |
Iron Pickaxe (iron_pickaxe) |
trades.json → tool_offers |
750 🪙 each |
up to 5 spares (→ ToolState) |
recipe iron_pickaxe unlocked |
Dynamite (dynamite) |
trades.json → tool_offers |
250 🪙 each |
repeatable (→ Inventory), capped to max_stack (5) |
recipe dynamite unlocked |
Optional fields on a tool_offer:
gold_cost(int) — price the offer in gold instead of dug materials, sold with a− N +quantity stepper. A persistent tool (iron_axe/iron_pickaxe) is bought as spares routed toToolState, up toTOOL_MAX_STACK(5) minus the count already owned;add_toolruns once per spare (auto-equipping if it beats the current tool, the rest waiting as full-durability reserves). Because a tool that breaks decrements the owned count and swaps in a fresh spare, the player re-buys as they wear out. A consumable is a quantity buy routed toInventory.consumable(bool) — the offer is a stackable item (dynamite) rather than a tool; capped so a purchase can't push past the material'smax_stack.gate_recipe(string) — hides the row until that recipe is unlocked (CraftingUnlockManager.is_unlocked), i.e. once the player has seen its inputs. Gold thus shortcuts the grind, not the progression. Nogate_recipe→ always shown.
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.json → cosmetic_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.json → cosmetic_offers |
400 |
"Fur-trimmed Tunic". Body garment, no effect. |
tunic_robe |
trades.json → cosmetic_offers |
350 |
"Robe". Body garment, no effect. |
boots_ironshod |
trades.json → cosmetic_offers |
300 |
"Iron-shod Boots". Footwear, no effect. |
extra_gloves |
trades.json → cosmetic_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.json → effect. |
dye_slate |
trades.json → cosmetic_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.json → wager. 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.json → wager |
25 |
Base ante in gold (the starting stake before population scaling). |
cost_pop_interval |
trades.json → wager |
50 |
Every this-many of peak population adds one price step. |
cost_step_first |
trades.json → wager |
5 |
Gold added by the first price step. |
cost_step_growth |
trades.json → wager |
1 |
Extra gold each later step adds on top of the previous one. |
success_chance |
trades.json → wager |
0.05 |
Win chance before the first Astrolabe ritual (5 in 100). |
success_chance_post_astrolabe |
trades.json → wager |
0.15 |
Win chance once the ritual has seeded exotics (15 in 100). |
cosmetic_chance |
trades.json → wager |
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.json → wager |
ember_essence, void_iron, ancient_clay, prismatic_shard — the four exotics a pre-ritual win can return. |
exotic_pool_post_astrolabe |
trades.json → wager |
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.json → wager |
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.json → trading |
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.json → trading |
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.json → trading |
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
- Material-for-food
cost/food_percompounds against the whole survival economy. Cheap food here can trivialize the early hunger loop. Move in single steps and feel-test. Dirt and clay are the early-game knobs; stone only reaches a player past depth 27, so it tunes the late game alone. Watch stone especially against its crafting demand — 27 recipes want 321 units of it across a run, and it is the one food material the player also needs for tools. success_chance/success_chance_post_astrolabeare per-roll odds. Small raises feel large across a long run. Keep the post-ritual value above the pre-ritual one so the wager stays worth playing after the pool grows to ten exotics. Remember Silver Tongue and luck cosmetics multiply these, so the effective ceiling is above the JSON number.basic_efficiencyis one multiplier on every hand exchange in the game. Change it and all material-to-material conversions shift at once. The Trading skill and Silver Tongue stack on top of it, so a maxed trader already recovers well above 45%.- Exotic
gold_costvalues are the gold escape hatch for post-Astrolabe materials. Set them too low and gold farming replaces deep mining. - Gold
tool_offersprices (iron axe/pickaxe, dynamite) are gold sinks that also shortcut the tool grind. The iron tools are stockable up to 5 spares, so a full restock is 5× the listed price; too low and gold hoarding replaces crafting. Thegate_recipekeeps them from appearing before the player could craft the item anyway. berry_yield_multon the gloves (cosmetics.json, default1.2) is a permanent, account-wide food multiplier on every bush the player ever picks. It is bounded by bush stock and regrowth, so it scales gently, but it never expires — treat it like a survival knob, not a cosmetic one.
Any edit to trades.json or balance.json needs the data validator and a smoke test
before it ships — see The Safe Change Workflow.