{b}RFTools Control Manual

Table of Contents:
{l:intro}Introduction
{l:programmer}Programmer
{l:processor}Processor
{l:networking}Networking
{l:craftingstation}Crafting Station
{l:craftingcard}Crafting Card
{l:workbench}Workbench
{l:tank}Tank
{l:items}Moving Items
{l:graphics}Graphics
{/}



{l:concepts}Programming Concepts
{l:types}Types
{l:parameters}Parameters
{l:variables}Variables
{l:events}Events
{l:opcodes}Opcode Types
{l:tokens}Tokens
{l:concurrency}Concurrency
{l:debugging}Debugging
{l:sharing}Sharing Programs
{-------------------------------------------------------------}
{b}Introduction
{n:intro}
RFTools Control is an addon mod for RFTools which adds a visual
programming system that is suitable for automation tasks. Programs
written with RFTools Control can move items around, interact with
redstone, examine energy levels of machines and so on. There is direct
support for the storage scanner and in the future it will also give
auto crafting abilities to that scanner.

Don't be too afraid of the word 'programming' though. Programs written
for RFTools Control are typically very simple and they are also written
in a visual manner. That means you don't actually have to 'write' code.
Instead you drag icons on a grid.
{-------------------------------------------------------------}
{b}The Programmer
{n:programmer}
{rb:programmer}
The Programmer is the basic block where you create your programs. To
use it you need to insert a program card item:
{ri:program_card}
{-------------------------------------------------------------}
The programmer gui can seem complicated at first but it is not that
hard. At the left side you can see all the available opcodes that you
can use in your programs. You can click and drag them onto the big
grid in the middle.

When an opcode is in the main grid you can connect it to neighbours
by clicking a side. If that side turns green you have made a connection
going from that opcode (the one with the green side) to the adjacent
one. Some opcodes (tests) have two outputs. There is also a red output
which indicates the negative path to follow (if the test fails)

If a connector is missing a 'stop' opcode is automatically inserted.
{-------------------------------------------------------------}
Every program needs an event to start with. An event opcode describes
what needs to happen before a program can start. Note that you can
have multiple events on the same card (and thus multiple programs) and
the same program string (connected opcodes) can even have multiple
events which indicate different entry points in the same program.

There are currently seven events: redstone pulse on, redstone pulse
off, timer, exception, signal, craft, and craft resume.
{-------------------------------------------------------------}
Many opcodes have parameters. When you select an opcode on the main
grid you get a list of all possible parameters below the gui.
Parameters are typed but many conversions are done automatically (for
example, an integer is automatically converted to a string when
that is required).

You can specify a parameter in three different ways: as a constant
value, as a variable, or as a function. Variables are stored in
the processor (more on that later). An important function is 'last'
which simply returns the last result of the previous opcode. This
is important, many opcodes have a result which you can access with
this function.
{-------------------------------------------------------------}
{b}The Processor
{n:processor}
{rb:processor}
The Processor is the device that actually runs your programs. First you
write a program with the Programmer and then you insert that card in
the processor. Up to 6 program cards are supported. The Processor needs
some more modules before it can really work though.
{-------------------------------------------------------------}
The most important thing that the Processor needs is at least one cpu
core. For every core that you install in one of the 16 expansion slots
you can run an additional program at the same time. Note that cpu cores
are expensive but you don't always need many even if you plan to run
multiple programs because typical programs don't run very long.

There are three tiers of cpu cores. They differ in their execution speed
and the RF/t energy consumption.
{-------------------------------------------------------------}
The Processor can store up to 32 variables. To do that it needs RAM chips.
Every RAM chip adds 8 variables so maximum 4 RAM chips are supported.

Variables can be used by programs but to do that you have to allocate the
variables to the right card slot. To do that there are six small buttons
above the card slots. Pressing such a button will switch the gui to
'allocation' mode. Then you can select the variables and mark them green.
The first variable marked green will be index 0 for programs on that card.
And so on. Note that the variable index you use in programs is relative
to how you allocated the variables!

