Dev Diary #19: Trade Pt. 2
18:09, 1 Apr 2023
Hello and welcome to the 19th development diary of Grey Eminence!
Today, we’re continuing the series of dev diaries dedicated to trade. In the previous edition, we gave a high-level overview of the structure of the trade system (markets and infrastructure) - now, we’ll explore two of the most important processes within the system, pricing and transactions.
Pricing
At any time within a single market, each good has a particular price - determined by the previous monthly iteration of that market (so pricing updates monthly, same as logistics). This price drives the behavior of all economic actors within that market for the next iteration - and that behavior in turn impacts the price for the iteration after that.
So, how exactly is the price of a good calculated? We mentioned before that it’s primarily driven by supply and demand, represented by production and consumption respectively in each market. The more a given market produces a good compared to consuming it, the lower its price will be (and vice versa), which sounds pretty straightforward and it is.
However, since markets are interconnected and form larger long-distance trade routes (especially in the first half of the game, prior to railroads unlocking multi-province markets), the pricing formula also considers imports and exports. This helps us solve the problem of linking a source of goods to a distant sink that might be multiple market connections away: without considering imports and exports, intermediary markets wouldn’t be able to adequately move goods along the chain without first building up massive stockpiles.
The exact parameters of the pricing formula are still subject to change, but at its core it’s essentially the base price (which is static per good depending on its supply chain complexity) multiplied by a ratio of the difference between production+imports and consumption+exports. As an example (with non-final variables), if a good has a base price of 1, but its consumption+exports outpaces production+imports by a factor of 5, the final price in that market will be 5.
There are a couple of balancing mechanisms we’ve added to the pricing mechanism to make it more resilient to major fluctuations and shocks: for any given iteration, the new price is clamped to be within +/-50% of the old one. Of course, this won’t prevent price spikes due to genuine shortages, but it does provide just enough leeway to smooth out minor disruptions caused by temporary issues such as re-routing of goods flow due to embargoes.
Transactions
Fundamentally, the pricing system exists to enable transactions - between the merchants of a given market and their suppliers/customers, or between the merchants of two connected markets. These transactions move goods around and facilitate the entire economic process of the game, so they’re an important process to get right. Note that we’ve gone through multiple iterations of the transaction system - and the one described above might not be the final one - but we’re confident that we’ve arrived at a pretty satisfactory solution overall.
Let’s start by covering local transactions - those that occur within a market between its merchants and either suppliers or customers. As we confirmed previously, each market has its own stockpile for each good. This stockpile is owned by the merchants of that particular market (in the case of multi-province markets, the stockpile is considered to be owned jointly by all merchants in the market’s constituent provinces). Whenever a building produces goods, it immediately sells those goods to its local market’s stockpile. Similarly, whenever a population (or building, or character) consumes goods, it buys them from its local market’s stockpile.
Thus, local transactions always occur via the merchants, who serve as permanent middlemen by design. Due to their omnipresence, merchants cannot refuse local transactions - they’ll always buy/sell from/to local producers/consumers at the current market price. As compensation for their inability to consent, we’ve added a slight markup to the price of all local transactions in favor of the merchants. This ensures that they’ll always have a small baseline level of profit, which ensures that local economies (particularly subsistence ones, which predominate in 1356) can run smoothly. While the markup is currently fixed (and, as usual, is subject to change), we’re planning on linking it to one of a country's economic laws, but that’s a topic for another time.
Now we’ll continue on to external transactions, which occur between two connected markets. Here we’ll find significantly more consent than in local transactions - in fact, external transactions are always voluntary and are always driven by profit. During each iteration of the trade system, each market scans connected markets looking for profitable import trades (accounting for transport costs, tariffs and so on). Similarly to the partial fulfillment we utilize in consumption/production, once all such import requests are aggregated, they’re fulfilled entirely (if stockpiles permit) or partially in proportion to their size (if stockpiles are insufficient). Crucially, it is the importer who pays all initial costs - and thus takes on the risk of his stockpile being less valuable in future iterations of the trade system.
This relatively simple (and purely local/neighbor-aware) behavior allows for the organic emergence of long-distance trade routes spanning dozens of markets. At each step along the way, local merchants import goods at a profit, without ever being aware of any information beyond their immediate surroundings. Of course, this does mean that changes in supply/demand take time to propagate across the network and re-routes require a radial propagation across all connections (rather than magically knowing the next-best optimal path after the one that just closed), but nevertheless the system produces surprisingly realistic outcomes considering its input data.
Conclusion
That’s all this time around! We’re continuing to work on getting the closed alpha ready, but due to our limited funding we’re doing so at a reduced pace. Considering the current speed of development, we feel that it’s safe to rule out a 2023 release for the game - though we remain optimistic that with time our community will grow to the point where we can reasonably finish the game without external financing. In addition, we’re also once again temporarily suspending the release of new dev diaries - our top priority is the closed alpha and we need to concentrate 100% of our resources on it.
Thank you for reading and for your unwavering support through these challenging times! As always, we’ll be happy to answer any questions and to chat in our Discord - and you should also make sure to join our Subreddit, and to follow us on YouTube, Facebook, and Twitter.