组合器 教程

2026-05-22

组合器 教程 — 从 wiki.factorio.com 导入的高级电路网络指南,涵盖锁存、存储单元和时钟等主题

这篇教程的目标读者

如果你已经能用判断组合器接灯、用算术组合器算乘除,并且在论坛上看见 SR 锁存、记忆单元、时钟、字典之类的词汇时想知道它们到底怎么搭出来,这篇教程就是为你写的。
本文不解释「什么是电路网络」 这种入门概念,那部分请看食谱版的入门教程。
接下来要讲的内容包含锁存、存储、时钟、脉冲、边沿检测、字典,全部都基于组合器的两步更新机制,是真正算得上「组合器逻辑」 的部分。

实际玩下来,这些结构最容易卡住的不是规则本身,而是「两步更新」 的时序——组合器先读取输入算出输出值、之后网络再把全部输出求和形成新的网络值,这两步之间的逻辑顺序如果搞反了,就会出现「为什么这个值晚了一拍」 的经典困扰。
理解了之后,后面所有的锁存、时钟、记忆单元都是同一套思路的不同组合。

关于版本与编辑器

本文以 2.0 之后的 GUI 与电路网络规则为基础,旧版本里那些 Each 信号的细节差异在这里不复存在,如果你看到的旧教程截图与本文行为对不上,多半是版本差异,不必怀疑自己的搭法。
试图理解组合器时,编辑器是最好的朋友:暂停游戏,使用 Tick once 快捷键让节点与网络一步步推进,每步观察输入与输出的具体数值,再复杂的结构在 5-10 个 tick 之内也能看懂。

组合器逻辑的物理学

要把组合器组合出有用的逻辑,关键是把组合器的输出绕回输入端形成反馈。
听上去像硬件电路里的触发器,本质也确实差不多。
之所以行得通,是因为 Factorio 每秒只更新 60 次,逻辑上每个 tick 分为两个明确的步骤:所有组合器先从连接的网络读取输入并算出新输出,然后网络把所有连接的输出值求和形成新的网络值。

两步更新带来的延迟

判断组合器算出的逻辑值,要到下一个 tick 才会对网络生效。
多个组合器串联起来时,这个延迟会逐级累积,每多一级就多一拍延迟,10 个组合器串起来的链路就会有 10 tick 的固定滞后,时序错误和显著延迟都来自这里。
设计时如果不在心里画出这个 tick 表,很容易在做时钟、脉冲、计数器时被「为什么晚一拍」 困扰半天。

红线与绿线的合并规则

电路导线行为类似电子电路里的总线,导线上同名信号会自动求和、异名信号各自传输。
组合器在算之前会把红线和绿线的输入合并,所以反馈回路用哪种颜色都行。
一般做法是「主线用红线、反馈用绿线」 这种对调安排,能让蓝图截图更易读,调试时也方便用过滤器分辨。

虚拟信号与逻辑通配符

除了普通物品信号外,电路网络还有一组不对应任何物品的虚拟信号,用作玩家自定义的通道。

虚拟信号一览

目前可在电路网络上传输的虚拟信号有 102 个(Space Age 里是 172 个),分布在 Signals、Enemies、Environment、Unsorted 几个标签页里,常见类别如下。

  • 36 个字母数字字符(A-Z、 0-9)。
  • 9 种颜色:red、green、blue、yellow、magenta、cyan、white、grey、black。
  • 25 个图标:各种十字、线条与箭头。
  • 全部敌人类型。
  • 全部环境对象:树、岩石、玩家、悬崖
  • 两种导线,以及 spidertron、放电、长距离炮遥控器等。

实际项目里你大概率会重度使用字母信号 A-Z,配合常数组合器做出可读的状态标签,比如把「S」 当作 set 通道、「R」 当作 reset 通道、「C」 当作 clock 通道,这样组合器堆得再多也能在 alt-mode 下一眼看懂。

Everything 通配符

Everything 通配符(图标是星号)专用于判断组合器,行为按用作输入还是输出而不同。

  • 作为输入:当全部输入信号都通过条件、或没有任何输入时返回 true,否则 false。
    等价于逻辑 AND 或全称量词。
  • 作为输出:返回所有非零输入信号。
    起到「回显」 或「转储」 的作用。

注意:只要输入不是 Each,就可以把 Everything 当作输出。

Anything 通配符

Anything 通配符也只在判断组合器里出现。
至少有一个输入时,任何输入信号满足条件就返回 true;没有信号满足条件或干脆没输入则返回 false。
它等价于逻辑 OR 或存在量词。
在输入与输出同时用 Anything 时,会返回匹配到的某个信号本身。

Each 通配符

Each 在判断组合器和算术组合器里都能用,行为远比前两个复杂,本质是「对每个输入信号单独执行一遍组合器动作」。
它可以作输入、也可以作输出,但只在自身被用作输入时才能同时作输出。