You can allocate variables that are already used by other cards. That way
it is possible to share information between programs on different cards.
{-------------------------------------------------------------}
The Processor also has access to 24 internal item slots. These are
always available but just like the variables you also have to allocate
them for each card. Again slot numbers used in programs are relative
to how you allocated them. i.e. slot 0 will be the first slot you
allocated for a program running in a specific program slot.
{-------------------------------------------------------------}
{b}Networking
{n:networking}
Using a network card and several nodes:
{ri:network_card}
{rb:node}
you can create a network. A processor has only six sides but using
a network you can extend this by also enabling access to the sides
of all nodes that are connected to the network.
{-------------------------------------------------------------}
After installing a network card you need to set it up. This can be done
with the 'net setup <name>' console command (in the Processor console).
The <name> will be the network name and is also used in all the nodes
that want to connect to this network.

Setting up the network card will also initiate the scan to find all
nodes that match the given channel name (in a 17x17x17 area with the
processor at the center). Note that the network card is also needed
to connect to crafting stations which this scan will also pick up.

Note: an advanced networking card supports a 33x33x33 area and can
also supports sending messages to other processors anywhere in the
world.
{-------------------------------------------------------------}
If you have an advanced networking card then you can also send
messages to other processors in the world (if they are chunkloaded).
To do that you need to have a network identifier card in one
of the internal processor slots:
{ri:network_identifier}
and then link that card to the destination processor (using sneak right
click). That destination does not need a network card for this to work.

Together with a message you can also send information in the form of
a variable.
{-------------------------------------------------------------}
{b}Crafting Station
{n:craftingstation}
{rb:craftingstation}
The Crafting Station is a device from which you can request items to
be crafted through a program that you write yourselves and that runs
on a nearby Processor. To have the Processor work with a Crafting
Station it needs a network card.

Crafting operations can sometimes take a long time and the gui of
this station shows operations that are still in progress.
{-------------------------------------------------------------}
Note that what a crafting station essentially does is show you for
which items a processor has 'craft' events enabled. As soon as you
request the crafting of such an item the resulting program will be
executed. But what you do in that program is fully up to you.
In many cases you would probably make a program that actually crafts
the desired result but you can also do other things so you can
use the crafting station as a way to trigger various actions to
happen. For example, you can have a 'craft redstone' event that
actually just turns on processing of various items and then a
'craft coal' event to turn it off again. It is up to you.
{-------------------------------------------------------------}
{b}Crafting Card
{n:craftingcard}
{ri:crafting_card}
A crafting card is a special item that can hold a recipe. It is often
used for the classical recipes (3x3 grid to single output) and it has
JEI integration so that you can easily put a recipe in it. But it is
not limited to that. In fact, if you open the GUI of the crafting card
you'll see that there are more then 3x3 possible input slots. You can
describe much more complex recipes then the typical 3x3 recipe.
{-------------------------------------------------------------}
Note also that the output slot does not have to actually correspond with
the actual output. Let's demonstrate with an example how this can be
useful. Say you want a recipe to craft EnderIO facade blocks. These
require a normal recipe and then the result of that has to be smelted.
So you could have a crafting card with as input the 3x3 slots needed
for the intermediate result and as output the final result from the
smelter. Of course this kind of crafting card will require support from
a program that can do this kind of multi-step crafting.
{-------------------------------------------------------------}
{b}Workbench
{n:workbench}
{rb:workbench}
The Workbench is a normal crafting device with an internal buffer for
items. It can be used just like that. However, it's main use is in automation
as this workbench supports piping out the crafted result from the bottom.
In addition a program running on a Processor can directly input ingredients
for a recipe in the workbench from the top side.

The internal buffer of the Workbench is often used for crafting cards to
help with autocrafting setups.
{-------------------------------------------------------------}
{b}Tank
{n:tank}
{rb:tank}
The multi tank is a block that is capable of holding four types of liquids.
When placed adjacent to the processor it gives that processor access to
four new fluid slots (four per tank) which can be allocated to programs
so that they can work with liquids.

