shpaass / yafc-ce

Powerful Factorio calculator/analyser that works with mods
GNU General Public License v3.0
54 stars 20 forks source link

Make "Use best modules" useful #155

Open shpaass opened 3 months ago

shpaass commented 3 months ago

In a Pyanodon project, if you select "Use best modules" in the modules dropdown on upper-right, it often selects the Efficiency Modules.
This result is mostly false. The Speed or Prod modules are more useful.

At the moment, "Use best modules" is a useless feature for pY due to how wrong the results are, so I wanted to see if we can do something about it. I don't consider it an important or even significant issue, because everyone already has their preference on speed vs prod and don't bother with YAFC suggestions in this regard, but I wanted to indicate that this problem exists at all.

The steps I see on how to tackle this problem are the following:

  1. Understand what we optimize for with the "best modules" and if this optimization goal should be configurable.
  2. See if the current implementation reflects our understanding of "best".
  3. Change the implementation if necessary.
DaleStan commented 1 month ago

Pollution

Increasing the pollution cost in the preferences will encourage selection of prod modules rather than efficiency modules.

This vanilla project has the pollution cost set to 0%, and Yafc only puts Prod3 modules in four recipes. By increasing the pollution costs to 100%, 1k%, and 10k%[^1], the module filler will add progressively more Prod3s, eventually filling all possible rows. Other changes, such as linking electricity production and adding miners, do not appear to effect the module filler.

vanilla.zip

[^1]: These values are not where the change happens; they are just ones I happened to use when testing.

Speed effects

