Combinator Tutorial

2026-05-10

Advanced combinator tutorial for Factorio: practical circuit logic like SR latches, memory cells, clocks, edge detectors, counters and more.

This is an advanced tutorial. Beginners should first consult the examples on Tutorial:Circuit network cookbook and the Circuit network overview page. This article assumes you understand basic circuit concepts and covers more advanced topics like SR latches, memory cells, clocks, and so on.

Introduction

Combinator logic is achieved by cross-connecting outputs back to inputs to produce the desired logical behavior. Complex logic may require many combinators, but often a handful of combinators can implement very useful basic logic. The reason combinator logic works is that Factorio updates 60 times per second. Logically, each update tick is split into two phases. In the first phase all combinators read their inputs from the connected networks and perform their calculations. That produces each combinator’s output values. The tick’s update completes in the second phase, when each network’s value is updated to be the sum of all connected outputs.

Even if a combinator calculates a logical value, its output is not acknowledged by the circuit network until the next phase. Therefore, when a decider combinator detects some input condition, the output value will only be reflected on the circuit network on the next step. This behavior is important and can cause sequence errors or large delays when chaining multiple combinators in series.

Circuit wires behave like an electronic bus, carrying the information present on connected wires. That means the same signals on a wire will automatically be summed. Different signals will be carried on the same wire independently.

When cross-connecting combinators it’s good practice to use the unused color of wire. This separates input and output networks and prevents unintended inputs from being accidentally connected into a large circuit network. Because combinators sum red and green inputs before computing, either color can be used when looping an output back to an input. However in most cases it’s useful to use the opposite color so the result doesn’t interfere with other outputs or inputs.

The in-game editor is your best friend for understanding combinators. Pause the game and step through nodes and networks tick-by-tick with the “Tick once” keybinding to inspect them.

Virtual signals Some virtual signals available on the circuit network

In addition to standard item signals, Factorio’s circuit network includes a set of signals that do not represent specific in-game items. These virtual signals function as user-defined channels on the circuit network and can be given arbitrary meanings. Currently there are 102 virtual signals that can be sent on the circuit network (172 in Space Age), organized into the Signals, Enemies, Environment, and Unsorted tabs. Included among them are:

  • 36 alphanumeric characters (A–Z, 0–9)

  • 9 colors: red, green, blue, yellow, magenta, cyan, white, grey, black

  • 25 icons: several crosses, lines, arrows

  • All enemy types

  • All environmental objects (trees, rocks, player, cliffs, etc.)

  • Two wires, spidertron, discharge, artillery remote

Logic signals

There are three additional virtual signals called logic signals*. Unlike other signals, these cannot be transmitted over the circuit network. Instead they modify combinator behavior by applying additional logic. Specifically, these logic symbols act as wildcards, representing zero or more arbitrary signals rather than a single discrete signal. Factorio’s circuit network implements three types of wildcards.

Everything wildcard *

The Everything* wildcard is used in decider combinators. Its exact behavior depends on whether it is used as an input or an output:

  • Input: Returns true when all input signals satisfy the condition, or when no input signals exist; otherwise returns false.

  • Output: Returns all non-zero input signals.

When used as an input, Everything* can be thought of as a logical AND or universal quantifier. When used as an output it acts like an “echo” or “dump” of input signals.

Note: Everything* may be used as an output only when the input is not an each wildcard.

Anything wildcard *

The Anything* wildcard is also used in decider combinators.

If at least one input signal exists, it returns true if any input signal satisfies the condition. If no signals satisfy the condition, or no input signals exist, it returns false. This behavior makes Anything* akin to a logical OR or existential quantifier.

When used as both an input and an output on a decider, Anything* returns one of the signals that matched the condition.

Each wildcard *

The Each* wildcard is used in both decider and arithmetic combinators, and behaves somewhat differently from the previous two. In general, Each* causes the combinator operation to be performed separately for each signal. The exact behavior depends on usage and the type of combinator. It can be used as an input or an output, but if it’s used as an output it must also be used as an input.

When used as an input in a decider combinator, Each* compares each input signal individually to the combinator condition and returns each signal that satisfies the condition. How the outputs are returned depends on whether Each* is also used as an output:

  • Input only: Sums each input signal that passed the condition and returns either the count of passed signals or the sum of their values as the desired output signal, depending on the output setting.

  • Input and output: Returns each signal that passed with their respective values (depending on the output setting).

