{b}RFTools Control Manual

Table of Contents:
{l:intro}引言
{l:programmer}编程器
{l:processor}处理器
{l:networking}网络化
{l:craftingstation}合成站
{l:craftingcard}合成卡
{l:workbench}工作台
{l:tank}储罐
{l:items}移动物品
{l:graphics}绘图
{/}



{l:concepts}编程概念
{l:types}分类
{l:parameters}参数
{l:variables}变量
{l:events}事件
{l:opcodes}操作码类型
{l:tokens}标记符
{l:concurrency}并行
{l:debugging}调试
{l:sharing}代码分享
{-------------------------------------------------------------}
{b}引言
{n:intro}
RFTools Control是RFtools的附属，为适应自动化任务而添加了一个可视化编程系统. 
用RFTools Control写的程序能搬运周围物品, 互动红石, 检查机器能量水平，等等. 
直接支持存储检测器，在未来会给予检测器自动合成能力.

不要太害怕'编程' 一词.为RFTools Control写的程序通常非常简单，并以一种可视化
的方式编写. 这意味着你不一定要 '书写' 代码.相反把图标拖到插槽里就是了.
{-------------------------------------------------------------}
{b}编程器
{n:programmer}
{rb:programmer}
编程器是编写程序最基础的方块. 你需要插入一张程序卡来使用它:
{ri:program_card}
{-------------------------------------------------------------}
编程器的界面乍一看很复杂，但并没有那么难. 在左侧你可以看到所有可以用在程序的
操作码（opcode）.你可以点击这些操作码图标，用鼠标将它们拖进中间的大格子里去.

当一个操作码在主格子里你可以双击图标的某一条边来链接到邻近的操作码.如果那条边
变绿了你就在一侧变绿的操作码和邻近的之间建立了一个连接.一些操作码(test，测试)
有两个输出. 也有一个红色的输出指示错误路径(如果测试失败)。

如果一个链接丢失，'停止' 操作码会被自动插入.
{-------------------------------------------------------------}
每一个程序都需要开始事件.一个事件（event）操作码描述了程序执行的前提事件. 注
意同一张卡上可以有多个事件(因此也会有多个程序)，甚至同一程序字符串(连接起来的
操作码)在同一程序中也可以有多个指示不同进入点的事件.

有7种触发事件:红石脉冲开,红石脉冲关，计时器,例外,信号,合成,和合成重新开始.
{-------------------------------------------------------------}
很多操作码都有独特的参数. 当你在主要格子里（中间格子）里选择了一个操作码，你
就可以在界面下方看到该操作码对应所有可能的参数.特征是固定分类的但是改变是自动
完成的(例如，整数在需要的时候自动转变为字符串).

你可以以三种方式指定一个参数: 使用常量, 使用变量, 或者函数. 变量存储在处理器
中(以后详谈). 一个重要的函数是'last'，简单地返回上一个操作码的最新一个结果.
它很重要——你可以通过这个函数访问很多操作码的结果.
{-------------------------------------------------------------}
{b}处理器
{n:processor}
{rb:processor}
处理器是自动执行你的程序的设备.首先你要写好一个程序然后把写好的程序卡插进处理
器. 最大支持6张程序卡. 在它能真正工作之前，处理器还需要些别的模块.
{-------------------------------------------------------------}
处理器所需最重要的东西是一个处理器核心.对于每一个你安装在左下角16个插槽之一的
核心，都可以同时运行一个扩展程序。注意处理器核心是很贵的，你不需要很多核心除非
你想运行很多程序，因为一般的程序不会运行很久.

有三个等级的处理器核心. 它们的不同在于执行速度和消耗的RF/t.
{-------------------------------------------------------------}
处理器最大能存储32个变量. 为了达到这个数量你需要内存条.每个内存条增加了8个变量
所以最大支持4个内存条.

变量可以被程序使用但是你必须把变量分配给正确的卡槽. 为了正确分配，在卡槽上有6个
小按钮.按下小按钮，界面会被切换到“分配”模式.然后你就可以在（左下角的菜单里）选
择变量并把它们标记成绿色.这张卡上的程序第一个被绿色标记的变量被指定为0，以此类
推.注意你使用的变量索引与你如何分配变量密切相关!

你也可以分配那些已经被其他卡使用了的变量.这让不同的卡的程序之间分享信息成为可能.
{-------------------------------------------------------------}
处理器也有24个物品插槽. 它们总是可用的，但是就像变量一样，你也必须把它们分配给
每一张卡.用在程序里的插槽号码也与你如何分配它们相关. 换句话说，插槽0会成为第一
个你分配给一个运行在特定程序（卡）插槽的程序的插槽.
{-------------------------------------------------------------}
{b}网络化
{n:networking}
使用一个网络卡和几个节点:
{ri:network_card}
{rb:node}
你可以建立一个网络.一个处理器只有六个面，但是使用网络，允许所有链接到网络的节点
到处理器某一面的接口可以扩展处理器.
{-------------------------------------------------------------}
网络卡安装之后需要设置.通过在处理器界面黑色区域的输入栏输入 'net setup <name>' 
控制指令来设定(与原文有出入——译者注).
<name>里的内容就是你网络的名字，并会应用在每一个链接到你网络的节点中.

设定网络卡之后，会开始扫描所有链接到给定网络名的节点(以处理器为中心17x17x17的
区域). 注意，网络卡也需要链接到合成站，扫描时也会发现它.

注意: 高级的网络卡支持33x33x33的区域，支持向世界各地的处理器发信息.
{-------------------------------------------------------------}
如果你有一张高级网络卡，你也可以向世界中的其他处理器发信息(只要它们所在区块被
加载).做到这个，你需要在处理器的内部16插槽中安放一个网络识别卡:
{ri:network_identifier}
然后将这张卡链接到目标处理器(潜行右击).目标处理器不需要一张相匹配的网络卡.

你也可以把信息以变量的形式发出.
{-------------------------------------------------------------}
{b}合成站
{n:craftingstation}
{rb:craftingstation}
合成站是一个通过你自己写的程序请求物品以自动合成的设备，在附近的处理器上运行.
要让合成站和处理器工作需要网络卡.

合成操作有时要费很长时间，合成站的界面会显示合成进度.
{-------------------------------------------------------------}
注意合成站本质上做的就是让你看到处理器“合成”某一物品的事件被触发.只要你请求这
样一个物品的合成，后续程序便会执行.但是你在程序里做的完全取决于你.很多情况下
你可能编辑一个事实上用来合成，但是也可以做别的程序，所以你可以使用合成站来作为
一种触发多个过程的方式. 例如, 你可以有一个“合成红石” 事件，自动打开不同物品的
（合成）进程，“合成煤炭”事件将这些进程关闭. 由你决定.
{-------------------------------------------------------------}
{b}合成卡
{n:craftingcard}
{ri:crafting_card}
合成卡是能容纳合成表的特殊物品.经常用于典型合成(3x3合成格一个输出格)，有JEI的
集成，所以往里面放入合成表很容易。但是不仅于此. 事实上，如果你打开合成卡的界面，
你会发现有不止3x3可能的输入槽. 你可以借此表达比3*3更加复杂更多的合成。
{-------------------------------------------------------------}
注意实际所需要的产物可以不一致于合成表的产物. 让我们看看一个此特性有用的实例. 
比如你想合成Ender IO的表面方块需要一个正常的合成，该合成的产品需要被熔炼.所
以你可以有一张写入3*3合成表的合成卡以合成中间产物，从冶炼炉输出最终产物。当然
这种合成卡需要处理多步合成的程序的支持.
{-------------------------------------------------------------}
{b}工作台
{n:workbench}
{rb:workbench}
工作台是一个有内部物品缓存的一般合成设备. 可以当做原版工作台，但是它的主要用
处还是自动合成，因为工作台支持从底部抽出合成产物。而且一个运行在处理器上的程
序可以直接将一个合成的原材料从工作台顶部输入.

内部缓存经常被用于合成卡辅助处理自动合成.
{-------------------------------------------------------------}
{b}储罐
{n:tank}
{rb:tank}
多容储罐可以容纳4种液体。当摆在处理器旁边时，会给予处理器4个新的流体槽（每个
储罐4个）可以分配给程序，这样程序就可以处理液体了.

注意没有其他的方式与多容储罐互动，除非是处理器和一个涉及流体的程序.很明显，这
是直接给处理器调用的流体储存期. 放在节点旁边是没用的.
{-------------------------------------------------------------}
{b}移动物品
{n:items}
许多程序都会在同一点移动物品. 注意处理器不能直接在容器之间移动物品，这很重要.
物品总是会通过处理器本身. 这就是为什么你需要互相'吸入'和'推出'物品.

能进入正常容器的操作码，也可以进入连接到存储检索器的存储系统. 做到这一点你需要
向处理器那16个插槽中插入一个来自rftools的屏幕显示模块.你只需要清空'容器'参数，
物品就会进入所支持的存储系统中.
{-------------------------------------------------------------}
{b}绘图
{n:graphics}
如果你在处理器里安装了图形卡，就可以进行一些简单的矢量绘图. 你可以画线，盒子以
及文本，以某种限定的方式与你的图形交互也是可能的. 绘图有两种方式: 既可以用处理
器内建的HUD(设定为 'Gfx' 模式) 也可以使用RFtools的屏幕配合'矢量画'模块. 如果
你想与你画的图形交互，rftools屏幕是唯一的方式. 以图形工作时必须有三个要点: 
'名称', '颜色', 和 '调谐'. 我会在下页交待.
{-------------------------------------------------------------}
{b}名称
一个处理器上的所有图形操作都是由一个'id（名称）'确定的. 既能用来修改一个特定的
操作(换句话说，图形的改变体现在ID的改变上)，也能控制首先渲染什么图形操作.一般来
说图形操作按照它们ID的字母表顺序（ABCD）渲染.

{b}Colors
颜色是整数.用这样的十六进制记号表示它们最简单: $AARRGGBB.举几个例子说明: 
$FF00FF00.这是完全不透明的绿色. $55990000是透明的暗红色.

{b}调谐
调谐范围从0,0 (最左上角)到128,128 (最右下角).
{-------------------------------------------------------------}
{b}编程事项
{n:concepts}
Rftools control程序是由安排在格子里的操作码编写的.操作码互相连接(通过绿色箭头
或者测试操作码的红色箭头)，而且操作码是决定程序能做什么的基本参数.

编程器内部操作码的提示可以给予更多信息。(按下shift访问更多信息)
{-------------------------------------------------------------}
{b}类
{n:types}
参数和变量已经被分类了.这意味着它们有特定的类(如整型，字符串...)并且需要转换
成别的什么.很多转换都是自动完成的.比如你想要一个字符串但是最终结果是一个整型，
整型会被自动转换为字符串.

一般执行这些类: 字符串，整型，浮点数，布尔值, 面向 (代表处理器的某一个面，或者
已经链接的节点), 库存(代表处理器邻近的一个容器或者一个连接的节点和任意一个可进
入容器的面),物品(一个物品堆栈，就是箱子里的一个槽), 等等.
{-------------------------------------------------------------}
{b}参数
{n:parameters}
在操作码执行之前，可以有多个参数决定了操作码如何工作.参数总是有一个特定类型.
你在操作码的提示中看到的参数都是可调节的。每一个参数有三个可能：既可以是常量, 
也可以是变量引用,或者一个函数. 如果你打开了编程器里的参数编辑器(“...”按钮)，
你可以在弹出的对话框中选择这三个选项.

允许的功能清单取决于参数的类型.有一些类型目前还没有为它们定义的功能.
{-------------------------------------------------------------}
{b}变量
{n:variables}
一个处理器最大可以存储32个变量. 变量也像参数一样分类. 确保把变量分配到需要它
们的卡槽. 所有在同一卡槽（指的是处理器上面的6个卡槽）上的程序都会自动分享这些
变量.

你也可以把变量分配到其他卡槽的程序中，因为允许把给定的变量分配到多张卡中.

进入程序的入口变量需要一个“相关索引”.所以一个程序里的变量0即为这张卡分配的第
一个变量.
{-------------------------------------------------------------}
{b}事件
{n:events}
用RFTools Control写的程序是'事件驱动'.也就是说，当事件发生时程序才会开始.事
件可以是红石信号,计时器,一个物品合成请求，等等.

大多数事件都有控制何时触发它们的参数.

同一张卡上的每一个程序序列(连在一起的操作码)需要至少一个事件，否则无法运行.将
多个事件链接到同一程序序列是可行的.

事件（操作码）被触发时，会运行在一个可用的处理器核心上. 如果没核心，就会转移
到等待队列中，计时器除外，如果没有核心，该事件会被直接忽略.
{-------------------------------------------------------------}
{b}操作码
{n:opcodes}
如下的操作码可用:
  * Events（事件）:每个程序都需要至少一个。
  * Operation（操作）:标准操作。
  * Evaluate（赋值）:一个赋值操作码. 一般是做一些计算或者检查，将结果提交给
    下一个操作码使用。
  * Test（测试）:这些操作码执行布尔值测试，并在此测试上生成一个分支. 因此这
    些操作码有两个输出(绿色和红色输出)。
  * Wire（线缆）:只是一个线缆操作. 用来连接不相邻的操作码。
{-------------------------------------------------------------}
{b}标记符
{n:tokens}
{ri:token}

