Trade calculation fix - suggested algorithm

  • We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
Fixed labels
  • Ato1

    Corporal
    49 Badges
    Mar 27, 2012
    30
    74
    • 500k Club
    • Victoria 2
    • Europa Universalis IV
    • Stellaris
    • Crusader Kings II
    • Crusader Kings III
    • Imperator: Rome Deluxe Edition
    • Victoria: Revolutions
    • Cities in Motion
    • Hearts of Iron IV: Cadet
    • Hearts of Iron IV: Death or Dishonor
    • Crusader Kings II: Horse Lords
    • Stellaris: Megacorp
    • Europa Universalis IV: Rights of Man
    • Stellaris: Leviathans Story Pack
    • Hearts of Iron IV: Together for Victory
    • Crusader Kings II: Monks and Mystics
    • Stellaris - Path to Destruction bundle
    • Hearts of Iron IV: Expansion Pass
    • Europa Universalis IV: Rule Britannia
    • Stellaris: Distant Stars
    • Europa Universalis IV: Dharma
    • Crusader Kings II: Reapers Due
    • Crusader Kings II: Holy Fury
    • Hearts of Iron IV: Expansion Pass
    • Stellaris: Ancient Relics
    • Hearts of Iron IV: La Resistance
    • Stellaris: Federations
    • Imperator: Rome - Magna Graecia
    • Europa Universalis 4: Emperor
    • Stellaris: Nemesis
    • Crusader Kings II: Charlemagne
    • Crusader Kings II: Legacy of Rome
    • Crusader Kings II: The Old Gods
    • Crusader Kings II: Sons of Abraham
    • Crusader Kings II: Sword of Islam
    • Europa Universalis IV: Art of War
    • Europa Universalis IV: Wealth of Nations
    • Europa Universalis IV: Res Publica
    • Victoria 2: A House Divided
    • Imperator: Rome
    • Victoria 2: Heart of Darkness
    • Crusader Kings II: Way of Life
    • Europa Universalis IV: Common Sense
    • Europa Universalis IV: Cossacks
    • Crusader Kings II: Conclave
    • Europa Universalis IV: Cradle of Civilization
    • Europa Universalis IV: Mandate of Heaven
    • Magicka 2 - Signup Campaign
    Here I propose a concrete solution to the trade price calculation problems. I believe that the suggested algorithm describes the trade in realistic manner, while being reasonably easy to implement under the current trade system and should lead to good results from the fun and play perspective.

    As it was noted in multiple reports, the trade as of now doesn't quite work. It very often creates silly loops, where hauling same goods back and forth creates money out of thin air, and even one-way routes can easily end up in a situation where it is profitable to import goods from higher cost market to the market where the final price is lower. The reason for this is that the calculation uses mid-way price between the initial (without any trade) and final (with trade) price. Problem has been well explained for example in [https://forum.paradoxplaza.com/foru...te-resource-loops-and-infinite-money.1552075/], and I will proceed assuming that the reader is familiar with it. The reason for the current calculation has been mentioned under the dev diary #54 [https://forum.paradoxplaza.com/foru...toria-3-dev-diary-54-trade-revisions.1538297/] and originates in a band-aid solution to make trade generate more money. While the current system is going to be reworked, I’m worried that the devs will resort to another band-aid type of fix that will just push the problem to another place (e.g. making sure that the trade flows one way only, which would not prevent the one-way trade problems, nor an infinite triangular trade exploit). I write this post in hopes that either devs or someone making mods will take a note and consider the approach. To my knowledge the concrete solution of this type has not been posted on the forum.



    Basic logic

    First, the price at which trade happens must be the current market price and not the midpoint between the price without and with the trade. The midpoint calculation is the direct cause of the nonsensical loops, moreover it doesn’t make an actual sense (in real life, the midpoint might make be somewhat relevant when the trade starts, however after many weeks of trade, the price without trade is completely lost and neither determinable nor relevant. You can determine current price of coal in China and Europe, and whether it is profitable to import. But good luck determining what the price would be if no trade was happening, and buying the coal at halfway to that imaginary price). We know that the devs tried the market-price approach, and the tests were unsatisfactory (Commissar Roach mentioned in reply to dev diary #54 that the prices hovered around base price). I think that the problem with using the market price was in the implementation, not in the price assumption (granted, I do not know the details of the tests).

    The next step is to determine the volume of the trade. Initially, the profitability will increase as the amount of transported goods increases. The trade will start to equilibrate the prices, and at some point the trade route reaches maximal profitability. Past that point any increase of transported goods decreases the overall profitability of the route, however the route is still profitable. At some point the prices equilibrate to the point that the trade is no longer profitable, and any increase in traded goods would make the overall route unprofitable. The whole situation is illustrated in the figure. Note that the actual shape of price lines (price as a function of the traded amount) is not that important (as long as it is smooth and monotonous, which is trivially true in the game).

    Vic3TradeFig.png


    Let’s denote the price in the importer as PI, in the exporter as PE, both are function of number of traded goods N. For simplicity we’ll assume that the cost of trade C is flat per unit of traded good (i.e costs twice as much in tariffs, convoys and jobs to move twice the amount of goods), which should be exact approximation in terms of the game. The total profit for the route is M = (PI(N)-PE(N) – C) * N, which is price gain per traded unit times the number of units.

    Between the trade start A and maximum profit B, there isn’t any reason why the trade wouldn’t grow (baring shortages in convoys or jobs, which is already included in the game and doesn’t need to be changed). After reaching point B, the situation becomes more nuanced. If the trader was a monopoly, there isn’t any reason why they would transport any more goods. On the other hand, a competition within the same country might exist (we still discuss only one country trading with another, but the trade on the same route could be done by independent agents competing within the same route, depicting various traders from a country all importing the same good). In such case any incoming agent can still make profit (at the expense of the other agents competing at the same route). In an idealized perfect competition case, this would happen as long as there would be any profit to be made, and the trade would go all the way to C. In reality, the ideal equilibrium E would be anywhere in between B and C, depending on the competitiveness level. The percentage of the shift is denoted by the competitiveness factor k. It ranges from 0 (monopoly maximizing profit) to 1 (idealized full competition). This factor could be varied based on the trading system; however it is unlikely that the variation within the game would lead to a satisfactory and understandable gameplay, and is thus better to be fixed (see the balancing section)



    Algorithm implementation

    In the simplest case, the k is chosen to be 0, and the trade routes are trying to maximize the profit and reach point B. Then the logic is even simpler than the current implementation of the price calculation. I will denote as NC the current volume, as NC+1 increased volume, NC-1 decreased volume. The volumes are quantized, since the route value is an integer value.

    if ( (PI(NC)-PE(NC)-C)*NC < PI(NC+1)-PE(NC+1)-C)*(NC+1) ) increase volume to NC+1 // increase makes more profit
    else if ( (PI(NC)-PE(NC)-C)*NC < PI(NC-1)-PE(NC-1)-C)*(NC-1) ) decrease the volume
    else do not do anything, you are already at the best profit

    In case k is chosen to be 1, trade will grow until point C. And the implementation is similarly easy:

    if (PI(NC+1)-PE(NC+1)-C > 0) increase the route // increase while it still makes money
    else if (PI(NC)-PE(NC)-C < 0) // if it is losing money, decrease it



    However, it is possible that best results would be obtained with k somewhere between 0 and 1, where the route is still profitable, but transports more goods than for the optimal-profit case. Unfortunately, the most efficient implementation depends on the details of the price curve as a function of trade volume. For example for linear dependence, it is possible to calculate the intersect of PI(N)-PE(N)-C with 0, and thus obtain the range of route levels and determine where the route is currently with respect to the chosen k (and profits would then be parabolic. For k=0.5 the route should grow until NC ~ 3/4 N(max) ). Otherwise, since most trade routes' level is rather low, it might also be possible to do additional calculation for the other few levels, and to determine the range that way.

    A third option that could be implemented is approximation based on the general shape of the curve: Calculating D = (PI(NC+1)-PE(NC+1))*(NC+1) – (PI(NC)-PE(NC))*NC. If it is larger than 0, we are below point of maximum profit B. If it is smaller, approximately how many more increases can the route take before it becomes non-profitable: X = (PI(NC)-PE(NC))*NC / D, and comparing it to the current volume to determine where approximately we are (e.g I trade 10 units, the route would become unprofitable around 18 units, my goal k is 0.8 – I’m not there)



    Balancing

    The current game is balanced around the system which rewards non-sensical loops. With the updated implementation, these loops would be removed, which would cause the contribution of the trade to GDP to decline. Maybe more importantly, the trade profits are currently inflated by the price calculation. It would be likely needed to rebalance the game to restore some of the trade contribution. The most obvious way is to lower the non-tariff portion of the trade costs C. That can be done by lowering requirements/price for shipping or jobs needed to move the same amount of goods. The other option is to increase the maximum allowed price difference from current base+-75% or make the prices change more at surplus/deficit, thus making trading more profitable.

    Additional testing would be necessary to determine the ideal value of k. I feel that k = 1 would be likely unsatisfactory, as it would lead to a situation where no route makes any profit. k = 0 might be simple and work well enough, making the routes as profitable as possible, while still moving a reasonable amount of goods between the markets. The devs did some testing with the market prices, I wonder what k their tests simulated (even if they didn’t use this formalism, the test would likely be either k=0 or k=1, since they needed to determine the volume of the route somehow). That knowledge could be used to determine the most promising k to use, since the one that was tested did not seem to work well.



    Additional considerations with multiple countries trading

    The system works same way regardless of number of traders or if they create chained or looped trade routes. Any silly routes would be automatically unprofitable. The only additional consideration comes from the discretization of the trade in game. For example, what happens when multiple traders could increase the route level, but not all of them at once (i.e. three traders at level 1. Any could increase the level, but if all move to level 2, the price will shift so much that they will all start losing money. Who gets to move? By prestige? The one with the largest profit increase? Or do all stay at level 1?) However, the current implementation faces the same problem, and I’d imagine that the same approach as now can be used.



    Discussion

    The suggested implementation describes the system in a realistic manner, and is thus impervious to the anomalies observed in the current system. Additionally, it is similar to the current system and could thus be implemented without any major development. It retains all the features that interact with the current system (e.g. removing tariffs decreases cost C, increasing the route volume and profitability). The trade change would almost surely require game rebalancing as the loop and mid-point profits would disappear, in order to keep the trade profitability in the range that “feels right”.



    Note

    This ended up being much longer than anticipated and reads more as a journal article than a forum post. But I do like the core of Victoria 3 and wish that the trade system can be improved in a solid fashion. I hope that I explained the idea clearly, otherwise I’d be happy to answer questions.


    Edit: fixed labels for importer/exporter
     

    Attachments

    • Vic3TradeFig.png
      Vic3TradeFig.png
      34,4 KB · Views: 0
    Last edited:
    • 7Like
    • 4
    Reactions: