In other languages: Deutsch Русский 简体中文

Tutorial:Combinator tutorial: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(→‎Basics: changed analogy a bit)
m (wording)
 
(53 intermediate revisions by 14 users not shown)
Line 1: Line 1:
''This is an '''advanced''' tutorial. Beginners should refer to the [[Tutorial:Circuit network cookbook]] for examples and the [[Circuit network]] page for an overview over the circuit network. This tutorial assumes a basic understanding of circuits and covers more advanced topics like SR latches, memory cells and clocks.''
{{Languages}}
{{Languages}}
== Introduction ==
== Introduction ==
=== Basics ===
Combinator logic is achieved by cross-connecting outputs to inputs in such a way to achieve the desired logic. While advanced logic requires a multitude of combinators, some very useful basic logic can be achieved using only a handful of combinators. Combinator logic works because Factorio only updates at '''60 times per second'''. Logically, each update tick is separated into two steps. In the first step, all combinators first read the input from the connected network(s), perform their computations. This produces an output value for every combinator. The tick update concludes with the second step, where the values of each network will be updated as the sum of all connected values.
----
 
Let us start with how combinator logic is processed. Combinators update at each tick, meaning if that your computer is running at 60 updates per second (UPS), your combinator similarly runs at 60 processes per second.
 
This is important to take into account as you build larger scale projects, as it will affect how fast your logic will run, and how much your logic will heavily task on Factorio.  


When logic values are computed by combinators, the outputs are not recognized by the circuit network until the following step. So when a [[decider combinator]] is used to detect a certain input condition, its output value will not take effect on the circuit network until the next step. '''This behavior is important to remember and can result in sequencing errors and significant delays when multiple combinators are connected in series.'''


Think of each signal like the number of boxes, where a wire will transport that box into other combinators that will process those boxes. <br>
Circuit wires act like a wire bus in electronics; they carry information in the connected wires, meaning that if there are similar signals on a wire it will add them automatically. If the signal is different, it will be carried in that wire as well, but as a different signal.
Think of a wire being that highway where boxes are transported, so boxes with the same name/label get merged as they transport those boxes, whereas boxes with different labels remain unmerged. <br>


The first highway will not interact with another highway, so boxes with the same label do not get merged with one another when they are given separate highways - i.e. values in the green wire will not merge with values in the red wire - when those highways are connected to the same combinator, the combinator will merge those boxes.
When cross-connecting combinators, it is good practice to use the unused color to cross-connect, this will split the input and output networks and prevent unwanted inputs from accidentally connecting to a larger circuit network. Combinators will sum the red and green inputs prior to calculation, so either color can be used when wiring the output back to the input. In most cases however, it is more useful to use the opposing color of the wire so that it will not interfere with the resulting output and input.


=== Basic Arithmetic ===
When trying to understand combinators, your best friend is the in-game editor. You can pause the game and, with the "Tick once" keybinding, inspect nodes and networks as they go through different states.
----


Combinators can work in both positive and negative values, and is in base-10. This allows you to work with boolean values ''(0 or 1)'', and integer values.
== Virtual signals ==


Float points do not exist in Factorio, and will be instead be bit-shifted to the nearest integer. <br> ''(9.3 becomes 9) and (10.7 becomes 10)''
[[File:Virtual Signals dialog box.png|thumb|right|Virtual Signals available for use in the circuit network]]


There is a risk for integer overflow, as combinators use signed 32-bit int, meaning the numeric range is from ''-2,147,483,648'' to ''2,147,483,647'', as it can only hold 2³², or 4 billion+ values.
In addition to the standard item signals, Factorio's circuit network also includes a set of signals that do not represent any particular game item. Instead, these virtual signals serve as user-definable channels for the circuit network; they hold whatever meaning the user wants them to. There are currently 48 virtual signals that can be sent over the circuit network:


* The 36 alphanumeric characters (A-Z, 0-9)
* Nine colors: red, green, blue, yellow, magenta, cyan, white, grey, and black
* Three icons: a check mark, an informational letter 'i', and a small, white dot


----
=== Logic signals ===
''There is also an example heavy [[Circuit-network_Cookbook|circuit network cookbook]] that you may find helpful to learn and refer to about circuit networks.''


== Virtual Signals ==
There are three additional virtual signals known as ''logic signals''. Unlike other signals, they cannot be sent over the circuit network; instead, they apply additional logic to combinators that modify their behavior. Specifically, these logic symbols act as wildcards, which are special signals that represent '''zero or more''' arbitrary signals instead of representing a single discrete signal.  Factorio's circuit network implements three types of wildcards.


===Everything Wildcard:===
==== <span style="color:#FF6666">Everything wildcard</span> [[File:Signal_everything.png|left|20px]] ====
----


This Red Wildcard serves to check all the specifed input signals.
The ''Everything'' wildcard is used with decider combinators. Its exact behavior depends on whether it is used as an input or an output:
* '''Input''': Returns true if ''all'' input signals pass the condition, or if there are ''no'' input signals, otherwise it returns false.
* '''Output''': Returns ''all'' non-zero input signals.