标记符除了存储信息没有别的效用. 你可以从某个程序写入任何数据到标记符中，从另
一个程序重新读取这些数据。标记符是不变的物品，所以你可以转移它们并借此将信息
带到任何地方.
{-------------------------------------------------------------}
{b}并行
{n:concurrency}
当你的处理器里有多个核心时，同时也会运行一样多的程序.但是有几个问题. 首先要
确保插槽和变量合理分配，以防程序不共享信息. 这种情况很容易发生.

但是有时你想共享信息. 例如，你有一个把物品放在内部插槽中的程序，和另一个把它
们取出的程序. 为了安全操作，你可能有时想要上锁.一个锁对整个处理器普适(对于该
处理器执行的所有程序而言)并且有一个名字. 只有一个程序可以持有有一些名字的锁. 
其他需要这个锁的程序都将等待，直到该锁解除重新可用. 保证总是修复锁!如果你忘
了你需要'reset（重置）' 以重置你的处理器，清空所有数据.
{-------------------------------------------------------------}
另一个并行的问题是，组织一个程序用尽所有的核心. 例如，如果你有一个需要经过一
段时间并且无论何时有红石信号都执行的程序，如果你很快地给予两个红石信号，就可
能会有很多程序实例等待执行 (如果有足够多可用的核心).

有时候这还可以，但是很多情况下，你想要每次执行程序只运行一个实例. 你可以使用
'single（单事件）' 参数来设定每一个事件. 如果此参数设定为真，这个事件只会被
触发一次并会被锁定，直到这个程序依附的事件结束运行.
{-------------------------------------------------------------}
并行的另一种解决方式是使用可以在处理器界面选择的'excl（专有）'选项 . 如果该
按钮被按下，卡片X上的程序便只能在处理器核心X上执行. 这意味着每个处理器核心是
否唯一对应单张卡上的程序.

这一特性可以用于同时装有低级核心和高级核心的处理器. 使用专有选项你可以确保那
些要求更高的程序只运行在更高级的处理器核心上.
{-------------------------------------------------------------}
{b}调试
{n:debugging}
你会弄出错误. 跟我念:你会弄出错误! 怎样修复这些错误呢? 有几个技巧.首先会有一
个'log（日志）'操作码，用来导出控制台的信息. 也可以显示简单的信息甚至是变量
的内容.

但是为了更好的调试，你可能需要内置调试器. 只需要简单地进入处理器然后输入:
    db debug

这会停止所有可能当前在运行的程序，允许你单步运行它们 (换句话说，一次只执行一
个指令).
{-------------------------------------------------------------}
看到一个特定的程序在哪可以使用:
    db info

单步执行一个运行在(比如) core 0的程序要输入:
    db s 0

这会执行当前的指令，并给你看到下一个准备执行的指令.
你也可以用如下指令检查最后一个结果:
    db last 0

(或者 'db last' 以显示所有当前程序的所有最终结果)
{-------------------------------------------------------------}
当一个程序被设定为单步运行，你当然也可以通过点击左面的 '...' 按钮来检测变量
(并修改它们).

重置所有程序需要输入:
    db resume
{-------------------------------------------------------------}
{b}共享程序
{n:sharing}
编程器支持剪贴板.选择操作码（程序中的）并按下Ctrl+C，操作码就会被复制到剪贴板
中。这是一个可以分享到网络中的JSON文件.如果你的剪贴板中有程序，按下Ctrl+V以粘
贴.如果一个程序足够小，你可以将其直接粘贴在编程器的程序格子里，会将该程序的最
左上角那一格粘贴到你点选粘贴的那一格，以作为粘贴的位置基准（与原文有差异——译者
注）. 如果你并没有点选粘贴点，那么程序会尝试粘贴在最左上角的格子里. 注意这会取
代剪贴板原有的内容（谨防剪切某个重要文件不粘贴还去复制这个的愚蠢行为——译者注）.

可以使用Ctrl+Z以撤销操作.
按下Ctrl+A选择当前格子里所有的操作码，Ctrl+单击选择单个的操作码，Ctrl+双击选择
连续序列操作码.
{-------------------------------------------------------------}
