Trade rumors
How the game records prices from other towns and shows them as "Can buy at" and "Can sell at" lines in the item tooltip, at full precision for game v1.4.8. For a plain-language version, see the trading guide. The prices themselves are explained in Prices and profit markers.
No official module (SandBox, StoryMode, NavalDLC, BirthAndDeath) overrides any of the models or behaviors on this page. The numbers in the examples and tables are computed by the Python model in src/bannerlord/trade/. Trade rumors are unrelated to the opening lines of villagers and townspeople, which are covered in Gossip rumors.
At a glance
| What | Needs |
|---|---|
| Trade rumors in the item tooltip | nothing |
| Rumors from your caravans | Traveling Rumors (Trade 100) |
| Rumors from your workshop towns | Toll Gates (Trade 100) |
The rumor record
Rumors are kept by TradeRumorsCampaignBehavior. A rumor is a record
(Settlement, ItemObject, BuyPrice, SellPrice, EndTime)
Settlement: the town the prices belong to.ItemObject: the item.BuyPrice: what that town charges for the item when the rumor was recorded.SellPrice: what that town pays for the item when the rumor was recorded.EndTime: when the rumor expires.
Prices are recorded with no client party, so they use
penalty = 0.06·0.2 = 0.012
instead of the player's real penalty: 0.06 is the starting penalty and ×0.2 is the "no client party" row of the trade penalty. For non-goods the item-type terms of that table are added to 0.06 first, and the whole sum is then ×0.2. Trade skill and perks do not enter.
Dedupe
At most one rumor per (settlement, item): a new one for an existing pair is dropped, the old price is kept. A pair is free again only when its rumor expires or is deleted.
Sources
| Source | When | What | Lifetime |
|---|---|---|---|
| Main party enters a town | at most once per town per day | first deletes every rumor of that town, then adds one for every trade good | 10 days |
| Your clan's caravan enters a town, with Traveling Rumors | same | same | 10 days |
| Daily tick | every day | one random (town, item) pair; item is any Goods or Horse item |
10–19 days |
| Daily tick, with Toll Gates | every day | every trade good in each town where you own a workshop | 10 days |
| Asking any caravan "trade rumors" | at most once per caravan per day | one of its logged trades with profit rate > 1.2, weighted by profit rate; adds that item's rumor for its destination town and its last visited town | 10 days |
Notes on the table:
- "Same" in the caravan row means the same timing (at most once per town per day) and the same action (delete the town's rumors, then add one for every trade good).
- In the caravan-dialog row, the profit rate is the value the caravan's trade log stores for each logged trade (
TradeActionLog.ProfitRate). Only trades with a profit rate above 1.2 qualify, and the pick among them is random, weighted by profit rate, so a higher profit rate is more likely to be picked. - Lifetime is the time from recording to
EndTime.
Timeline: visit, toll gates and caravan dialog rumors last 10 days, the daily random rumor lasts 10 to 19 days. Below, eleven blocks from 10 days left to 0 days left: full colour from 10 down to 5, then fading at 4 and 3, and half strength from 2 to 0.
How long each source keeps a rumor.
| Source | Shortest (days) | Longest (days) |
|---|---|---|
| Visit | 10 | 10 |
| Daily random | 10 | 19 |
| Toll gates | 10 | 10 |
| Caravan dialog | 10 | 10 |
A rumor starts to fade 5 days before it expires.
| Days left | Strength |
|---|---|
| 0 | 0.5 |
| 1 | 0.5 |
| 2 | 0.5 |
| 3 | 0.6 |
| 4 | 0.8 |
| 5 | 1 |
| 6 | 1 |
| 7 | 1 |
| 8 | 1 |
| 9 | 1 |
| 10 | 1 |
Staleness: the Toll Gates and caravan dialog bug
Only your own visits (and your caravans') replace stale rumors. Toll Gates and the caravan dialog hit the dedupe: their rumor for a pair is refreshed only after the previous one expires, so their prices are up to 10 days old.
The daily tick (DailyTick) first adds the day's rumors (AddDailyTradeRumors) and only then deletes expired ones (DeleteExpiredRumors). The dedupe check does not look at whether the existing rumor has expired.
Step by step, for a town where you own a workshop and have Toll Gates:
- Day 0: the daily tick adds a rumor for every trade good in the town, with today's prices and a lifetime of 10 days.
- Days 1 to 9: the daily tick tries again, but every pair already has a rumor, so each new one is dropped. The tooltip keeps showing day-0 prices.
- Around day 10: the day-0 rumors reach their end time, but each tick adds before it deletes, so on the tick that finds them expired the new rumors are still dropped. The expired day-0 rumors are deleted at the end of that tick.
- The next daily tick: the pairs are free; the Toll Gates rumors get through with fresh prices. That is day 10 or day 11, depending on whether the tick falls before or after the end time.
If you enter the town on, say, day 4, your visit deletes every rumor of that town first and records day-4 prices. The daily random rumor is subject to the same dedupe.
Tooltip
ItemMenuVM.SetMerchandiseComponentTooltip builds the tooltip lines for the hovered item. It takes the rumors for that item outside the current town, sorted by SellPrice descending, then BuyPrice descending, and tests each one:
buy there if rumor.BuyPrice < 0.9 · (your sell price here) -> "Can buy at {town} for: {BuyPrice}"
sell there if rumor.SellPrice > 1.1 · (your buy price here) -> "Can sell at {town} for: {SellPrice}"
otherwise not shown; if both hold, only the buy line is shown
rumor.BuyPrice,rumor.SellPrice: the prices stored in the rumor.- "Your sell price here": what the current merchant would pay you for the item.
- "Your buy price here": what the current merchant would charge you for the item.
- "Your price here" is the real price for the main party, with penalty and perks. The rumor prices are recorded with
penalty = 0.012(see above), so the two sides are not on the same footing.
Whether the rumor adds a line to the item tooltip.
| Case | Rumor buy | Rumor sell | Sells here for | Buy here for | Tooltip |
|---|---|---|---|---|---|
| Cheap to buy there | 80 | 75 | 100 | 110 | Buy line |
| Dear to sell there | 140 | 130 | 90 | 100 | Sell line |
| Nothing stands out | 105 | 100 | 100 | 110 | No line |
| Both; buy line wins | 80 | 130 | 100 | 105 | Buy line |
The "both conditions" row only illustrates the rule: real rumor prices (sell below buy) never satisfy both.
Table of four cases with local buy, local sell, rumor buy and rumor sell prices: cheap to buy there gives a buy line, dear to sell there gives a sell line, nothing stands out gives no line, and when both conditions hold the buy line wins.
Step by step for each row of the table:
- Cheap to buy there:
80 < 0.9 · 100 = 90, so the buy line is shown. - Dear to sell there:
140 < 0.9 · 90 = 81fails;130 > 1.1 · 100 = 110holds, so the sell line is shown. - Nothing stands out:
105 < 0.9 · 100 = 90fails and100 > 1.1 · 110 = 121fails, so no line. - Both; buy line wins:
80 < 0.9 · 100 = 90and130 > 1.1 · 105 = 115.5both hold; only the buy line is shown.
Fade
line opacity = clamp(days left / 5, 0.5, 1)
days left: time until the rumor'sEndTime, in days.clamp(x, 0.5, 1):xlimited to the range 0.5 to 1.
A rumor fades during its last 5 days and stays at half opacity until it expires. With 4 days left the line is at 4 / 5 = 0.8; with 3 days left at 0.6; from 2.5 days left down to expiry at 0.5. The strength column of the second table under Sources lists every whole day.
Game code
IL for every method on this page, decoded from game v1.4.8:
- TradeRumor.il: the rumor record,
IsExpired. - TradeRumorsCampaignBehavior.il:
OnSettlementEntered,AddTradeRumors,DailyTick,AddDailyTradeRumors,OnTradeRumorIsTaken,DeleteExpiredRumors. - CaravansCampaignBehavior.rumors.il: the caravan "trade rumors" dialog.
- ItemMenuVM.tooltip.il:
SetMerchandiseComponentTooltip. - DefaultTradeItemPriceFactorModel.il: the prices a rumor records.
- DefaultPerks.InitializeAll.il: Traveling Rumors and Toll Gates.
The types and assemblies, and the commands to reproduce the IL, are listed under Reproducing.
Changelog
- v1.4.8 (2026-11-10): First version from IL.