As the Decider Combinator, <br />
When used as an input, the ''everything'' wildcard can be thought of as a logical AND, or a [[:Wikipedia:universal quantification|universal quantifier]]. When used as an output, it acts as an 'echo' or 'dump' of input signals.
its input is used to serve if all inputs meets the specified signals or variables. <br />
its output is used to serve output every signal. <br />


Side note: "Everything" outputs true by default even if there is no signal to guarantee if that is true. ''Everything is false when every input does not meet the condition, otherwise, output true.''
'''Note''': Can be used as an output as long as the input is not an ''each'' wildcard.


===Anything Wildcard:===
==== <span style="color:#99FF99">Anything wildcard</span> [[File:Signal_anything.png|left|20px]] ====
----


This Green Wildcard serves to check all the specifed input signals.
The ''Anything'' wildcard is also used with decider combinators.


As the Decider Combinator,  
Given '''at least one''' input signal, it returns true if ''any'' input signal passes the condition. If no signal passes the condition, or there are no input signals, then it returns false. From this behavior, the ''anything'' wildcard can be thought of as a logical OR, or an [[:Wikipedia:existential quantification|existential quantifier]].
its input is used to serve if any of its inputs meets the specified signals or variables.


Side note: "Anything" outputs false by default if there is no signal to guarantee if it is true. ''Anything is false when any of inputs do not meet the condition, otherwise, it is true.''
When used in both the input and output of a decider combinator, ''anything'' will return one of the signals that matched.


===Each Wildcard:===
==== <span style="color:#FFFF99">Each wildcard</span> [[File:Signal_each.png|left|20px]] ====
----


This Yellow Wildcard serves to check for each the specifed input signals.
The ''Each'' wildcard is used with both decider combinators and [[arithmetic combinator]]s, and behaves somewhat uniquely compared to the previous two. Generally speaking, it performs a combinator action on each signal '''individually''', with the exact action depending on how it is used, and the type of combinator it is used in. It can be used as an input, and it can be used as an output, but ''only when it is used as input as well''.


As the Decider Combinator, <br />
In a '''decider combinator''', when used as an input, the ''each'' wildcard individually compares each input signal against the combinator condition, returning each signal that passes the condition. The manner that the ''each'' wildcard returns signals when used as input depends on whether or not it is also used as output:
its input is used to serve if any inputs meets the specified signals or variables. <br />
* '''Input only''': Sums each input signal that passed the condition, and depending on output settings returns either a count of the passed signals or a summation of their values as the desired output signal.
its output is used to serve output the each variable. <br />
* '''Input and Output''': Returns each signal that passed the condition, their values depending on the output settings.


As the Arithmetic Combinator, <br />
In an '''arithmetic combinator''', the designated arithmetic operation is applied individually to each input signal, and similar to the decider combinator, the signal that is returned depends on whether or not the ''each'' wildcard is used as output:
its input is used to serve each input, then the following summations are summed and outputted, with each signal as its own respective signals.
* '''Input only''': The result of each operation on the input signals is summed and returned as the desired output signal.
* '''Input and Output''': Each input signal is returned with the result of the specified operation applied to it.


== Input Isolator & Gate ==
The ''Each'' wildcard is therefore notably more complex than the other two wildcards, but offers a good deal of power in exchange for its complexity.
An arithmetic combinator set to (In: Each + 0, Out: Each) can be used to swap wire colors and as an isolator to prevent downstream logic from backfeeding into the circuit network's inputs.


A decider combinator set to (Out: Everything, Input-> Output) will also function as an isolator as long as the set logic condition is true. This can also selectively pass or 'gate' inputs only when desired. This could be used to sequentially poll remote train stations for their chest contents, and include only desired stations.
== Input insulator & gate ==
An arithmetic combinator set to (In: Each + 0, Out: Each) can be used to swap wire colors and as an insulator to prevent downstream logic from backfeeding into the circuit network's inputs.


== Set/Reset Latching Switch ==
A decider combinator set to (Out: Everything, Input-> Output) will also function as an insulator as long as the set logic condition is true. This can also selectively pass or 'gate' inputs only when desired. This could be used to sequentially poll remote train stations for their chest contents, and include only desired stations.
You want something to SET a trigger at some quantity, but then STAY on until that quantity hits some other value, the RESET value. You'll need one decider combinator and one arithmetic combinator. Two decider combinators and a constant combinator can also be used for more complex multi-channel conditions.


Setup the first decider combinator to the desired set conditional and to output a 1. Then connect the output to the input of an arithmetic combinator, and configure it to multiply by the bias value, the difference between the set and reset values, and wire the arithmetic output to the input of the decider. The arithmetic output channel MUST be set the same as the decider's input channel. That's it! Whenever your set conditional is reached, the decider will output a '1', and the bias of the arithmetic combinator will be applied. This will 'hold' the output true until the value goes back below the reset point.
== Set/Reset latching switch ==
You want something to SET a trigger at some quantity, but then STAY on until that quantity hits some other value, the RESET value. You'll need one decider combinator and one arithmetic combinator. (Two decider combinators and a [[constant combinator]] can also be used for more complex multi-channel conditions.)


