Skip to content
HN On Hacker News ↗

Solving Factorio Quality − Exyr.org

▲ 282 points • 107 comments • by laurenth • 2w ago • HN discussion ↗

Pangram verdict · v3.3

We believe that this entire text is human-written.

0 %

AI likelihood · overall

Human
100% human-written 0% AI-generated
SEGMENTS · HUMAN 1 of 1
SEGMENTS · AI 0 of 1
WORD COUNT 1,520
PEAK AI % 0% · §1
Analyzed
Sep 30
backend: pangram/v3.3
Segments scanned
1 windows
avg 1520 words each
Distribution
100 / 0%
human / AI fraction
Verdict
Human
Pangram v3.3

Article text · 1,520 words · 1 segments analyzed

Human AI-generated
§1 Human · 0%

Solving Factorio Quality Simon Sapin, 2026-02-15 I play Factorio the normal way: by writing matrix math code to plan the factory. But we’ll get to that. Or, TL;DR, go to my new online calculator tool. Intro to Factorio and Quality Factorio pretty much founded the factory video game genre: you play a character who harvests resources and combines them to craft increasingly complex items, which in turn enable more sophisticated crafting. So far this sounds a lot like Minecraft and many other survival games, but what sets factory games apart is the focus on automation: soon enough, most of the crafting is done not “by hand” by the character but by increasingly many machines, with various forms of logistics like conveyor belts to move items between machines or wherever they need to go. Some factory game go further and remove the player character altogether. As “technologies” are unlocked in-game, Factorio offers many mechanisms to improve production. One of them is modules: crafting machines have a (limited) number of slots to accept different kinds of modules that affect their stats: speed modules make the machine run faster at the cost of more energy consumption, productivity modules increase yield from the same ingredients at the cost of speed and energy, etc. Released in 2024, the Space Age extension adds new game mechanics including Quality: every item and recipe now come in five quality tiers: ⚀ normal, ⚁ uncommon, ⚂ rare, ⚃ epic, and ⚄ legendary. Depending on the item, each tier improves stats such as making crafting machines faster or making productivity modules more productive. High-quality items can be crafted directly from ingredients of the same quality, but the only way to increase quality is through the new quality modules. Quality modules can have quality too. Source: Factorio wiki Modules affect the probability QQ of any quality increase. For a given craft, each quality tier increase after the first is another 10% chance. We can build a table of the probabilities of output quality depending on input quality: Source: Factorio wiki For example, the maximum possible quality chance in a machine with four module slots is 24.8%: Jumping from normal to legendary in one step is only a 0.0248% chance. Source: Factorio wiki Some players dislike the introduction of randomness to a game that was mostly deterministic, but with enough repetitions probabilities become ratios. The probabilities are balanced so that even with multiple crafting steps (each a potential quality jumps), getting high-quality items unavoidably involves also crafting many unwanted low-quality ones. To avoid the factory grinding to a halt when storage eventually gets full, Space Age also introduces the recycler: a new machine that destroys any item and (usually) returns 25% of its ingredients. This enables players to design “upcycling” contraptions that craft and recycle in a loop with quality modules until items reach the desired quality, at the cost of consuming many more ingredients: Source: Factorio blog Factory planning tools Some video games are partly “played” outside of the game itself. Blue Prince fully expects its players to keep extensive notes of everything they see, but doesn’t provide an in-game notepad or similar tool. Factory games lend themselves to building large spreadsheets for resource accounting, but a select few players decide that spreadsheets are not powerful enough for factory planning and spent countless hours programming dedicated tools that reproduce much of the game’s math to accurately model a production chain. Example production chain in Factoriolab This is all optional in factory games, it’s perfectly viable to play it by ear and just build more when seeing something lacking. But I do like to plan in advance: how many machines of each kind do I need? How much yield can I expect? Where are the bottlenecks? The looping nature of quality upcycling makes this particularly challenging either to guess, or to calculate with existing tools. Matrix math Let’s imagine: Some ingredients (for example iron plates) that come from an arbitrary production chain that may involve quality modules. Any given ingredient has a probability to be in each quality tier: ⚀ normal, ⚁ uncommon, ⚂ rare, ⚃ epic, and ⚄ legendary. Enough assembling machines with each recipe tier to craft all ingredients into some product (for example pipes). These machines have quality modules so that the a quality chance is 10%. Let’s track the possible fates of one item: A product of a given tier can come from ingredients of the same tier or lower. The total probability for this outcome is the sum of (independent) probabilites of different ways to get it. In turn, those are the product of the percentage chance of a specific quality jump times the probability of having the corresponding ingredient tier in the first place: p⚀=i⚀⋅90%p⚁=i⚀⋅9%+i⚁⋅90%p⚂=i⚀⋅0.9%+i⚁⋅9%+i⚂⋅90%p⚃=i⚀⋅0.09%+i⚁⋅0.9%+i⚂⋅9%+i⚃⋅90%p⚄=i⚀⋅0.01%+i⚁⋅0.1%+i⚂⋅1%+i⚃⋅10%+i⚄ \begin{align*} p_⚀ &= i_⚀ ⋅ 90\% \\ p_⚁ &= i_⚀ ⋅ 9\% &+ &i_⚁ ⋅ 90\% \\ p_⚂ &= i_⚀ ⋅ 0.9\% &+ &i_⚁ ⋅ 9\% &+ &i_⚂ ⋅ 90\% \\ p_⚃ &= i_⚀ ⋅ 0.09\% &+ &i_⚁ ⋅ 0.9\% &+ &i_⚂ ⋅ 9\% &+ &i_⚃ ⋅ 90\% \\ p_⚄ &= i_⚀ ⋅ 0.01\% &+ &i_⚁ ⋅ 0.1\% &+ &i_⚂ ⋅ 1\% &+ &i_⚃ ⋅ 10\% &+ i_⚄ \end{align*} (The percent sign can be thought of as implicit division by 100, so that “percentage of” is the same as multiplication.) Here the percentage coefficients look transposed across the diagonal compared to the quality jump probability table from the wiki, but that’s only because we’ve arranged product tiers vertically. Instead let’s group the probabilities of different tiers of the same item into row vectors: product=(p⚀p⚁p⚂p⚃p⚄)ingredient=(i⚀i⚁i⚂i⚃i⚄) \begin{align*} product &= \begin{pmatrix*} p_⚀ & p_⚁ & p_⚂ & p_⚃ & p_⚄ \end{pmatrix*} \\ ingredient &= \begin{pmatrix*} i_⚀ & i_⚁ & i_⚂ & i_⚃ & i_⚄ \end{pmatrix*} \\ \end{align*} Now our system of linear equations can be written as a single equation where a vector is multiplied by a transition matrix that matches the wiki’s table: products=ingredients⋅Tquality(10%)Tquality(q)=(1−q9q109q1009q1000q100001−q9q109q100q100001−q9q10q100001−qq00001) \begin{align*} {products} &= {ingredients} ⋅ T_{quality}(10\%) \\[1em] T_{quality}(q) &= \begin{pmatrix*} 1-q & \frac{9q}{10} & \frac{9q}{100} & \frac{9q}{1000} & \frac{q}{1000} \\[0.3em] 0 & 1-q & \frac{9q}{10} & \frac{9q}{100} & \frac{q}{100} \\[0.3em] 0 & 0 & 1-q & \frac{9q}{10} & \frac{q}{10} \\[0.3em] 0 & 0 & 0 & 1-q & q \\[0.3em] 0 & 0 & 0 & 0 & 1 \end{pmatrix*} \end{align*} As an edge case, zero quality chance means no tier transformation. The corresponding transition matrix is the identity matrix: Tquality(0%)=I5T_{quality}(0\%) = I_5 This may not seem like much progress, but now a multi-step process can be computed through successive matrix multiplication. For example mining iron ore with 7.5% quality chance, then smelting it into iron plates with 5% quality chance, then crafting pipes with 10% chance. With no productivity bonus, we get these probabilities of end-products: pipe=(10000)⋅Tquality(7.5%)⋅Tquality(5%)⋅Tquality(10%)=(0.9250.06750.006750.0006750.000075)⋅Tquality(5%)⋅Tquality(10%)≈(0.878750.105750.0136130.0016650.000223)⋅Tquality(10%)≈(0.7908750.1742630.0296780.0044670.000719) \begin{align*} pipe &= \begin{pmatrix*} 1 & 0 & 0 & 0 & 0 \end{pmatrix*} ⋅ T_{quality}(7.5\%) ⋅ T_{quality}(5\%) ⋅ T_{quality}(10\%) \\ &= \begin{pmatrix*} 0.925 & 0.0675 & 0.00675 & 0.000675 & 0.000075 \end{pmatrix*} ⋅ T_{quality}(5\%) ⋅ T_{quality}(10\%) \\ &≈ \begin{pmatrix*} 0.87875 & 0.10575 & 0.013613 & 0.001665 & 0.000223 \end{pmatrix*} ⋅ T_{quality}(10\%) \\ &≈ \begin{pmatrix*} 0.790875 & 0.174263 & 0.029678 & 0.004467 & 0.000719 \end{pmatrix*} \end{align*} Quality strategies While it is possible to use quality modules as much as possible and deal with Every tier Everywhere All at Once, here we’ll focus on smaller self-contained systems. “Gambling”: opportunistic quality without recycling The easiest but also least effective is to craft from normal-quality ingredients, with quality modules, and not recycle anything. This can be done before unlocking the recycler but is only viable for a small number of items, such as crafting a few hundred asteroid collectors to hope to get a dozen uncommon or rare ones for an early space ship. This is improved when the factory has another use for normal-quality items. For example if placing thousands of normal-quality solar panels on the ground, crafting them with quality modules gives a better yield of higher-quality ones for space ships before the output buffers fill up. With a single step and no loop, this is simplest to calculate: the expected product tier distribution is the first row of the Tquality(q)T_{quality}(q) transition matrix or of the probability table found on the wiki. “Washing”: pure recycling loop For most items, the recycler reverses the main crafting recipe and returns 25% of the ingredients. But some items don’t have a crafting recipe (like ore) or it is considered irreversible (typically smelting and chemical processes). In that case the recycler produces either nothing or, 25% of the time, the same item. This process can improve quality if the recycler has quality modules. Repeating it in a loop, eventually all items will be either destroyed or improved until they reach any desired quality tier. Self-recycling items is arguably not the common case but let’s start here since the math is simpler. Example setup mining ore (with quality modules), and “washing” it until rare or above. Let’s consider one item injected into the system, in this case from mining, and call freshunitfresh_{unit} the 5-component row vector of probabilities of each quality tier. After we transform that vector, the new probabilities may add up to less than one.