The calculations should consider speed effects, especially when prod modules are not an option. Increased speed (especially from Bob's Pure speed modules, which do not have a consumption penalty) can reduce fuel/electricity consumption more than using exclusively efficiency effects. Even in vanilla, one speed3 plus three eff3 reduces the total energy consumption to 13⅓% of the no-modules consumption, through the combination of reduced base consumption and increased speed.

Efficiency effect limit

Once the 20% efficiency limit is reached, further improvements should not be considered. If enough module slots are available and other modules do not have efficiency penalties, three Eff1 modules (-90% -80%, cost 366) should be preferred over two Eff2s (-80%, cost 2.54k) or two Eff3s (-100% -80%, cost 14.3k)

shpaass commented 3 weeks ago

After thinking and asking in the pY Discord, I came to a conclusion that the autofill functionality is extremely niche for the following reasons:

For vanilla, there is a ton of analysis on what modules and beacons to use. Yafc can't top that, even with a clean slate of the Space Exploration DLC. That leaves us the case of mods.

In mods however, the cases where it's not "prod if you can" are exceedingly rare, and are too esoteric to make the functionality for. I asked in pY Discord if there was a case where the choice between Speed and Prod was not obvious, and got the following answers:

[For SE,] higher tier prod modules get really expensive and aren’t worth the extra prod always, so we mostly use lower tier modules. We always have prod in machines basically, but in beacons we often use a mix of speed and eff modules because power generation is a bigger deal in SE. (c) quintuple

[For pY,] you can prod pressurized water, for instance. Most of the time that'll be no modules, or speed modules, but occasionally that'll be some prod + some speed. (c) vraleth

I think it would be better to remove the module-autofill functionality and dedicate the Auto Module section of the column-menu to things like mass-set modules to all recipes as a one-off, or as a default.

What do you guys think? @DaleStan

zzh8829 commented 3 weeks ago

I did some research into this yesterday #282

in my opinion the autofill feature is still useful but its a bit over promised. we can simplify the supported use case by considering a few scenarios

  1. fill best possible prod module at each milestone - works today
  2. fill best possible speed module for pyAL - works after #282 improvment
  3. maximize -80% power saving using mixed modules - potentially new feature
  4. late game power is practically free so add best possible module and ignore energy cost - potentially new feature
shpaass commented 3 weeks ago

So essentially, you want to convert Module Autofill into the following buttons:

I'm fine with the first three, but I have doubts about the last point. Isn't it the same as the first two? If you fill a row with best possible speed or prod, you already disregard energy concerns -- because you always use best available module. Am I incorrect?

skullbearer commented 3 weeks ago

TL;DR

NATTERING ABOUT GOAL SEEK PROBLEM BELOW This is a classic optimization problem, and for any optimization you need to define the goal(s) of the algorithm.

We must separate out what is a goal and what is a conclusion.

Straight Conclusions (require no goal oriented optimization, just explicit math relation)

Goals 'obvious' to Player

Proposed Goals (Flexible, more manual by user)

The above goals, if put into an order list, provide actionable optimization. For example, in order of highest priority (1) to lowest priority:

Factory target is a set Glass output

  1. Minimize Quartz input
  2. Minimize Syngas consumption (Glassworks are set to consume Syngas is my assumption here)

This would first, prod the Glassworks to minimize the quartz requirements. It would then seek to minimize Syngas consumption. Because this example is simple, there would be no change possible which would not increase Quartz consumption, therefore goal (1) controls.

Another example:

Fixed CuZn Battery production of 0.1/s (for 0.1/s Simple Circuits), pre-circuits, full Py0 research completed

  1. Max tier 1 modules
  2. Max 40/s Raw Coal
  3. Max 3 Moss Farms
  4. Minimize Gasifiers
  5. etc...

Assuming you setup the production of the above including power and ash separation + soot separation, you end up with a mixture of productivity and efficiency modules to achieve the goals. Each time you move towards a lower tier goal and that violates a higher tier goal, you must revert back to the last point of higher tier goals passing the condition.

I think the best way to approach it is to prod the highest level in each chain/sub-chain of production, and move down the chain(s). Each module will create a cost differential for each particular goal affected. Raw Coal is a linking cost goal for the entire chain due to steam power. Maybe you use Coal Dust to fuel the Zinc furnace stack. Now the algorithm may put a prod module into the ash separation recipe, but that consumes so much power that the Raw Coal goal is violated, so the prod is removed. This occurs so on and so forth, with efficiency modules also being used where the Raw Coal consumption is reduced in order to allow for prod modules in the highest level factories, EXCEPT where the module addition violates a higher goal itself, such as Minimizing the Gasifiers.

Doing it manually I end up with a mixture of prod1s and eff1s, but no speed1s. Not everything needs to be moduled with eff1s either, even if it can be. For instance, muddy water production is negligible when moduled.

skullbearer commented 3 weeks ago

I'm adding this as separate because it raises a separate issue.

If a goal seek algorithm is used for modules, it can also be used to plan entire complex production chains. Tell it what's available, limits of the availability (if any), tell it what you want out of it, let the goal seek search through combinations of production options to build a moduled per goals full factory plan for those goals. The quality of the result will depend heavily on the user's ability to set goals and boundaries appropriately, and it can and will frequently be 'unsolvable' so a 'no solution possible' needs to be thrown when there is no ability to meet all goals (ie, no new approach).

For example, I want 1/s Simple Circuits as a max limit and I set Maximize Simple Circuits as a goal I limit Raw Coal consumption to 150/s (10 lanes) as a max limit, which includes the Raw Coal consumption of the Burner Miners! This is perhaps, just all I can fit on my patch and I don't want to go look for another patch yet. I set Minimize Raw Coal consumption as a goal.

Notice that if working correctly, the algorithm should try to obtain the most Simple Circuits possible until it reaches 1/s, after which point it will then seek to minimize Raw Coal, until that drops the Simple Circuits < 1/s, then it returns to the first goal and so on and so forth.

It should automagically seek out the right combination of fuels (Coal Gas or Syngas? Tar for fuel or Tar further processed?) and in which portions.

It will still require voiding or buffering. We haven't set goals for anything regarding that. We could though if we were very careful and savvy about it.

Every additional goal will require exponentially more computations to seek, but the load is on the user's PC, therefore the only suggestion would be to ensure an exit and perhaps, a psuedo-live update of the current 'best state' that 'most matches the goals' to show something is occurring. Calculation time should still be extremely fast unless the band at which all goals can be achieved is extremely narrow (like, perhaps, only one exact solution possible). Explicit solutions could be found, but would require significant pre-calculation of recipe relationships that is just unnecessary since in modern computing, even low power computers have ridiculous calculation capacity.

I