Here's a more specific example :
Setup the first decider combinator to the desired set conditional and to output a 1. Then connect the output to the input of an arithmetic combinator, and configure it to multiply by the bias value, which is the difference between the set and reset values, and wire the arithmetic output to the input of the decider. The arithmetic output channel must be set the same as the decider's input channel.<br>
i want the pump to run when petrol reach 2000, and turn off when reach 200.<br>
Whenever the set conditional is reached, the decider will output a '1', and the bias of the arithmetic combinator will be applied. This will 'hold' the output true until the value goes back below the reset point.
only with green wire<br>
Tank -> in decider<br>
out decider-> in arithmetic<br>
out arithmetic -> in decider<br>
green wire from in decider, to pump<br>


Pump have the same condition as the decider (Petrol > 2000)
In this specific example, the pump runs when light oil reaches 20000, and turns off when it reaches 5000:


Decider : Petrol > 2000<br>
[[File:SR_latch.png|600px]]
out : A = 1<br>
Arithmetic : A x 1800 (2000 - 200 )<br>
out : petrol<br>
[[File:Factorio combinator switch.png|620px]]


Backup steam power example with detailed configuration and explanation can be found here:<br />[[Tutorial:Circuit-network_Cookbook#SR_latch_-_single_decider_version|Tutorial:Circuit-network_Cookbook#SR latch - single decider version]]
A similar backup steam power example with detailed configuration and explanation can be found here:<br>[[Tutorial:Circuit_network_cookbook#RS_latch_-_single_decider_version|RS latch - single decider version]]


== Smart Train Loading ==
== Basic memory ==
A decider combinator can be used to store values, either for a counter or for more advanced logic (see below). The decider combinator is configured with
* input and output connected to the same network (typically each other),
* condition set to a signal > 0 for positive values or ≠ 0 to store both positive and negative values,
* output set to the input count of a specific input signal or [*].
As long as all inputs on the network are zero, it will hold the previously set value.


Initially designed by [https://www.youtube.com/user/Darkphade MadZuri],
Remember the two step update process from above? If the network has value [X]=5, the combinator will read this value from the network as its input, determine that it is > 0. It will then set the output to the input, which is [X]=5. In the next step, the value of the network will be computed, which is the sum of all the connected outputs, which is [X]=5, again.


This solves the problem of loading logistics into chests, which tend to be unequal and is slower in the rate of loading logistics into the cargo of trains.
A non-zero input held over time, e. g. the output of a constant combinator, will create a basic runaway clock. The stored value will be incremented by the sum of all connected input values every cycle. So e. g. with a constant combinator that produces [A]=1 connected to the memory, the network will store the value 1 in the first tick, 2 in the second, etc., incrementing 60 times per second.
{{BlueprintString|bp-string=0eNqlU11rwzAM/C96TkuStWvqh8F+xyghH2orSOygyGWh5L/PjkcJJetW9hKQLd2d7pwrlI3FjkkLqCtQZXQP6uMKPZ100fgzGToEBSTYQgS6aH1VY0U18qoybUm6EMMwRkC6xk9QyRj9CuCJpNCyjJCOhwhQCwlh0DMVQ65tWyI7iodAEXSmd7NGe36Ht9sk620EA6jVNsvWW8fk5oRNk5d4Li7khlznkRpB/sGAC7FYd3JjDh2rd5jQrHcwiWcmHAKLxsor6T1U4j8nRtTzpah2G7te4sqSTKWfHr2Nd3unjxJYWPtu6Zo4qAmECxZ8w+burqab7iNxL/mfLcEL8iBn0qfgTUgIVOyLtit4kqvgzU0aK539B3Y35JP5+ZFNm5N2YKCELY7P2J/MvF6II53CTJ9Lzz3h6c2r2T8WgZPfhwCyZLPbp7vsdR+/xJtx/AJNbzZ8}}


To setup the design, you require an Arithmetic Combinator, as well as Red and Green wires. '''Wire all the chests used, to the input of the Arithmetic Combinator'''. '''Then write (Logistics Item / -Amount of chests) and as the output as the Logistics Item in the Arithmetic Combinator''', this will average the amount of items within the chests. Lastly, '''wire all the inserters used to the output of the Arithmetic Combinator and have the other color of the wire be wired to the adjacent chest'''. '''Have the inserters enabled when Logistics Item < 1'''.
Again, how does this work in detail? The network will start without any values set. As soon as the constant combinator becomes active, it will produce [A]=1, and the decider combinator will produce 0 because no value is set yet. Step 2: The network will be set to the sum of all output, so [A]=1. In the next update tick, the constant combinator produces [A]=1 again, but now the decider sees [A]=1, so it would also output [A]=1. Step 2: The network is set to the sum, which is [A]=2. And so on.


A more visual representation as well as questions for the design can be found [https://www.reddit.com/r/factorio/comments/4e03g2/madzuris_smart_loading_train_station_guide/ here].
Typically a constant combinator producing 1 will be used, but of course it could output other values, including negative values.
A negative values would decrease the stored value in the example below.
If the decider combinator uses > 0 as the condition, only positive values will be allowed, so the value will stop decreasing if 0 is reached.
If the condition is ≠ 0, negative values will also be allowed.


Explanation of why this works:
A single pulse of an input will cause a single increment by the pulsed value, creating a counter. In the following blueprint, place one item on the belt. Every time it is scanned by the connected belt, a pulse is generated that increments the stored value.
It compares the average amount of total items within the chests and the chest adjacent to the inserter so that it activates when the average number of items is higher than the amount within the chest.
{{BlueprintString|bp-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 reason for why the division denominator is negative is because if the items in the chests are 0, it basically makes it so that it adds 1 to the equation.


== Memory ==
A stored value is cleared if the condition is no longer met, which makes the decider clear its output. This only works if the value is also not output elsewhere in the network. A stored value can also be reset to zero if a negative pulse equal to the input occurs. The latter can also happen while other inputs are still connected.
How to store a constant value for later use, either for a basic counter or for more advanced logic. A decider combinator wired output tied to input and configured greater than zero (for positive values), input -> output will 'hold' a value, as long as all other inputs on the network are zero.


Any non-zero input condition will create a basic clock; incrementing the stored value by the sum of all connected input values every cycle. A single pulse of an input will cause a single increment by the pulsed value. Reset to zero occurs whenever the set condition is no longer met, or if a negative pulse equal to the input occurs.
== Basic clocks ==
 
== Basic Clocks ==
[[File:Timer.png|thumb|right|377px|A basic clock. 30 ticks is the ceiling for Signal 1; which is continuously added.]]
[[File:Timer.png|thumb|right|377px|A basic clock. 30 ticks is the ceiling for Signal 1; which is continuously added.]]
Clocks are constructed by having the output of a combinator tied back to its own input, such that every cycle advances its own count. Either the arithmetic combinator or the decider combinator can be used.
Clocks are constructed by having the output of a combinator tied back to its own input, such that every cycle advances its own count. Either the arithmetic combinator or the decider combinator can be used.
Line 115: Line 106:
An arithmetic combinator tied to itself is fun to watch and will happily run-away, but requires additional control logic to reset.
An arithmetic combinator tied to itself is fun to watch and will happily run-away, but requires additional control logic to reset.


A self-resetting clock requires just a single decider combinator with output wired to input and configured with Less Than (<) and Input -> Output. When a constant combinator is then connected to the input, every cycle it will count up by the value of the Constant Combinator until the set conditional value is reached, then output a zero which will be summed with the constant combinator, and reset the process.
With a single decider combinator, a self-resetting clock can be built. Wire output to input and configure with Less Than (<) with a specific number, and Input -> Output. When a constant combinator is then connected to the input, every cycle it will count up by the output of the constant combinator until the number is reached. The decider will then clear its output, only the constant combinator will contribute to the value in the network, which resets the clock.


The clock sequence will not include zero, will begin at the value set by the constant combinator, and will include whatever value eventually causes the conditional to be false. An arithmetic combinator can modify the clock sequence but remember its outputs will occur one cycle later than the clock cycle values.
This means that the clock sequence will not include zero. It will begin at the value set in the constant combinator. Furthermore, it will include the number value that causes the conditional to become false. An arithmetic combinator can modify the clock sequence, but remember that its outputs will occur one cycle later than the clock cycle values.


A clock that only counts once can be built using the following setup:
A clock that only counts once can be built using the following setup. The clock can get reset by enabling and disabling the constant combinator that outputs [R].


[[File:Onetime_Clock.png|thumb|none|360px|One-time clock. Runs until T=Z+1. Reset via R>0.]]
[[File:Onetime_Clock.png|thumb|none|360px|One-time clock. Runs until T=Z+1. Reset via R>0.]]
{{BlueprintString|bp-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 ==
== Pulse generators ==


Connecting an additional (=) decider combinator to the output of a basic clock will create a pulse generator, and will pulse a single output every time the clock cycles through the set condition. Any output value can be used, either directly from the clock sequence (input->output), a 1, or some value on a separate logic channel on the circuit network, such as set by a constant combinator. or by the circuit network.<br />
Connecting an additional (=) decider combinator to the output of a basic clock will create a pulse generator, and will pulse a single output every time the clock cycles through the set condition. Any output value can be used, either directly from the clock sequence (input->output), a 1, or some value on a separate logic channel on the circuit network, such as set by a constant combinator. or by the circuit network.<br />
Line 130: Line 122:
*''As an example from the above timer, this light will pulse every 1st tick after the timer reaches 30 ticks, making it pulse 1/30th of a second, as Factorio updates at 60 times per second.''
*''As an example from the above timer, this light will pulse every 1st tick after the timer reaches 30 ticks, making it pulse 1/30th of a second, as Factorio updates at 60 times per second.''


== Counter ==
== Edge detectors ==
A counter is used to count the number of input events, and output the sum of that count. Any pulsing input into a decider combinator configured input -> output and wired between output and input will create a counter, but this input must be zero at all other times or else the combinator will run away like a clock. A pulse generator is normally used to accomplish this. Combining several gating decider isolators set with sequential conditionals, a clock, and a pulse generator to the input of a counter will allow remote polling and counting of each isolator's contents.


== Logic Gates ==
The computation delay of combinators can be used to generate a one-tick pulse when a signal changes, e. g. from 0 to 1.


==='''Unary NOT'''===
Connect an output of a combinator with red to the input, and with green to the output of an arithmetic combinator that multiplies by -1. When the red circuit changes a signal from 0 to 1, the arithmetic combinator gets input 1, but the output is still 0. So the green wire has value 1 for this one tick. In the next tick, the arithmetic combinator updates, so the output switches to -1. The green wire now has two inputs that cancel each other out. The same happens if the red input signal changes from 1 to 0, but in this case the green wire becomes -1 for one tick.
----
[[File:NOT.png|415px]]


Truth Table:
If you're only interested in generating a pulse if the signal changes from 0 to 1, a decider combinator set to >0 can be used to filter out the negative pulses. This mechanic can e. g. be used to count the numbers of trains that enter a station.


{| class="wikitable"
== Counter ==
|-
A counter is used to count the number of input events, and output the sum of that count. Any pulsing input into a decider combinator configured input -> output and wired between output and input will create a counter, but this input must be zero at all other times or else the combinator will run away like a clock. A pulse generator is normally used to accomplish this. Combining several gating decider isolators set with sequential conditionals, a clock, and a pulse generator to the input of a counter will allow remote polling and counting of each isolator's contents.
!Input!!Output
|-
| 0 || 1
|-
| 1 || 0
|-
|}
 
==='''Binary OR'''===
----
[[File:OR.png|300px]]
 
Truth Table:
 
{| class="wikitable"
|-
!Input 1!!Input 2!!Output
|-
| 0 || 0  || 0
|-
| 0 || 1  || 1
|-
| 1 || 0  || 1
|-
| 1 || 1  || 1
|-
|}
 
''*Deprecated: Use the Arithmetic Combinator's OR option instead.''
 
==='''Binary NOR'''===
----
[[File:NOR.png|415px]]
 
Truth Table:
 
{| class="wikitable"
|-
!Input 1!!Input 2!!Output
|-
| 0 || 0  || 1
|-
| 0 || 1  || 0
|-
| 1 || 0  || 0
|-
| 1 || 1  || 0
|-
|}
 
 
==='''Binary XOR'''===
----
[[File:XOR.png|300px]]
 
Truth Table:
 
{| class="wikitable"
|-
!Input 1!!Input 1!!Output
|-
| 0 ||  0 || 0
|-
| 0 ||  1 || 1
|-
| 1 ||  0 || 1
|-
| 1 ||  1 || 0
|-
|}
 
''*Deprecated: Use the Arithmetic Combinator's XOR option instead.''
 
==='''Binary AND'''===
----
[[File:AND.png|530px]]
 
Truth Table:
 
{| class="wikitable"
|-
!Input 1!!Input 2!!Output
|-
| 0 || 0 || 0
|-
| 0 || 1 || 0
|-
| 1 || 0 || 0
|-
| 1 || 1 || 1
|-
|}
 
''*Deprecated: Use the Arithmetic Combinator's AND option instead.''
 
==='''Trinary AND'''===
----
[[File:TrinaryAND.png|415px]]
 
Truth Table:
 
{| class="wikitable"
|-
!Input 1!!Input 2!!Input 3!!Output
|-
| 0 || 0  || 0  || 0
|-
| 0 || 1  || 0  || 0
|-
| 0 || 0  || 1  || 0
|-
| 0 || 1  || 1  || 0
|-
| 1 || 0  || 0  || 0
|-
| 1 || 1  || 0  || 0
|-
| 1 || 0  || 1  || 0
|-
| 1 || 1  || 1  || 1
|-
|}
 
==='''Binary NAND'''===
----
[[File:NAND.png|300px]]


Truth Table:
== Memory cells ==


{| class="wikitable"
=== Simple latch ===
|-
!Input 1!!Input 2!!Output
|-
| 0 || 0  || 1
|-
| 0 || 1  || 1
|-
| 1 || 0  || 1
|-
| 1 || 1  || 0
|-
|}


==='''Binary XNOR/XAND'''===
When looping the combinator to itself, use a different color of wire from your main inputs or outputs.  
----
[[File:XAND.png|300px]]


Truth Table:
[[File:SimpleLatchv2.png|415px]]
 
{| class="wikitable"
|-
!Input 1!!Input 2!!Output
|-
| 0 || 0  || 1
|-
| 0 || 1  || 0
|-
| 1 || 0  || 0
|-
| 1 || 1  || 1
|-
|}
 
== Memory Cells ==
 
==='''Simple Latch'''===
 
When looping the combinator to itself, use a different colour of wire from your main inputs or outputs.
 
[[File:SimpleLatchv2.png|300px]]


Truth Table:
Truth Table:
Line 341: Line 168:
''Input 1 is Set, while Input 2 is Reset.''
''Input 1 is Set, while Input 2 is Reset.''


==='''Binary Cell'''===
=== Positive cell ===
 
Cell for storing a positive value, with reset support:
 
[[File:AdvancedMemoryCell.png|500px]]
 
Connect the desired value as signal I on the right side to set the memory cell and connect a negative value as signal I to reset the cell.


RS NOR Latch
* The output of the memory cell is 2 mutually exclusive signals.
[[File:RS-NOR.png|500px]]
** In case input signal I > 0 then signal I is passed to the other side.
** In case input signal I is interrupted, then signal M is passed instead as a memory of previous input value.
* When input signal I is interrupted, it takes 2 ticks to switch to memory signal M.
* In case input I signal lasts only one tick then memory cell starts to cycle between the 2 previous values, tick by tick. Indefinitely.
* Switching is seamless, e.g. there are no ticks with empty signal.


=== Positives and negatives cell ===


This cell can store negatives or positives. Reset is done on a dedicated line. Additionally, a 1-tick burst is handled properly. [https://forums.factorio.com/viewtopic.php?f=193&t=60330&p=362377#p362377 Forum post].


==='''Advanced Cell'''===
* The output M (memory) is the last non-zero input I (Input).
* A non zero R (reset) signal sets the output to zero.
* 1-tick bursts of R or I are handled properly.
* Negatives are handled properly.


Cell for storing a positive value:
[[File:Memory_cell_with_negatives.png|500px]]


[[File:AdvancedMemoryCell.png|500px]]
== Multiplier and Dictionaries/Arrays ==
[[File:combinatorMultiplierDetailed.png|left|500px]]
* Multiplying two signals together is simple and requires only a single combinator, however multiplying a set of signals is more complicated.
* A proof is shown below for the equation and why it works.
* A dictionary is a system that allows a value on a specific signal to be accessed. For example, A can contain many signals (either from a constant combinator or memory cell) and B can contain 1 of a specific signal (such as blue signal). What remains is the blue-signal value from A. This is because all the other signals are multiplied by 0.
* Arrays are similar to dictionaries, but instead of using a signal as a key, we use a number. Constant combinators are placed mapping each signal to a unique number (such as 1 yellow belt, 2 red belt, 3 blue belt, 4 burner inserter, etc). Then, use a combinator of "each = index OUTPUT 1 of each" and plug that in as the input to a dictionary.{{clear}}
[[File:combinatorMultiplierMath.png|left|500px]]


Connect the desired value as signal 3 on the right side to set the memory cell and connect a negative value as signal 3 to reset the cell.  *Please note the arithmetic combinator's output should be facing the opposite direction of the decider combinators.
    ((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


'''Address Enable Switch'''
{{clear}}


== See Also ==
== See Also ==
*[http://www.factorioforums.com/forum/viewtopic.php?f=18&t=14556 Combinators 101 (Tutorial)]
* [http://www.factorioforums.com/forum/viewtopic.php?f=18&t=14556 Combinators 101 (Tutorial)]
*[[Arithmetic combinator]]
* [[Tutorial:Circuit network cookbook]]
*[[Constant combinator]]
* [[Circuit network]]
*[[Decider combinator]]
* [[Arithmetic combinator]]
*[[Circuit network]]
* [[Constant combinator]]
*[[Circuit-network_Cookbook]]
* [[Decider combinator]]

Latest revision as of 15:24, 30 August 2024

This is an advanced tutorial. Beginners should refer to the Tutorial:Circuit network cookbook for examples and the Circuit network page for an overview over the circuit network. This tutorial assumes a basic understanding of circuits and covers more advanced topics like SR latches, memory cells and clocks.

Introduction

Combinator logic is achieved by cross-connecting outputs to inputs in such a way to achieve the desired logic. While advanced logic requires a multitude of combinators, some very useful basic logic can be achieved using only a handful of combinators. Combinator logic works because Factorio only updates at 60 times per second. Logically, each update tick is separated into two steps. In the first step, all combinators first read the input from the connected network(s), perform their computations. This produces an output value for every combinator. The tick update concludes with the second step, where the values of each network will be updated as the sum of all connected values.

When logic values are computed by combinators, the outputs are not recognized by the circuit network until the following step. So when a decider combinator is used to detect a certain input condition, its output value will not take effect on the circuit network until the next step. This behavior is important to remember and can result in sequencing errors and significant delays when multiple combinators are connected in series.

Circuit wires act like a wire bus in electronics; they carry information in the connected wires, meaning that if there are similar signals on a wire it will add them automatically. If the signal is different, it will be carried in that wire as well, but as a different signal.

When cross-connecting combinators, it is good practice to use the unused color to cross-connect, this will split the input and output networks and prevent unwanted inputs from accidentally connecting to a larger circuit network. Combinators will sum the red and green inputs prior to calculation, so either color can be used when wiring the output back to the input. In most cases however, it is more useful to use the opposing color of the wire so that it will not interfere with the resulting output and input.

When trying to understand combinators, your best friend is the in-game editor. You can pause the game and, with the "Tick once" keybinding, inspect nodes and networks as they go through different states.

Virtual signals

Virtual Signals available for use in the circuit network

In addition to the standard item signals, Factorio's circuit network also includes a set of signals that do not represent any particular game item. Instead, these virtual signals serve as user-definable channels for the circuit network; they hold whatever meaning the user wants them to. There are currently 48 virtual signals that can be sent over the circuit network:

  • The 36 alphanumeric characters (A-Z, 0-9)
  • Nine colors: red, green, blue, yellow, magenta, cyan, white, grey, and black
  • Three icons: a check mark, an informational letter 'i', and a small, white dot

Logic signals

There are three additional virtual signals known as logic signals. Unlike other signals, they cannot be sent over the circuit network; instead, they apply additional logic to combinators that modify their behavior. Specifically, these logic symbols act as wildcards, which are special signals that represent zero or more arbitrary signals instead of representing a single discrete signal. Factorio's circuit network implements three types of wildcards.

Everything wildcard
Signal everything.png

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

  • Input: Returns true if all input signals pass the condition, or if there are no input signals, otherwise it returns false.
  • Output: Returns all non-zero input signals.

When used as an input, the everything wildcard can be thought of as a logical AND, or a universal quantifier. When used as an output, it acts as an 'echo' or 'dump' of input signals.

Note: Can be used as an output as long as the input is not an each wildcard.

Anything wildcard
Signal anything.png

The Anything wildcard is also used with decider combinators.

Given at least one input signal, it returns true if any input signal passes the condition. If no signal passes the condition, or there are no input signals, then it returns false. From this behavior, the anything wildcard can be thought of as a logical OR, or an existential quantifier.

When used in both the input and output of a decider combinator, anything will return one of the signals that matched.

Each wildcard
Signal each.png

The Each wildcard is used with both decider combinators and arithmetic combinators, and behaves somewhat uniquely compared to the previous two. Generally speaking, it performs a combinator action on each signal individually, with the exact action depending on how it is used, and the type of combinator it is used in. It can be used as an input, and it can be used as an output, but only when it is used as input as well.

In a decider combinator, when used as an input, the each wildcard individually compares each input signal against the combinator condition, returning each signal that passes the condition. The manner that the each wildcard returns signals when used as input depends on whether or not it is also used as output:

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

In an arithmetic combinator, the designated arithmetic operation is applied individually to each input signal, and similar to the decider combinator, the signal that is returned depends on whether or not the each wildcard is used as output:

  • Input only: The result of each operation on the input signals is summed and returned as the desired output signal.
  • Input and Output: Each input signal is returned with the result of the specified operation applied to it.

The Each wildcard is therefore notably more complex than the other two wildcards, but offers a good deal of power in exchange for its complexity.

Input insulator & gate

An arithmetic combinator set to (In: Each + 0, Out: Each) can be used to swap wire colors and as an insulator to prevent downstream logic from backfeeding into the circuit network's inputs.

A decider combinator set to (Out: Everything, Input-> Output) will also function as an insulator as long as the set logic condition is true. This can also selectively pass or 'gate' inputs only when desired. This could be used to sequentially poll remote train stations for their chest contents, and include only desired stations.

Set/Reset latching switch

You want something to SET a trigger at some quantity, but then STAY on until that quantity hits some other value, the RESET value. You'll need one decider combinator and one arithmetic combinator. (Two decider combinators and a constant combinator can also be used for more complex multi-channel conditions.)

Setup the first decider combinator to the desired set conditional and to output a 1. Then connect the output to the input of an arithmetic combinator, and configure it to multiply by the bias value, which is the difference between the set and reset values, and wire the arithmetic output to the input of the decider. The arithmetic output channel must be set the same as the decider's input channel.
Whenever the set conditional is reached, the decider will output a '1', and the bias of the arithmetic combinator will be applied. This will 'hold' the output true until the value goes back below the reset point.

In this specific example, the pump runs when light oil reaches 20000, and turns off when it reaches 5000:

SR latch.png

A similar backup steam power example with detailed configuration and explanation can be found here:
RS latch - single decider version

Basic memory

A decider combinator can be used to store values, either for a counter or for more advanced logic (see below). The decider combinator is configured with

  • input and output connected to the same network (typically each other),
  • condition set to a signal > 0 for positive values or ≠ 0 to store both positive and negative values,
  • output set to the input count of a specific input signal or [*].

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

Remember the two step update process from above? If the network has value [X]=5, the combinator will read this value from the network as its input, determine that it is > 0. It will then set the output to the input, which is [X]=5. In the next step, the value of the network will be computed, which is the sum of all the connected outputs, which is [X]=5, again.

A non-zero input held over time, e. g. the output of a constant combinator, will create a basic runaway clock. The stored value will be incremented by the sum of all connected input values every cycle. So e. g. with a constant combinator that produces [A]=1 connected to the memory, the network will store the value 1 in the first tick, 2 in the second, etc., incrementing 60 times per second.

Blueprint.png  Copy blueprint string

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

Again, how does this work in detail? The network will start without any values set. As soon as the constant combinator becomes active, it will produce [A]=1, and the decider combinator will produce 0 because no value is set yet. Step 2: The network will be set to the sum of all output, so [A]=1. In the next update tick, the constant combinator produces [A]=1 again, but now the decider sees [A]=1, so it would also output [A]=1. Step 2: The network is set to the sum, which is [A]=2. And so on.

Typically a constant combinator producing 1 will be used, but of course it could output other values, including negative values. A negative values would decrease the stored value in the example below. If the decider combinator uses > 0 as the condition, only positive values will be allowed, so the value will stop decreasing if 0 is reached. If the condition is ≠ 0, negative values will also be allowed.

A single pulse of an input will cause a single increment by the pulsed value, creating a counter. In the following blueprint, place one item on the belt. Every time it is scanned by the connected belt, a pulse is generated that increments the stored value.

Blueprint.png  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=

A stored value is cleared if the condition is no longer met, which makes the decider clear its output. This only works if the value is also not output elsewhere in the network. A stored value can also be reset to zero if a negative pulse equal to the input occurs. The latter can also happen while other inputs are still connected.

Basic clocks

A basic clock. 30 ticks is the ceiling for Signal 1; which is continuously added.

Clocks are constructed by having the output of a combinator tied back to its own input, such that every cycle advances its own count. Either the arithmetic combinator or the decider combinator can be used.

An arithmetic combinator tied to itself is fun to watch and will happily run-away, but requires additional control logic to reset.

With a single decider combinator, a self-resetting clock can be built. Wire output to input and configure with Less Than (<) with a specific number, and Input -> Output. When a constant combinator is then connected to the input, every cycle it will count up by the output of the constant combinator until the number is reached. The decider will then clear its output, only the constant combinator will contribute to the value in the network, which resets the clock.

This means that the clock sequence will not include zero. It will begin at the value set in the constant combinator. Furthermore, it will include the number value that causes the conditional to become false. An arithmetic combinator can modify the clock sequence, but remember that its outputs will occur one cycle later than the clock cycle values.

A clock that only counts once can be built using the following setup. The clock can get reset by enabling and disabling the constant combinator that outputs [R].

One-time clock. Runs until T=Z+1. Reset via R>0.
Blueprint.png  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

Connecting an additional (=) decider combinator to the output of a basic clock will create a pulse generator, and will pulse a single output every time the clock cycles through the set condition. Any output value can be used, either directly from the clock sequence (input->output), a 1, or some value on a separate logic channel on the circuit network, such as set by a constant combinator. or by the circuit network.
PulseGen.png

  • The value 1 can be written as any positive integer, so long as it is within the cap or ceiling of your timer.
  • As an example from the above timer, this light will pulse every 1st tick after the timer reaches 30 ticks, making it pulse 1/30th of a second, as Factorio updates at 60 times per second.

Edge detectors

The computation delay of combinators can be used to generate a one-tick pulse when a signal changes, e. g. from 0 to 1.

Connect an output of a combinator with red to the input, and with green to the output of an arithmetic combinator that multiplies by -1. When the red circuit changes a signal from 0 to 1, the arithmetic combinator gets input 1, but the output is still 0. So the green wire has value 1 for this one tick. In the next tick, the arithmetic combinator updates, so the output switches to -1. The green wire now has two inputs that cancel each other out. The same happens if the red input signal changes from 1 to 0, but in this case the green wire becomes -1 for one tick.

If you're only interested in generating a pulse if the signal changes from 0 to 1, a decider combinator set to >0 can be used to filter out the negative pulses. This mechanic can e. g. be used to count the numbers of trains that enter a station.

Counter

A counter is used to count the number of input events, and output the sum of that count. Any pulsing input into a decider combinator configured input -> output and wired between output and input will create a counter, but this input must be zero at all other times or else the combinator will run away like a clock. A pulse generator is normally used to accomplish this. Combining several gating decider isolators set with sequential conditionals, a clock, and a pulse generator to the input of a counter will allow remote polling and counting of each isolator's contents.

Memory cells

Simple latch

When looping the combinator to itself, use a different color of wire from your main inputs or outputs.

SimpleLatchv2.png

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 seen in the picture, it carries the value to latch.

Input 1 is Set, while Input 2 is Reset.

Positive cell

Cell for storing a positive value, with reset support:

AdvancedMemoryCell.png

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

  • The output of the memory cell is 2 mutually exclusive signals.
    • In case input signal I > 0 then signal I is passed to the other side.
    • In case input signal I is interrupted, then signal M is passed instead as a memory of previous input value.
  • When input signal I is interrupted, it takes 2 ticks to switch to memory signal M.
  • In case input I signal lasts only one tick then memory cell starts to cycle between the 2 previous values, tick by tick. Indefinitely.
  • Switching is seamless, e.g. there are no ticks with empty signal.

Positives and negatives cell

This cell can store negatives or positives. Reset is done on a dedicated line. Additionally, a 1-tick burst is handled properly. Forum post.

  • The output M (memory) is the last non-zero input I (Input).
  • A non zero R (reset) signal sets the output to zero.
  • 1-tick bursts of R or I are handled properly.
  • Negatives are handled properly.

Memory cell with negatives.png

Multiplier and Dictionaries/Arrays

CombinatorMultiplierDetailed.png
  • Multiplying two signals together is simple and requires only a single combinator, however multiplying a set of signals is more complicated.
  • A proof is shown below for the equation and why it works.
  • A dictionary is a system that allows a value on a specific signal to be accessed. For example, A can contain many signals (either from a constant combinator or memory cell) and B can contain 1 of a specific signal (such as blue signal). What remains is the blue-signal value from A. This is because all the other signals are multiplied by 0.
  • Arrays are similar to dictionaries, but instead of using a signal as a key, we use a number. Constant combinators are placed mapping each signal to a unique number (such as 1 yellow belt, 2 red belt, 3 blue belt, 4 burner inserter, etc). Then, use a combinator of "each = index OUTPUT 1 of each" and plug that in as the input to a dictionary.
CombinatorMultiplierMath.png
   ((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