Open cmfrydos opened 3 months ago
I'm all for more unit-tests! Woo!
At the time of writing this comment, there was no prod code yet, so hard to evaluate the goals of a new algorithm. But I guess that's why it's a draft. XD
@catloversg because they're the big brain on corps, and have very good ideas about when/how to make changes there.
I'm all for more unit-tests! Woo!
At the time of writing this comment, there was no prod code yet, so hard to evaluate the goals of a new algorithm. But I guess that's why it's a draft. XD
Yup, I was using this document as my working version, so it might not be very professional. To be honest, I'm not entirely sure how to properly use the draft feature.
While testing, I was utterly amazed at how easy it was to write scenarios as unit tests. They just magically work without requiring 'real' interaction with the game. 👍 This really speaks to the strength of the game's architecture. However, the tests do rely on 'internal' game objects, which might cause them to fail if the internal structure changes. I'm not sure how to make them more reliable, but I hope it's clear that they are meant to be discarded when they can no longer accurately measure what they're supposed to. That said, they were a huge help during development. It's astonishing how quickly things can break unexpectedly, and it's really nice to get immediate feedback. I definitely need to do this more in my own projects.
FEATURE: Better SmartSupply
This pull request introduces a new algorithm to improve the current functionality of SmartSupply. The algorithm addresses several shortcomings of the existing system, extending its capabilities and making it more reliable and user-friendly for players. The new algorithm is a bit better at handling tricky situations, but it’s still possible for players to create their own version using the in-game scripting tools if they prefer to save on SmartSupply costs.
Basics
Corporations cycle through several distinct phases: "START" -> "PURCHASE" -> "PRODUCTION" -> "EXPORT" -> "SALE". To ensure sufficient base materials for production, players must calculate the necessary quantities during the "PURCHASE" phase. SmartSupply automates this task, making it more convenient. The products and materials used can vary by industry, with different sizes and conversion ratios.
Current Problems
There are two major and two minor issues with the current implementation.
a) Overbuying Resources When Products Are Larger Than Their Base Materials
The current algorithm fails to account for situations where the volume of materials increases during production. For example, in mining, small amounts of hardware are used to produce large quantities of ore and minerals. The old algorithm tends to overbuy materials, leaving insufficient room for production. The new algorithm reserves the exact amount of space needed for production.
b) Underbuying When Base Materials Are Already in the Warehouse
When base materials are already present in the warehouse, the current algorithm reduces the maximum amount of resources that can be bought by the space occupied by these materials. It then splits the remaining space according to material ratios and buys the necessary amounts. However, this approach only adjusts for base resources already in the warehouse after the split, leading to inefficiencies. For example:
c) (Minor) Activation with a One-Cycle Delay
The current algorithm relies on "measured" production volume information from the previous production cycle to calculate the necessary materials, causing a one-cycle delay in activation and updating. The new algorithm, instead, calculates the required amounts directly, eliminating this delay.
d) (Minor) Ignoring Import Volume
The current algorithm does not consider the amount of imported materials when determining available space, which can result in insufficient base materials for the next cycle. The new algorithm addresses this by reserving space for the import cycle.
Changes
New SmartSupply Algorithm Overview
The main task of SmartSupply is to optimize the usage of available space in the warehouse. The goal is to ensure that:
Before the SmartSupply algorithm is triggered, the warehouse might look like this:
Improved Algorithm: Reserving Space for Imports
The new algorithm enhances the previous approach by reserving space for the IMPORT/EXPORT phase, which occurs after the PRODUCTION phase and before the SALE phase. This reservation ensures that there is no congestion when importing new materials.
Analyzing Filled Space
Next, the algorithm analyzes the filled space. It identifies the space used by existing input materials and combines this with the empty space to determine the "available space" for production.
Calculating Ratios and reserving Space for Output
SmartSupply's task is now to adjust the ratios of resources within this space to optimize production. The algorithm examines each required input material, calculates the ratio of existing to needed quantities, and adjusts the available space accordingly. If there is already more of a resource than required, the algorithm removes the space allocated for that resource and recalculates the ratios.
Example 1: Mining
For example, in mining:
The corresponding ratios are:
Normalized:
Here, the output is 8.34 times larger than the input. To accommodate this, we divide the available space by 8.34:
Dropping the output and focusing on the input materials, we get:
In this case, only Hardware is needed, and the newly calculated "available space" will be filled with it until production requirements are fully satisfied.
Example 2: Chemicals
Let's consider another example with Chemicals. To produce 1 unit of chemicals:
Normalized ratios:
Since the sum of the input material volumes is larger than the output volume, we don't need to reserve extra space for the production. We drop the output and normalize the input ratio again:
Adjusting for existing Materials
Finally, we compare the existing ratios to the required ones, and sorting the material by this fraction. For example, if the available space currently looks like this:
We get the following ratios:
Thus treat Water, with the greater existing:required-ratio, first, then Plants.
We find that Water is not needed in large quantities and is even too high (fraction > 1). Therefore, we remove its share from the available space, adjust the ratios, and normalize again. The remaining space should then be filled with Plants, but not excessively—production capacity must be taken into account to avoid overbuying resources.
Conclusion
This algorithm is more advanced than the previous one and handles edge cases more effectively. When dealing with multiple products or output materials and when production limits are involved, it is supported by the function
getProductionCapacity()
, which calculates both the average product size and total production capacity. This separate function ensures that the algorithm can manage these scenarios efficiently.One significant advantage of this new approach is that it activates immediately, without requiring a "warm-up" cycle as the old algorithm did. Notably, the new SmartSupply Algorithm and the production capacity calculation are two separate improvements and could be split into different parts or pull requests.
Testing
Test-Driven Development (TDD)
To ensure the reliability of the new algorithm, I have added a suite of Jest tests. Some of these tests are designed to fail with the current version of SmartSupply, highlighting areas where the new algorithm improves functionality.
As I am relatively new to Jest and unit testing in general, I welcome any feedback or suggestions for improving these tests.
Shortcomings / Room for Further Improvement
Related Issues Not Addressed by This PR
While these issues are not directly related to SmartSupply, I’m open to discussing them in the comment section. This could potentially lead to more PRs and further improvements.
Discussion and Open Questions
Discussion
1. Correct Implementation of Production Limits
The current implementation of production limits, those set by players, has some quirks that need addressing. Although this is more of a bug, it seems that the developers have not reached a consensus on how to resolve it. SmartSupply needs to be synchronized with any future changes to this quirky implementation of limits to ensure consistency and prevent issues such as overproduction or underutilization of warehouse space. Input on how to approach this issue is appreciated.
2. Placement of Functions and Logic / Codestyle
I’m currently unsure where to place the new functions introduced in this PR. They logically belong to the
Division.js
module, but I’ve separated them into their own file because they seem to add new functionality that isn’t part of the core game. Should these functions remain in their own file, or should they be integrated into the existing module? I’m open to suggestions on the most logical and maintainable structure.3. Concept of Multiple Market Cycles per Processing Step
While reviewing the code, I came across the concept of multiple market cycles per processing step. However, I’m unsure of its intended purpose or how it is currently used, if at all. Clarification on this concept’s role and any potential applications would be helpful. Understanding its function could lead to better integration or improvements within the SmartSupply system.
4. Optimizing Production Throughput with Geometric Series
There is potential to optimize production throughput by using a geometric series to manage space freed up during the "PRODUCTION" stage. This approach could maximize throughput, but careful consideration is needed to ensure that a full warehouse after production does not hinder imports. One idea is to allow players to set a production space limit (e.g., Production Space = CAPACITY - IMPORTS) to balance production and imports, or automatically limit production to avoid rejecting any planned imports. The calculation logic from
smartSupply.ts/getProductionCapacity
could be reused here, but community feedback is essential to refine and develop this concept further.Additionally, it’s important to note that the current version of SmartSupply provided here depends on the production algorithm being updated alongside it. Depending on the outcome of this discussion, the SmartSupply algorithm may need slight adjustments to stay synchronized with the production logic.
5. Feedback, Suggestions, and Criticisms
I encourage everyone to provide feedback, suggestions, and criticisms on this PR. Are there any potential oversights? Is the approach taken here in line with what the community needs? Are there additional features or adjustments that could enhance the implementation? All comments are welcome to ensure that this PR meets expectations and improves overall gameplay.
Especially since I’m new to this game, repository, and JavaScript, I’m really thankful for any guiding comments and tips on how to write better code and PR's. This is also my first "real" PR tackling a more advanced feature. I also want to apologize for any awkward language choices, as English is my second language. I hope everything is clear, but if not, please don’t hesitate to ask.
6. Further Testing and Implementation
While I believe the general concept is sound and all current "theoretical" jest tests have passed, I’m not yet fully convinced that the code is entirely bug-free or will work flawlessly in its current state. I would like to conduct more extensive testing, particularly with a more complex scenario involving multiple divisions exporting to each other and operating at or near full warehouse capacity. Writing these additional tests and potentially running some "real-world" tests within a live corporation environment would be beneficial, but it will take a few more days to complete.
At this stage, it should also be clear whether this change is actually welcome or should be rejected, and I appreciate your feedback. As with any first version, bugs are likely to be present. While I encourage you to review these changes, it might be worth discussing how long this should remain in testing, and possibly consider skipping a version number or two before full implementation to be on the safe side.