In an arithmetic combinator, the specified arithmetic operation is applied individually to each input signal. Like the decider combinator, the result returned depends on whether Each* is an output:

  • Input only: Sums the results of the operation applied to each input signal and returns that as the desired output.

  • Input and output: Returns the result of applying the operation to each input as the corresponding signal.

Each* is more complex than the other two wildcards but enables much more powerful operations.

Input insulator & gate

An arithmetic combinator set to (In: Each + 0, Out: Each) can be used as an insulator to change wire color or to prevent downstream logic from feeding back into the input of a circuit network.

A decider combinator set to (Out: Everything, Input -> Output) can also act as an insulator while its logic condition is true. This allows it to selectively pass inputs only when desired, functioning as a “gate”. This is useful for polling remote train station chest contents in sequence and including only the stations you want.

Set/Reset latching switch

You may want to SET a trigger when some quantity reaches a threshold, then keep it ON until another value (the RESET value) is reached. This requires one decider and one arithmetic combinator. (For more complex multi-channel conditions you can use two deciders plus a constant combinator.)

Set the first decider to the desired set condition and make it output 1. Connect that output into an arithmetic combinator and configure the arithmetic to multiply by a bias value (the difference between set and reset values), then feed the arithmetic output back into the decider input. The arithmetic output channel must be the same channel that the decider reads.

When the set condition is met the decider outputs ‘1’ and the arithmetic bias is applied. That causes the value to be held until it drops below the reset point.

In this concrete example a pump turns on when light oil reaches 20000 and turns off when it reaches 5000:

A similar example with detailed settings and explanation for backup steam generation is here: RS latch - single decider version

Basic memory

Decider combinators can be used to hold a value. They act as memory for counters and more advanced logic (see below). Configure the decider combinator as follows:

  • Connect the input and output to the same network (usually mutually),

  • Set the condition to signal > 0 if you want to hold only positive values, or ≠ 0 if you want to hold both positive and negative values,

  • Set the output to be the input count or value for a particular input signal.

As long as all inputs on the network are zero, the previously set value will be retained.

Remember the two-stage update process mentioned above. If the network has value = 5, a combinator will read that value from the network as input and determine it is > 0. It then sets its output to that input (=5). On the next step the network is set to the sum of all outputs and remains =5.

If a constant combinator or similar supplies a non-zero input over time, a basic increment clock is formed. The stored value increases every cycle by the sum of all connected input values. For example, if a constant combinator outputs =1 and is connected to the memory, the network will store 1 on the first tick, 2 on the second tick, and then continue increasing at 60 ticks per second.

Copy blueprint string 0eNqlU11rwzAM/C96TkuStWvqh8F+xyghH2orSOygyGWh5L/PjkcJJetW9hKQLd2d7pwrlI3FjkkLqCtQZXQP6uMKPZ100fgzGToEBSTYQgS6aH1VY0U18qoybUm6EMMwRkC6xk9QyRj9CuCJpNCyjJCOhwhQCwlh0DMVQ65tWyI7iodAEXSmd7NGe36Ht9sk620EA6jVNsvWW8fk5oRNk5d4Li7khlznkRpB/sGAC7FYd3JjDh2rd5jQrHcwiWcmHAKLxsor6T1U4j8nRtTzpah2G7te4sqSTKWfHr2Nd3unjxJYWPtu6Zo4qAmECxZ8w+burqab7iNxL/mfLcEL8iBn0qfgTUgIVOyLtit4kqvgzU0aK539B3Y35JP5+ZFNm5N2YKCELY7P2J/MvF6II53CTJ9Lzz3h6c2r2T8WgZPfhwCyZLPbp7vsdR+/xJtx/AJNbzZ8

So why does this work in detail? The network starts with no value. When the constant combinator becomes active it produces =1 and the decider still outputs 0 because no value was yet set. Step 2: the network is set to the sum of all outputs, becoming =1. On the next update tick the constant combinator again outputs =1, but this time the decider reads =1 and itself outputs [A]=1. Step 2: the network is set to sum =2. It continues increasing similarly.

Usually the constant combinator outputs 1 but of course it could output other values (including negative values). Negative values will decrease the stored value as in the example below. If the decider condition is > 0, only positive values are allowed and the decrease stops at 0. If the condition is ≠ 0, negative values are allowed.