Note that there is currently no way to interact with the multi tank except
through the processor and a program accessing the fluids. It is meant
purely as a directly accessible fluid storage for the processor. Placing
it adjacent to a node is also not useful.
{-------------------------------------------------------------}
{b}Moving Items
{n:items}
Many programs will move items at some point. It is important to note that
the processor cannot move items directly from one inventory to another.
Items always have to go through the processor itself. That's why you
typically need 'fetch' and 'push' items after each other.

For many opcodes where you can access a normal inventory you can
also access a storage system linked to a storage scanner. To do that
you need to insert a storage screen module from RFTools into one of
the 16 expansion slots of the Processor. Then to use this feature you
just leave the 'inventory' parameter empty and it should access
the storage where supported.
{-------------------------------------------------------------}
{b}Graphics
{n:graphics}
If you install a graphics card into your processor you will be able to do
some limited vector graphics. You can draw lines, boxes and text and it is
also possible to interact with your graphics in a limited way. There are
two ways to display graphics: either you can use the built-in HUD (set
to 'Gfx' mode) or else you can use an rftools screen with a 'vector art'
module. If you want to interact with your graphics then the rftools screen
is the only way. When working with graphics you have to know about
three concepts: 'ids', 'colors', and 'coordinates'. I'll go over these in the
next page.
{-------------------------------------------------------------}
{b}Ids
Every graphics operation on a processor is identified by an 'id'. This is both
needed to be able to modify a certain operation (i.e. replace the graphics
represented by that id) as well as to control what operations are rendered
first. Basically graphics operations are rendered with their id in
alphabetical order.

{b}Colors
Colors are integers. It is easiest to represent them in hexadecimal notation
like this: $AARRGGBB. A few examples to clarify this: $FF00FF00. Is a fully
non-transparent green color. $55990000 is a transparent dark red color.

{b}Coordinates
Coordinates go from 0,0 (top-left corner) to 128,128 (bottom-right corner).
{-------------------------------------------------------------}
{b}Programming Concepts
{n:concepts}
A program in RFTools Control is made out of 'opcodes' that are
arranged on a grid. Opcodes connect to other opcodes (through a
green arrow or a red arrow in case of a test opcode) and they have
parameters that can influence what they can do.

The tooltip on an opcode in the programmer will give more
information (press shift for even more information)
{-------------------------------------------------------------}
{b}Types
{n:types}
Parameters and variables are typed. That means that they have a specific
type (like integer, string, ...) and need to be converted to be used as
something else. Many conversions are done automatically. For example,
if you need a string but the last result was an integer then the integer
will automatically be converted into a string.

The following types are currently implemented: string, integer, float,
boolean, side (represents a side of the processor or one of the connected
nodes), inventory (represents an inventory adjacent to the processor or a
connected node and an optional side from which to access the inventory),
item (an itemstack), and exception.
{-------------------------------------------------------------}
{b}Parameters
{n:parameters}
As mentioned before opcodes can have multiple parameters which control
how the opcode works. Parameters always have a specific type. Many
parameters are optional which you can see in the tooltip.

Every parameter can be either a constant value, a reference to a
variable, or a function. If you open the parameter editor in the
programmer (the ... button) you can select between these three options
with the buttons at the top.

The available list of functions depends on the type of the parameter.
Some types have no functions defined for them (yet).
{-------------------------------------------------------------}
{b}Variables
{n:variables}
A processor can store up to 32 variables. These are also typed just
like parameters. Make sure to allocate the variables to the card slot
that you need them for. All programs that are on the same card slot
will share those variables automatically.

You can also share variables with programs on other slots because
it is possible to allocate a given variable to multiple cards.

Note that accessing variables in programs needs a relative index.
So variable 0 in a program means the first allocated variable for
that card.
{-------------------------------------------------------------}
{b}Events
{n:events}
Programs written with RFTools Control are 'event driven'. That means they
only start when there is some kind of event. An event can be a redstone
pulse, a timer, a crafting request for some item and more.

Most events have parameters that control when they are fired.

Every program sequence (connected opcodes) on a card will need at least
one event. Otherwise it can never run. It is possible to connect multiple
events to the same program sequence.

