games/kaintuck: two-vector commodity pricing + rumor/reality banter
#38 in Riparion/riparion-retro — merged 2026-06-12
Why
Kaintuck's market was a one-dimensional downstream gradient — a single base_ranks per town, prices base_ranks/2 · (1–3 band). That captured "cheap upstream, dear at Natchez" but flattened the real economic geography: it couldn't say a town is cheap because it produces a good (Cincinnati pork, Monongahela rye) or dear because it lacks one (the provision-hungry lower landings), and it posted a single quote with no bid/ask.
What
Two-vector model + spread. Each town gets a sparse market: Vec<MarketBias> (supply discount / demand premium / extra spread, with a cause note) layered on the existing base_ranks gradient:
mid = base_ranks/2 · (1−supply)(1+demand) · band
buy = mid · (1 + spread/2) // ask
sell = mid · (1 − spread/2) · (1 + reputation/200) // bid
An 8% scenario base_spread applies to every quote; base_ranks is untouched (Natchez's premium stays in the distance gradient — no double-counting).
Historical first pass: Monongahela rye (Pittsburgh), Porkopolis pork + hides demand (Cincinnati), Kentucky tobacco/livestock (Maysville), bourbon (Louisville), and demand premiums + wider spreads at Shawneetown / Cairo / Memphis.
Rumor & reality banter. Reuses the existing banter system: hand-written rumors on the approach legs (the "every town's its own market" thesis early on the upper Ohio, plus Porkopolis/Kentucky-leaf/bourbon/hungry-landings color) and an engine-derived "wharf factor" reality line at each dock — composed from the same market data, so the spoken truth can never drift from the prices.
UI quotes actionable prices: the Trade screen and town-hub table show ask/sell, and the Natchez cash-out values cargo at the realizable bid (cargo_sale_value) rather than the mid.
Tests
- Reworked the price-band test to fold in the local factor.
- New
reality_banter_matches_the_market(banter == schema invariant) andbuy_ask_never_below_sell_bid(ask ≥ bid > 0 against the livebuy_price/sell_price). - Market-bias range validation in the scenario consistency test.
- Re-pinned the golden trace (
0x4702_3407_a369_986e) — a deliberate retune (every quote moves). - Bumped trail-kit 0.1.6→0.1.7, kaintuck 0.1.11→0.1.12.
🤖 Generated with Claude Code
Last updated 2026-06-13
Links to this note
Merged pull requests, newest first.