A single pulse input causes a single increment equal to the pulse value, creating a counter. In the next blueprint, place one item on a belt. Every time the connected belt detects it, a pulse is produced and the stored value increases.

Copy blueprint string 0eNqllMGO4jAMQP/F5zAqpaXQw/7IahWljQFLbVIlLtoK5d83aXdZEJ3DMBeQU+fFenZyg6YbcXBkGOobUGuNh/rnDTydjerSGk8DQg3E2IMAo/oUsVPGD9bxpsGOIQggo/E31NvwSwAaJiZcSHMwSTP2DbqY8BlDwGB93GZNOjWiqqL8KAVMUG/KQ/ZRhiBeaPl7tG2kCdDksF1S8hX27gvs/XOlT+xCQNTKznaywYu6knVpX0uuHYklGtV0KDX59A/1SXUexf2zQ6XlRRktEySWGK2yGx8y/q0vqb3VEZKF+VCz1ODTedv0c3aI5rEtpKEu/7NSGFsY1lwX7/l4cV2ssMs7W2NLGt2mtX1DRnGUtcI/fmo7X7f9F5tkabo7OZHzLF9m/UqOx7hyL2rJ2OAV3cQXMmdY/HpW6eJkKegH5eZya/gRd9qRh/Eb7GGKtY6G5cnZXpKJsKXx4Sut3T24Xml1HlstIP/uZOzfuoXVcf1OV2/N2Ux7moR9eormZ6t+eOUERNF+GZXDtqiOeXXYH7NdVoTwB9igtjA=

The stored value is cleared when the condition is no longer satisfied and the decider clears its output. This only happens if that value is not being output anywhere else on the network. The stored value can also be reset to zero by a negative pulse equal to the current value; the latter can occur even while other inputs remain connected.

Basic clocks A basic clock. The C signal cycles up to 30 ticks and is incremented continually. Single-combinator version settings shown.

Clocks are made by looping a combinator’s output back into its input so it increments its own count each cycle. This can be done with either arithmetic or decider combinators.

An arithmetic combinator looped on itself is interesting to watch as it grows without bound, but requires additional control logic to reset it.

Using a single decider combinator you can build a self-resetting clock. Connect its output to its input, set it to less than (<) a particular number, and set Input → Output. If you connect a constant combinator as an input, each cycle the count will be increased by the constant combinator’s output; when it reaches the threshold the decider clears its output. At that point only the constant combinator contributes to the network and the clock is reset.

With this mechanism the clock sequence does not include 0. The clock starts at the value set by the constant combinator. Also the value that caused the condition to become false is included in the sequence. Arithmetic combinators can change the clock sequence, but remember arithmetic outputs are emitted one cycle later than the clock value.

You can omit the constant combinator by adding a constant 1 to the arithmetic output. This version will set the threshold-equal signal for one tick longer, causing it to count one tick more for the same threshold (similar to the off-by-one difference between 0-based and 1-based counting in programming). If exact period is required, decrease the threshold by 1 (e.g., set the threshold to 59 to repeat every second / 60 ticks).

A one-shot clock that counts only once can be built with the following configuration. The clock can be reset by enabling/disabling a constant combinator that outputs .

One-time clock. Runs until T=Z+1. Reset via R>0. Copy blueprint string 0eNq1VdtugzAM/Rc/p1Wh9BZtPzHtaVOFKLidJUhQSKpVFf8+B6oK9QrT9oJI4hzb5xzDETa5w9KQsiCPQKlWFcjPI1S0U0nu9+yhRJBAFgsQoJLCrzJMKUMzSnWxIZVYbaAWQCrDb5BBLZ4C+EQ2UfY2QlivBaCyZAnbeprFIVau2KDhFI8qEVDqiq9q5dMz3GI2E3AAOZqtgvGM02RkMG0D5sLXYo3O4w1+JXtiAL51go35LGugKr+7JVPZ+Kq1PRnreOdcVBsxevctVegx+l/68Je4mzIxTTcSXjhGO1u6oalTXR64A6dsvDW6iEkxBshtkldYN+dKtTw03QX+YTDrEk68ijiSTOrINstGnJ1BVJeBfMKoYT+YgINr75QLacOHHrmh7WI8WN0t5RbNHac/Ecb5UQmWk47d13e4vElS0I+G6VAawjMNy9V/0vDWpaFLAr9Xsc/W+msAJT2dEf1y6K/5CP9x6E/8tJqBnFwM8+sfD7M1bsgsB31nedoR4PZH4MGoX3tcDFDeO8n/LGTn5yRgz05txVsG0WIVLpbz1WQ6ier6B+n0TYg=

