-
-
Notifications
You must be signed in to change notification settings - Fork 377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make (Bulk) Trading Profitable Again + Station Restocking #5291
Conversation
Station commodity stocks are now stored in a persistent table. - Buying from a station depletes the stock of commodities. - Station stocks recover over time, currently appx. 12 weeks. - Leaving a system and coming back no longer resets station stocks. Station stock target algorithm has been changed to be exponential instead of linear. - Larger ships now have a reason to ship bulk cargos. - Precious Metals is no longer the only commodity worth shipping. Hopefully resolve bug with equipmentStock table not being created for stations when docking. Use visited[station] table for checking whether we need to create station data rather than advertisments.
Haulaway (negative price) commodities are considered transient and have a different stock algorithm. Incorporate feedback from jimishol.
Use a normal distribution for station restocking based on feedback from jimishol. Fix remaining bugs resulting in zero h2 and rubbish stocks. Add error logging in case of station being created twice.
Add documentation, refactor return values from GetStationTargetStock
Well done!by a player. The GetMaxStockForPrice(price) function means that investment equals to Price * Stock = constant / Price^(a-1). That gives a huge tool in developers hands. Developers should really find time to play this PR for real and feel the difference it brings in game play. Initial game play is not affected at all. So, take amphiesma SetMoney to 100000, to save time, and try to acquire dsminer as soon as possible. It would be needed about 125 trades or about 12.5 hours of play time. A liitle harder than in current state where it is needed 9.7 hours. (Download Calibration.lua, ship_table.lua, FloydWarshall.lua in same folder and run the last one if you are curious about how i estimated this. This is another example of what can be achieved by this PR). Duration of 12.5 hours seems still small for me as player. From personal experience, i propose to try to double by design that duration. By playing this PR, i welcome the feature of not being profitable to visit same station in row but, i would like motivation to change systems, not just stations in same system. So, i welcome any thought to increase duration of restock. But even that has problem in near Sol systems. Near Sol i find many systems with huge number of stations. So, there is always enough stations to do A1,B1,A2,B2,A3,B3, A4... and so on trips between same pair of systems A, B. For this matter, take a thought if possible to limit number of stations a system can have. Very Well Done!! P.S. Constant and exponential a, of GetMaxStockForPrice function, are constants of an economy universe. I propose, those two, to be available at least to all lua files in libs and modules folders. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precious Metals is now a rare, low-volume commodity, being the best good to haul in a small ship but dropping off in absolute profit once the player has worked their way to a Mola Mola or similar entry-level medium hauler. By the time the player has purchased a Skipjack or larger ship, Robots or even Medicines are the better cargo to haul, giving the player an incentive to change it up and not just run the same route between two systems for the rest of the game until they get bored.
Sounds very good, and this certainly is an improvement, so it's a step in the right direction. I don't see any downsides with this.
@jimishol & others: some things to playtest:
- Are we still getting "sold out" adverts some times? There's a 50% chance that if market has 0 in stock of some item, then there'll be a "sold out" advert on the BBS.
- That H2 never sold out
- You could increase the
eventProbability
probability and setminTime=0
in the NewsEvent module, and check that these still work:- commodity hinted at in system reported, has either zero or very much in stock, and price is either much higher or much lower, respectively
data/libs/Game.lua
Outdated
-- Function: GetStartTime() | ||
-- | ||
-- Returns the zero-offset time in seconds since Jan 1 3200 at which the | ||
-- current game began |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should one explain why player might need it? I.e. a new game doesn't start the timer on 0? Maybe implicitly understood, but my lazy brain would miss it. I.e. an example perhaps?
--
-- > local seconds_since_start = Game.time() - Game.GetStartTime()
--
Should one also mention that it's in game time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't consider it high-priority as the name is relatively self-documenting, but I'll add that usage line.
Author: Webster Sheets <[email protected]> Date: Fri Sep 24 04:52:21 2021 -0400 On branch NEWS_game_start_time Changes to commit: add: Game.lua cherry picked from pioneerspacesim#5291 PR edit: ../modules/NewsEventCommodity/NewsEventCommodity.lua uses Game.GetStartTime() function from pioneerspacesim#5291 PR
As pointed out on IRC the other day, can a market spawn with 0 in stock for some commodity? I.e. have that equilibrium state, or is only possibility for 0t if player buys up the market? Asking, since SoldOut advert module doesn't set commodity supply to 0, but instead monitors the market and then spawns advert (with 50% probability) to buy the sold out commodity. Could the player use this? Buy all available precious metal. Jump out, jump back, and now sell back to someone offering x2 price? |
Yes. The chance of a commodity spawning at 0 is the same as before, but you get fewer "tries" at it as stock values aren't rerolled every time the player re-enters the system.
You probably won't see as many SoldOuts with these changes, but this does open up the opportunity for a more dynamic market ecosystem (among other things I want to add after this is merged is a separate "demand" tracker in addition to the current supply tracker) that SoldOut can make better use of then just how much of a commodity is in stock at the station.
They theoretically could, although it's more probable that the commodity would restock to be back above zero when they jump back in. In either case, I consider this internally consistent behavior (SoldOut triggers on zero stock, doesn't care about how it got there); this is something where changing it would require tracking both supply and demand of a given commodity. |
uses Game.GetStartTime() function from pioneerspacesim#5291 PR
uses Game.GetStartTime() function from #5291 PR
Bulk Trading Changes
This PR addresses a problem very astutely noticed by @jimishol in the economic and trading simulation portion of the game - once the player acquires a ship with ~80t of cargo space, the trading gameplay loop of Pioneer is effectively over. All commodities in the game have the exact same maximum profit for a single trade run, and the only variance is in how much hull space is required to make that exact same amount of money.
This means that once you have found an export/import run for Precious Metals, you have hit the maximum profit ceiling in trading. Sure, you can run a second commodity at the same time in a larger hull, but that costs more fuel, takes more real player time, usually requires a second chain of hyperjumps, and the profit margin is much lower than your primary commodity.
I promised charts, so charts you will have!
(Investment and Profit use left axis, Tonnage uses right axis.)
The current paradigm (which I will call "linear stocking") uses a simple formula to determine the amount of commodities that are present at a station when you enter the system. There is some variance in stock from station to station and from system to system based on the price modification from underlying system economy variables, but that variance has comparatively little effect on the primary viable trade route - buy a commodity at a major export station and sell at a minor import station, yielding approximately 30-35% profit.
With linear stocking, the "midgame" of trading ships (that is, medium haulers) is in fact the endgame of trading in Pioneer; you can spend more money on a larger ship, but you will never make any more money hauling a different cargo in a larger hold than you will hauling Precious Metals in a comparatively small hold.
This problem stems from the fact that the current stocking algorithm only takes into account a single factor - the price of the commodity - to cap the maximum profit that can be made in a single run. It ignores the other implicit factors of cargo space (price to acquire the ship), fuel costs (often 3-10x higher in a large bulk ship), and hyperjump range needed to haul larger cargoes.
This PR addresses that problem by introducing a new station stocking algorithm (which I call "exponential stocking"). It's based on the core of #5272, and uses an exponential term in the function that calculates a station's maximum stock to better model the factors of commodity rarity and time-and-resource cost to the player to haul bulk commodities, resulting in a higher credit-value profit from hauling bulk cargo while leaving the actual profit margin of 30-35% entirely untouched.
(Investment and Profit use left axis, Tonnage uses right axis.)
This new algorithm provides a better and more balanced economy that gives both large bulk ships and smaller cargo/courier ships like the Amphiesma and the Sinonatrix a role to play in trading and a natural progression through the game. Precious Metals is now a rare, low-volume commodity, being the best good to haul in a small ship but dropping off in absolute profit once the player has worked their way to a Mola Mola or similar entry-level medium hauler. By the time the player has purchased a Skipjack or larger ship, Robots or even Medicines are the better cargo to haul, giving the player an incentive to change it up and not just run the same route between two systems for the rest of the game until they get bored.
You can see the source data for all of these charts here.
Dynamic Station Restocking
Now, merely that change alone would solve the stated problem by giving bulk haulers a reason to haul textiles in their massive holds instead of being a glorified courier for Precious Metals, but there's something else that can be done to improve the trading gameplay as well, and something that lays the groundwork for a dynamic, simulated economy.
Stations now no longer re-roll their stock values for every commodity each time you re-enter the system, and instead persistently track the player's purchases and re-stock to a deterministic equilibrium over time. This means that when you've bought a station entirely out of one commodity stock, you can't just jump out and jump back in to refresh that station; you'll have to find another station in the system and buy from that station instead.
Stations will over time recover back to their "equilibrium" stock amounts (being a combination of a very lightweight approximation of NPC trade and commodity production happening in the background and the station interface being a front for multiple trading companies with their own exclusivity contracts and stock reserves) as you jump between systems and trade with other stations, eventually becoming a viable part of the player's trade route again.
The constants behind these two algorithms are currently tuned to allow the player to make one "max profit" run from a station before needing to use another station in the same system, with the station restocking after 3-6 such trade runs. This could be further changed after merge in several directions; either to use a lower equilibrium stock and restock much faster (while the player is on the pad, potentially, though I don't think this has much gameplay utility), or to have a higher equilibrium stock and restock much slower, potentially taking a year or more to get back to equilibrium stock after heavy bulk trading.
However, I don't think tuning in either direction is actually the best way to go, as I've neglected to mention how these new features interact with other potential future changes to the economy - one of the biggest is giving each station its own economy type and making export/import price modifications be relative to a specific station or planet rather than system-wide. This would greatly amplify the impact of limited station stocks as instead of N stations in the system to buy that stock from, you could have as little as 1-2 stations that sell the commodity you want at the right price.
Other changes that could impact and provide even more depth would be dynamic commodity prices based on available stock (buy from the highest-stock station and sell to high-demand); or basing station stock on station population and industry/agriculture production of the station and parent bodies during system generation - these values are currently too random and unpredictable to be used directly.
General Improvements
And of course, I've saved the best for last - I've rewritten the way SpaceStation.lua caches data about visited stations, adding an actual
visited
cache instead of using the advertisement register. This wound up resolving (or at least mitigating the cause) of theGetEquipmentStock()
bug that's been causing many crashes and issues over the past few months. This supersedes and will close #5284.I've also added a
Game.GetStartTime()
function for modules (e.g. hyperdrive breakdown) to use to determine when the loaded game was started; unfortunately it's inaccurate for old saves, but going forward that data will be available.Testing Notes
I'd appreciate some eyes on this PR with regards to longer-running games; both to confirm the fix for the GetEquipmentStock() bugs and also to test the progression from Amphiesma to Sinonatrix to Mola Mola and then the "midgame". I don't expect to see any bugs shaking out of the woodwork, but I would like feedback about the experience to see if I need to tweak any of the constants further to make the design more apparent.
Fixes #5149, fixes #5233. Closes #5272, closes #5284.