If an event fires it is executed on an available core. If no cores are
available then it will be put in a waiting list. Except for the timer event.
That one is discared if there are no cores available.
{-------------------------------------------------------------}
{b}Opcode Types
{n:opcodes}
The following types of opcodes are available:
  * Events: at least one of them is needed for every program
  * Operation: the standard operations
  * Evaluate: an evaluation opcode. These typically do some
    calculation or check and set the result for the next
    opcode to use
  * Test: these opcodes perform a boolean test and then do
    a branch based on that test. Therefore these opcodes have
    two outputs (a green and a red output)
  * Wire: there is only one wire opcode. It is meant to connect
    opcodes that are not adjacent
{-------------------------------------------------------------}
{b}Tokens
{n:tokens}
{ri:token}

Tokens are items that serve no purpose except that they hold
information. From within a program you can write any data to
a token and then from another program read that data again.
Tokens are regular items so you can transfer them and by doing
that transmit the information anywhere you want.
{-------------------------------------------------------------}
{b}Concurrency
{n:concurrency}
As soon as you have multiple cores in your processor multiple programs
can run at the same time. There are a few problems with this. First you
must make sure that slots and variables are properly allocated in case
where these programs don't share that info. This is the easy case.

But sometimes you want to share data. For example, if you have one
program putting items in some internal slots and another program getting
them out again. To handle this safely you might sometimes want to use
locks. A lock is global to the processor (for all programs on that
processor) and it has a name. Only one program can hold a lock with some
name. Other programs that want that lock will wait until the lock is
available again. Make sure to always restore locks! If you forget
you can use 'reset' to reset your processor and clean everything.
{-------------------------------------------------------------}
Another problem with concurrency is preventing one program to use up
all the cores. For example, if you have a program that needs some time
to execute and executes whenever there is a redstone signal then if
you give two signals very quickly there might be multiple instances of
that program running (if there are sufficient cores available).

Sometimes this is ok but in many cases you might want only one instance
of a given program running at every time. To do that you can use the
'single' parameter that you can set with every event. If you make that
true then this event can only be fired once and it will be locked until
the program that was attached to that event stops running.
{-------------------------------------------------------------}
Another solution to concurrency can be the 'exclusive' option that you
can select in the GUI of the processor. If this button is pressed then
programs on card X can only execute on core X. So that means that
every core if exclusively dedicated to programs on a single card.

This feature can also be used when you have a processor that has a
low tier and a high tier core installed. Using exclusive mode you can
make sure that the more demanding programs only run on the high tier
core.
{-------------------------------------------------------------}
{b}Debugging
{n:debugging}
You will make bugs. Repeat after me: you will make bugs! So what can you
do to fix those bugs? There are a few techniques. First there is a 'log'
opcode that you can use to dump messages on the console. It can show
simple messages or even the contents of variables.

But for more advanced debugging you might want to use the internal
debugger. To use that you simply go to the processor and type:
    db debug

This will halt all programs that might currently be running and allow you
to selectively singlestep them (i.e. execute them one instruction at a
time).
{-------------------------------------------------------------}
To see where a specific program is at you can use:
    db info

To singlestep a program running on (for example) core 0 you would type:
    db s 0

This will execute the current instruction and show you the next
instruction that is waiting for you to execute.
You can also examine the last result with:
    db last 0

(or 'db last' to show all last results for all current programs)
{-------------------------------------------------------------}
While the program is being single stepped you can of course also
examine variables by clicking the '...' button on the left (and
change them).

To resume all programs you do:
    db resume
{-------------------------------------------------------------}
{b}Sharing Programs
{n:sharing}
The programmer supports the clipboard. You select opcodes, you can type
Ctrl-C and the selected grid will be copied to the clipboard. This is a
JSON file that you can share on the web. If you have such a program in
your clipboard you can do Ctrl-V to paste it. If the program is small
enough you can paste it in a section of your grid by clicking on the
grid location where you want the left-top opcode to appear. If you
select nothing it will try to place from the top-left corner. Note that
it will merge what is in the clipboard with what is already there.

Note that you can always use Ctrl-Z to undo this.

To select opcodes you can use Ctrl-A for the entire grid or else
ctrl-click for a single opcode and ctrl-double click for a sequence.
{-------------------------------------------------------------}