Pulse generators

Attach an additional (=) decider combinator to a basic clock output and you get a pulse generator that emits a single pulse every time the clock passes the set condition. Any output value can be used. The pulse source may come directly from the clock sequence (input->output), from 1, or from a value placed on another logic channel via a constant combinator, etc.

  • The value 1 may be written as any positive integer ≥ 1, provided you do not exceed the timer’s ceiling.

  • In the timer example above, the lamp pulses on the first tick after the timer reaches 30; since Factorio updates 60 times per second this results in blinking at 1/30 second intervals.

Edge detectors

Using combinator computation delay you can create 1-tick pulses when a signal changes (e.g., from 0 to 1).

Loop the combinator output back to its input with a red wire, and connect the arithmetic combinator input with red and its output with green configured to multiply by -1. When the red circuit changes a signal from 0 to 1, the arithmetic combinator receives the input 1 but its output is still 0 during that tick. Therefore for that one tick the green wire carries 1. On the next tick the arithmetic combinator updates and outputs -1. Now the green wire has two inputs that cancel each other out. Similarly when a red input changes from 1 to 0, the green wire will have -1 for a single tick.

If you only want a pulse on the 0→1 change, you can filter the negative pulse with a decider combinator set to >0. This mechanism is useful for counting trains that enter a station, for example.

Counter

A counter counts the number of input events and outputs the total. Connect any pulsing signal to a decider combinator set to input->output and loop that output back to its input to create a counter. However that input must be zero except when pulsing, otherwise the combinator will run away like a clock. Typically you use a pulse generator to produce the pulses. By combining multiple gated deciders (insulators with sequential conditions), clocks, and pulse generators as inputs to a counter, you can poll the contents of remote chests and count them.

Memory cells Simple latch

When looping a combinator to itself, use a wire color different than your main input or output.

Truth Table:

Output 1 | Input 1 | Input 2 | Output 1 (t+1) | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 (2)* | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 (2)

Output 1 is the green wire loop visible in the diagram, which holds the latched value.

Input 1 is Set, Input 2 is Reset.

Positive cell

A cell that stores positive values (with reset):

Connect the desired value to the right as signal I to set the memory cell; connect a negative value as signal I to reset the cell.

  • The memory cell’s outputs are two mutually exclusive signals.

  • When input I > 0, signal I is passed through to the other side.

  • When input I is absent, signal M is output instead as the memory of the previous input value.

  • It takes two ticks for the output to switch from input I to the memory signal M when input I is removed.

  • If input I lasts only one tick, the memory cell will continue to alternate between the previous two values each tick indefinitely.

  • The switch is seamless; no tick will produce an empty signal.

Positives and negatives cell

This cell can store either positive or negative values. Reset is performed on a dedicated line. It also handles 1-tick bursts correctly. See the forum post for details.

  • Output M (memory) is the last non-zero input I.

  • If a non-zero R (reset) signal appears, the output is set to zero.

  • 1-tick bursts of R or I are handled correctly.

  • Negative values are handled properly.

Multiplier and Dictionaries/Arrays

  • Multiplying two signals is simple and can be done with a single combinator, but multiplying multiple signals is more complex.

  • Below is a proof of the equation and an explanation of why it works.

  • A dictionary is a system that can access a value at a specific signal. For example A may contain many signals (from constant combinators or memory cells) and B may contain a single signal (e.g., the blue signal). The result is the value of the blue signal inside A. This works because all other signals are multiplied by 0.

  • An array is similar to a dictionary, but uses numbers instead of signal keys. Place constant combinators such that each signal corresponds to a unique index number (e.g., 1 = yellow belt, 2 = red belt, 3 = blue belt, 4 = burner inserter, etc.). Then use a combinator like "each = index OUTPUT 1 of each" and connect that to the dictionary input.

((A+B)^2 - (A-B)^2)/4 = AB (A+B)^2 - (A-B)^2 = 4AB (A^2 + 2AB + B^2) - (A^2 - 2AB + B^2) = 4AB 4AB = 4AB

See Also