在判断组合器里,Each 把每个输入信号分别和条件比较,返回每个通过的信号。
返回方式取决于是否也用作输出:

  • 仅作输入:把每个通过条件的输入信号求和,根据输出设置返回信号计数或值的总和。
  • 同时作输入与输出:返回每个通过条件的信号,值按输出设置决定。

在算术组合器里,运算单独应用到每个输入信号上:

  • 仅作输入:把每路运算结果求和,作为所需输出信号返回。
  • 同时作输入与输出:返回每个输入信号,值是应用运算后的结果。

灵活归灵活,初学者第一次写 Each 时八成会写错,强烈建议用编辑器单步跟一遍,把每个 tick 的输入信号束、运算结果、输出信号束都用纸笔列出来对照,这是搞清 Each 行为最有效的办法。

实用「绝缘体」 与门

把算术组合器设为「In: Each + 0, Out: Each」,可以用作绝缘体:交换线色、防止下游逻辑回流到输入端。
这种做法在大型电路里几乎是标配,能干净地把子模块与主电网分开。

把判断组合器设为「Out: Everything, Input→Output」,则在条件成立时充当绝缘体兼门,可以按需「门控」 输入。
例如想顺序轮询若干远程火车站的箱子内容、只让目标站点的数据通过时,就靠这个结构。

设置/重置锁存器(SR Latch)

如果你需要一个「达到某数值时 SET、达到另一数值时 RESET」 的开关,最经典的实现是一个判断组合器加一个算术组合器,能覆盖大多数滞回控制场景。

基本结构

  • 判断组合器:设置成 set 条件,输出 1。
  • 算术组合器:把判断器的输出乘以「set 与 reset 的差值」 作为偏置。
  • 把算术组合器的输出回连到判断器输入。
  • 算术输出信号必须与判断器的输入信号相同。

每当 set 条件达成时,判断器输出 1,算术组合器把这个 1 放大成偏置,再加回输入端,从而让输出维持 true,直到实际值跌回 reset 阈值以下。

具体例子

让某泵在轻油 ≥ 20000 时开启、跌到 5000 时关闭:

  • set 阈值:light oil ≥ 20000。
  • reset 阈值:light oil ≤ 5000。
  • 偏置:15000,作为算术组合器的乘数。

这种「滞回」 在工业控制里叫 hysteresis,能避免开关在阈值附近反复抖动,是任何变量控制的基本范式,从家用空调到工业 PID 控制器都在用这个套路,Factorio 里只是把它简化到了 2 个组合器的最小规模。

基础存储单元

判断组合器可以用来「记住」 一个值,是更复杂逻辑的基础。

标准配置

  • 输入和输出连到同一网络(一般直接相连成回路)。
  • 条件设为「某信号 > 0」 仅存正值,或「≠ 0」 正负皆存。
  • 输出设为该信号的 input count 或 input value。

只要网络上没有新的输入扰动,存储单元就会维持之前的值不变。

两步更新如何让值「记住」

如果网络上某信号当前为 5,组合器读到 5、判断 > 0 为真、输出 5。
下一步网络求和又是 5。
这样 5 就在循环里被持续传递下去,等同于「保存」。

自增时钟的雏形

把一个常数组合器接到存储单元,每 tick 把常数加上现有值,存储值就会以每秒 60 次的速度递增。
例如常数 1,第一 tick 存储 1、第二 tick 存储 2、以此类推。
把这个机制反过来用、加负值就能减少,再用条件门控就能做出受控计数器。

计数器范例

把一个脉冲(来自每次抓取物品的快速插入器)接入存储单元,每次脉冲会让存储值跳跃一次,从而做出累计计数器,可以统计这条插入器自工厂开始运转以来搬过的所有物品总数,玩到通关时这个数字往往会让你大吃一惊。
配合常数组合器与判断器的清零条件,还能做成「每 24 小时归零一次」 的日统计板,挂在主基地门口能让基地访客直接读到日均产能。

时钟与脉冲发生器

通过把组合器的输出接回自身输入,可以做出每 tick 推进一次自身计数的时钟,算术与判断组合器都可以扮演这个角色。

自连接算术时钟

自连接的算术组合器会无止境地自增,需要外部逻辑才能复位,所以一般只在临时调试时用。

自复位判断时钟

用单个判断组合器加 Input→Output,条件设为「value < 阈值」,外接一个常数组合器输出 1。
每 tick 累加 1,到达阈值时判断器清零输出,下一个 tick 又从 1 开始。
这种时钟在脉冲发生、间歇控制里出场率最高。

注意计数序列不包含 0,从常数组合器设置的起点开始,且包含让条件变为 false 的那个数值。
周期严格的场景下要把阈值减 1(例如要 60 tick 一次的话设 59)。

把常数组合器省掉

可以在输出里加一个常数 1,从而省掉外部常数组合器。
注意这一版会在阈值瞬间多计数 1 个 tick(像编程里 0-based 与 1-based 计数的差别),所以高精度场景下要相应调整阈值。

