TL;DR
Solve performance issues of large factories by creating a new feature that will allow user to "compile" part of their factory into single entity.Why ?
Let's start with a justification and then continue to actual proposal and technical details.Issue of UPS
If I were ask to point out a single issue that the most of discussions is about (implicitly or explicitly), it would be the performance (UPS) of large factories. It may not be that obvious, since the community spans whole spectrum of players, but generally speaking large amount of discussions is about "mega bases". And with a megabase, sooner or later the player will hit the "issue" of UPS. I pesonally think that Factorio has amazing performance for vanilla experience, and you can only hit the UPS drop zone when you go for it, playing late endgame. Nevertheless, it is an engine limit and the player needs to either play around it (using optimized design patterns), or feel the consequences. Many of the discussions are therefore about megabase design, which evolved over the years, but is inherently tied to engine UPS limitations.
I am not big fan of an opinion that player needs to play the game paying attention to engine limitations. I think that using solar power instead of other types, or using trains instead of insanely long and resource-inefficient belts, or using inventory-to-inventory item movement, just because it is nicer to the engine, isn't something that player should be forced to do.
Propositions I've seen so far aimed towards player's behavior optimization (use engine-optimized patterns, don't play beyond first rocket launch), general single-thread optimization, hardware improvement suggestions, or unrealistic and simplified parallelism suggestions. Although all these can still be applied, I believe there is another option, that is moreover significantly more scalable.
Before we dig into the details, let's elaborate why players, Wube owners and employees should care.
- Players:
- The feature could be natural extension of blueprints and allows players to move from micromanagement to macromanagement without necessity to care about UPS or even some tiny factory bugs.
- It would allow to work with parts of the factory as indivisible sectors serving particular role, which is innevitable gameplay pattern of the endgame anyway. Players would get a dedicated feature for it beyond blueprints.
- Wube owners:
- I have no idea how hard would be to implement such thing in Factorio, but I (a player) would kindly pay 20 Euro on top of the base game for such content - because it would change the endgame. If there was a real endgame goal (launching rocket is too easy), it would be valuable even more. This post of mine is not an evaluation of business opportunity, I have no interest in it beyond an interest of an avarage fan. That is also the reason why I spent only limitted time on development of my suggestion.
- Wube developers:
- This forums section is meant to be for suggestions that cannot be created by a modder. I believe this is the case - that such feature has to be part of the base game, similar to blueprints. In this context I suggest an interesting new feature to work on.
- Technical part of the feature would require to solve really hard, but interesting problems. I would personally find very entertaining working on those. I don't know what all of your competitors in genre of factory simulations are doing, but I find Factorio on top of them in terms features related to factory construction and operation. Solving the proposed feature would move it up another level.
- If there is performance ticket somewhere in your backlog, think of this as a smart workaround. It will not solve a game core performance issue, but it will allow players to handle it. Of course it is not a solution solving all performance problems forever, but just another way to approach the problem. I think of it as IPv4 to IPv6 transition.
What ?
Let's summarize the problem:- Game engine requires update the game state in real time.
- The game state complexity grows with amount of objects in the map interacting with each other.
- Large factories can hit the state where amount of updates per second is smaller that frames per second - factory time flow speed becomes slower than real time flow speed, which reduces the amount of items the factory can produce per single real-life second. Simply speaking, factory simulation speed is getting slower.
- Factory "size" is measured by amount of items it can produce - its output.
- General way how to reduce number of object interactions while keeping factory output constant is to increase speed of item crafting and increase bulk size of items moving. This also means that increasing factory output can be achieved by an object that is "printing" items very fast. But this goes against core gameplay idea - crafting items take some time and there has to be complex chain of components. Cannot craft rockets from iron ore.
- Having complex factory section where hundreds of objects interact is another core gameplay feature. It cannot be simplified by having a single huge "box" that prints items at rate of the original factory section. It would "not look good and realistic".
- Factory view and size must be "realistic and appealing". It should preserve the original complexity and visuals.
- Joy of building of a factory is another core feature, but simplification by using the blueprints is ok. It is not considered "cheating".
Reduce amount of object interactions while keeping constant factory output, but avoid "black boxes" that are both visually unpleasant and unrealistic. Abstraction of individual items into blueprints that allow printing whole factory sections is ok.
Finally, elaborate on the statement from TL;DR.
The idea is to create a feature in Factorio, that will allow user to turn selected part of their factory to single entity. An "item", which will have the same visual appeal, same input-output properties (transformation capability, speed, resource and electricity consumption), but will abstract from internal interactions. It will simply transform input items to output items, but doing that will visually, sprite-wise, look the same. The difference would be that it will be a single entity - an object with an input and output slots, instead of set of belts, inserters, furnaces, assembling machines etc.
I know it may look too ambitious, and maybe it is. But I believe that technical solution consists of few well-defined tasks that need to be solved.
Me, a complete ignorant of Factorio engine, can identify at least these:
- Solve item transformations and consumption.
- Calculate a directed acyclic graph (DAG) from object interfaces between input and output - what is being consumed and produced, what items participate on it?
- Define how the user will select where is the start and the end of the section. Can there be an input inventory that will accept only predefined item?
- Calculate overall crafting speed - resource consumption, production; power consumption.
- Detect that items must not loop around; has it to be a DAG? Detect when a user creation cannot be transformed to a DAG.
- Solve graphics
- Graphical appearance should remain the same; how to merge sprites?
- How to simulate items flowing "in" the object. How unrealistic would be to not show them?
- Other tasks
- How to specify borders of a section that is meant to be transformed to single entity?
- How to work with it once it is a single object? Can it be destroyed or repaired? Partially, totally? Once "compiled", cannot "uncompile"?
- How will it work in multiplayer?
- How to release?
- Free or payed feature?
There are clearly lots of tasks to solve. For me, the most appealing (and probably the hardest) part is solving the first one - how to calculate an end-to-end item flow from arbitrary player's creation? It seems hard, but it reminds me problems from data engineering area. Actually, real-life ETL data pipeline in a corporation is very similar to a Factorio factory in sense that inputs are transformed to output through series of interfaces and transformers.Types of items in a factory are equally important as data types, and individual blocks are connected together to create a single well-oiled machine with a purpose.
Transforming the problem to an oriented graph is standard excercise, the only problem is how to do it in that particular example and what to do with it once there. Anyway, I find it very interesting problem and gave it a try on a trivial case of small section of steel smeltery. See below.
Suppose a user wants to transform their little steel smelting block into a single object:
What is the basic item flow? Clearly there are 6 parallel smelteries that grab items from common belt getting items from a input chest an putting finished items to an output chest. Also, excuse my right-left direction please, wanted to keep visual connection to original smeltery screenshot.
But it is not that simple, there are individual inserters and the each belt consists of two individual bets (two sides).
Ok, but that diagram shows only schematic connections. It does not show the particular transformation of items, nor the speed of the transformation. Also single, unbranched item trajectory may not be visible.
Let's extract only what happens in one furnace. Some interface speeds are simplified, namely inserter has common speed 60 items per minute.
From the picture it is clear what is the input and what is the output of each operation. Some in-game objects has to be decomposed to multiple nodes, because they actually consists of multiple interfaces. Interface speeds are denoted, and there are speeds that limit the whole transformation marked in red.
Let's show the overall composed view when all 6 furnaces work in parallel.
Ok, the last diagram may look little crazy, but it shows the problem. When the goal is to calculate input and output speeds, it needs to take into consideration all interfaces and their throughputs. In case of paralellism, the throughput is summed over the parallel segments. But there may be a bottleneck anywhere in the system (anyone who plays Factorio knows very well). So the goal is to find that bottleneck, because it defines the IO speed of whole system. Which in case of single-object system is its "crafting speed".
I know my explanation may be in few places little hasty, but this is not a research paper and I don't want to spend excesive amount of energy on it, when the most probable reaction on this wall of text will be something like: "it's nonsense", or "nice, but won't do".
So, have a nice day.