Skip to main content

WHERE THESE NUMBERS COME FROM

Nothing on this site is copied off another trading page. All 258 trades are read out of the data files Minecraft ships inside its own client, compared row by row against what this site says, and re-checked every morning. Last run on , against Java 26.2 and Bedrock 1.26.30.5.

The Java source

Mojang publishes a version manifest at launchermeta.mojang.com. The checker takes the newest release from it, downloads that client jar, and reads three sets of files out of it:

The last of those is xp, the trading XP a villager earns per use, and it is the number behind every line on this site about levelling one up. It carries a trap worth naming: 176 of the trades here state it and the rest leave the field out, which is not the same as paying nothing. VillagerTrade.CODEC declares it lenientOptionalFieldOf("xp", ConstantValue.exactly(1)), so a silent file means one point. That default is read out of the class itself, and the checker stops rather than publishes if it ever moves.

Since 26.2 these are plain data files rather than numbers buried in code, which is what makes a check like this possible at all. Anyone with the client jar can open the same files and get the same answer.

The Bedrock source

Bedrock has no jar to open, so the second edition is read from Mojang's own bedrock-samples repository, at the tagged release matching 1.26.30.5. Java is what this site describes; Bedrock is only used to name a difference. 3 trades really do differ between the editions, and those rows say so instead of picking a side.

The pack holds more than the trades themselves, so four things about Bedrock are checked here rather than described from memory. num_to_select on each group says how many of that group's offers a villager draws, which is where the Bedrock chance under every Java one comes from: Bedrock splits a tier into groups and draws from each, so it disagrees with Java on 116 of the 170 trades both editions state a draw for. total_exp_required gives the trading XP each tier costs, and every one of the 13 professions asks for the same 10, 70, 150 and 250 Java does. price_multiplier is the same field Java calls reputation_discount, which is how the cure page can say the two editions price a cure identically on 171 trades and differently on the 6 maps the cartographer sells. And trader_exp is Java's xp under another name, so what a trade pays the villager can be compared too: the two editions agree on 169 of the 173 trades that state it in both, and disagree on 4, which the tables say row by row.

What is still not readable there is code. How often a Bedrock villager restocks, what a cure is worth in reputation, how the discount spreads through a village: none of that is in the pack, so none of it is claimed as checked anywhere on this site. The pack also carries reward_exp, which sits next to trader_exp and looks like a match for it. It is not: it is a true or false about the player's own experience orbs, and Java ships nothing in its data to hold that against, so it is read nowhere on this site.

What each mark means

The mechanics numbers

How often a villager restocks, what a tier costs in XP and what curing a zombie villager is actually worth are not in the data files. They are constants in the game's code, so a second script reads them out of the same client with javap and names the class and member each one came from:

That script does not publish a number it cannot confirm. If one of these moves in a new version it stops with the difference printed, rather than writing the new value into the pages unread.

The odds

A villager does not show its trade table, it shows a draw out of it, and the size of that draw is data too: data/minecraft/trade_set/<job>/level_<n>.json says how many offers the game picks, and the tag beside it says how many it can pick from. Every chance on this site is those two numbers and nothing else. The draw is without replacement, so the chance one named offer is among them is the draw over the pool, and the rolls to expect before it turns up is that fraction upside down.

The enchanted book odds need one thing more, because the librarian's book trade names an enchantment tag rather than an enchantment. The same javap check reads EnchantRandomlyFunction to confirm the two assumptions the numbers rest on: the enchantment is picked flat out of the tag with Util.getRandomSafe, so the weights the enchanting table uses play no part, and the level is picked flat between the enchantment's own minimum and maximum with Mth.nextInt. The tag itself, #minecraft:tradeable, holds 40 enchantments in Java 26.2, which is the denominator behind every book chance on the rolling guide. If either assumption stops holding, the check fails rather than publishes.

The daily figures are the trade's own use limit times the 2 restocks a villager is allowed per in-game day. That is a ceiling on one villager, not a measurement of a farm: it assumes you are there for every restock and it says nothing about how long a restock takes to come round.

Where the item facts come from

An item page also says where the item comes from when you are not trading for it: the recipe that makes it, the mobs and blocks that drop it, the tool its own block demands. Those lines used to be written per category, which is how a page could tell you a dandelion was biome-locked or that a clock turns up on a shelf instead of at a crafting table. They are read out of the same jar now: data/minecraft/recipe for the recipe and what it takes, data/minecraft/loot_table/entities and /blocks for what drops it, and /chests and /equipment for the two loot counts. The conditions on those drops are read too, which is where "only gives it back to Silk Touch" and the 10% of gravel that is flint come from.

Where the jar says nothing, the page says nothing. An item whose name covers a group, like a dye or a coloured wool, gets no facts at all rather than the facts of one member of the group.

What is not checked

Being straight about the edges is the whole point of the rest of it. Still unchecked:

When it runs

Every morning at 08:00. If the result is identical to the previous day apart from the date, the site rebuilds itself so the date under each table is today's. If anything in the game's data moved, the run stops and waits for a person, because a changed number is worth looking at rather than publishing unread. That is why the date under a table is a real check and not a timestamp.

All 258 trades, by item or by villager job.