脉冲发生器

在时钟的输出端再接一个判断组合器(条件 = 阈值),就成了脉冲发生器:每到设定值就喷出 1 个 tick 的脉冲。
脉冲值可以取时钟值本身、固定 1、或者外部常数组合器的值,灵活适配不同下游需求。

边沿检测器

组合器的固有延迟可以用来检测信号的瞬变。
比如想知道某信号「从 0 变成 1」 的那一瞬间,可以让红线把信号接回自身、绿线接到一个把输入乘以 -1 的算术组合器。
当红线某信号从 0 变到 1,绿线那 tick 上就会出现一个 1 的瞬时脉冲,下一 tick 算术组合器更新后两路抵消变 0,整体效果就是只发出一个 tick 长的脉冲。

过滤负脉冲

如果只想检测「上升沿」 而不要「下降沿」,给输出再加一个判断组合器 > 0 过滤掉负脉冲即可。
该结构非常适合用来统计进入车站的列车数量、火箭发射次数、或者敌人攻击次数等离散事件,所有「我想数一下某件事发生了几次」 的场景都可以借助它实现。

计数器结构

计数器在脉冲发生器的基础上,加一个 Input→Output 的判断组合器、把输出回连到输入端,就成了累计计数器。
关键点是输入「平时必须为零」,否则计数器会像时钟那样失控。
把若干带门控的隔离器配合时钟和脉冲发生器接到计数器输入端,可以远程轮询多个不同位置的箱子内容并加总。

记忆单元(多变体)

把组合器回连到自身时,记得用与主输入/主输出不同的颜色,避免内部状态泄漏到外部网络上。

简易锁存的真值表

简易锁存有两个输入(Input 1 = Set、Input 2 = Reset)与一个输出(Output 1),转移规则如下:

  • Output=0、Input1=0、Input2=0 → 下一 tick Output=0。
  • Output=0、Input1=1、Input2=0 → 下一 tick Output=1(被置位)。
  • Output=0、Input1=0、Input2=1 → 下一 tick Output=0。
  • Output=0、Input1=1、Input2=1 → 下一 tick Output=0(同时为 1 时复位)。
  • Output=1、Input1=0、Input2=0 → 下一 tick Output=1(维持)。
  • Output=1、Input1=1、Input2=0 → 下一 tick Output=1。
  • Output=1、Input1=0、Input2=1 → 下一 tick Output=0(复位)。
  • Output=1、Input1=1、Input2=1 → 下一 tick Output=1(同时为 1 时维持)。

记住「Set 与 Reset 同时为真时锁存保持哪一边」 是 SR / RS 锁存命名的关键差异。

正值存储单元

存储正值并可重置的单元。
把目标值作为 I 信号接入即可设置,把负值作为 I 接入即可重置:

  • 输出是两个互斥信号 I 和 M。
  • 当输入 I > 0 时,I 被传到对侧。
  • 当输入 I 中断时,M 作为前一个输入值的「记忆」 接替输出。
  • 从 I 切到 M 需要 2 个 tick。
  • 若 I 只持续 1 tick,单元会在前两个值之间逐 tick 交替循环、无限循环。
  • 切换是无缝的,不会出现「空信号」 的 tick。

正负值存储单元

这一版可以同时存正值与负值,重置走专用线路,1 tick 的脉冲也能被正确处理。

  • 输出 M 是最后一个非零输入 I。
  • 非零的 R 信号会把输出清零。
  • R 或 I 的 1 tick 脉冲都能正确处理。
  • 负值同样支持。

乘法器、字典与数组

把两个信号相乘只需 1 个组合器,但把一组信号同时相乘就需要多组合器配合,下面的代数式给出原理证明。

两数相乘的恒等式

要把 A 和 B 两个信号相乘,可以套用以下恒等式:

((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

把 (A+B)^2 与 (A-B)^2 各自用算术组合器做出来,相减再除 4,就得到 AB。
这个套路是后续字典查表、数组寻址的底层基石。

字典:按信号取值

字典是一种把「信号当 key」 的结构。
比如 A 信号束里有许多信号(来自常数组合器或存储单元)、B 信号束只有一个特定信号(例如蓝色信号),把 A 与 B 配合相乘后,剩下的只是 A 中对应蓝色键的值,其他信号都被乘以 0 抹掉。

数组:按数字取值

数组类似字典,但用数字作 key。
常数组合器把每个信号映射成唯一编号(1=黄带、2=红带、3=蓝带、4=燃烧抓取器……),再用一个组合器设为「each = index OUTPUT 1 of each」,最后接到字典输入端,就可以按下标取值。

后续推荐

把上述基础结构练熟之后,组合器之路就开了。
接下来可以扩展到铁路调度、动态优先级、跨星球库存平衡,思路都是把这套小积木搭得更大。

来源: Combinator Tutorial