Create: Computing AgesBrass Docs
Libraries

peripheral

Find and drive the blocks around the computer and on its data cable.

All computers

A peripheral is a block the computer can talk to: a chest, a Create machine, a Traffic Light, a monitor, a sensor of Create Aeronautics. The peripheral library finds these blocks and hands the program an object that carries the block's own functions, its methods: chest.count(), light.set("green"), controller.set_speed(64). Every computer has it.

Brass
local chest = peripheral.wrap("left")
print(chest.count("minecraft:iron_ingot") .. " iron ingots")

Blocks against the computer are named after the face they touch: "front", "back", "left", "right", "top" and "bottom", as for rs (left and right as seen facing the screen). The block that drives the computer counts too: the shaft at the back (below a Microcontroller) is a kinetic peripheral.

Blocks on the Data Cable. From the Minicomputer on, every block touching the computer's Data Cable network is a peripheral as well, named type@x,y,z: its type and its coordinates, as F3 shows them, like inventory@120,64,-35. The name stays the same as long as the block is there.

  • Plain shafts, cogwheels and gearboxes along a cable are not peripherals of the network, so a cable can run along a gear train. Against the computer itself, they are.
  • Other computers on the cable are not peripherals: computers talk to each other with net.
  • A side of a cable cut with a wrench lets nothing through.
  • A network reaches 2048 cables at most, and only in loaded chunks. A new cable is seen at once, a block placed against a cable within a second.
  • The Tube Computer and the Transistor Mainframe have no network port: they only reach their six faces.

Types. What a block can do is its type. The methods of each type are on its page:

typeblockspage
traffic_lightTraffic LightTraffic Light
inductive_loopInductive Loop DetectorInductive Loop Detector
monitorCRT Monitor, LCD MonitorMonitors
radio_modem, wifi_routerRadio Modem, Wi-Fi RouterRadio Modem and Wi-Fi Router
redstone_linkCreate's Redstone LinkRedstone Link
kineticevery Create block that turns: Millstone, Mechanical Press, Rotation Speed Controller...Create kinetic blocks
inventoryevery block that holds items: chest, barrel, Item Vault, Depot, Basin...Inventories
tankevery block that holds fluids: Fluid Tank, Basin...Tanks
altitude_sensor, gimbal_sensor, velocity_sensor, optical_sensor, navigation_table, swivel_bearing, torsion_springthe sensors of Create AeronauticsCreate Aeronautics sensors
hot_air_burnerthe Hot Air Burner of Create AeronauticsHot Air Burner

The last two rows only exist when Create Aeronautics is installed. What every object has in common is on Every device.

Several types. A block can be several things at once: a Create Millstone turns (kinetic) and holds items (inventory), a Basin holds items and fluids. Its object then has the methods of all its types together: millstone.speed() and millstone.count(). peripheral.type, the type() method and the network name give the first type, in the order of the table above (the Aeronautics types first); peripheral.list(type) and peripheral.find(type) look at all of them, so peripheral.find("inventory") finds the Millstone, named kinetic@x,y,z on the cable.

Seen from one side. An inventory or a tank is seen from its face that touches the computer (or the cable), the way a hopper on that side would see it: a Furnace shows its input slot from above, its fuel slot from the side, and its result from below.

Costs. Most calls cost one instruction, but scanning a cable network costs more, because every block around it is asked what it is:

callinstructions
peripheral.list, peripheral.find16, plus 4 per block next to the cable network (air included), if there is one
peripheral.wrap8
a network name (type@x,y,z) given to wrap, type or call1 more per 4 blocks next to the cable network

A straight cable 20 blocks long has about 80 blocks around it: peripheral.list() then takes about 340 instructions, more than a whole tick of a Minicomputer. Find your peripherals once at the start of the program, keep the objects, and only scan again when the installation changes. The methods themselves have their own costs, listed on the pages of each type. See also Speed, memory and limits.

Functions
peripheral.list([type])The names of the peripherals the computer can reach, as a list. Without a type, every peripheral; with one, only the blocks that have that type (among all their types). An empty list when there is none.
peripheral.find(type)The first peripheral of a type, already wrapped: the shortest way to reach a block when there is only one of its kind. It looks at the faces first, then at the cable. It costs as much as peripheral.list, plus the lookup of a network name when the block it finds is on the cable.
peripheral.type(name)The type of the block behind a name: "inventory", "kinetic", "traffic_light"... nil when the face is empty (or holds a block that is no peripheral, like stone), and for a name that matches nothing.
peripheral.wrap(name)The object that drives the block behind a name. It is a table of functions: call them with a dot, chest.count(), never with a colon. Every device tells what every object has in common.
peripheral.call(name, method, ...)Calls one method of a peripheral without keeping an object: peripheral.call("left", "set", "red") does the same as peripheral.wrap("left").set("red").

Finding peripherals

#

peripheral.list([type])

→ table⚙ cost 16

The names of the peripherals the computer can reach, as a list. Without a type, every peripheral; with one, only the blocks that have that type (among all their types). An empty list when there is none.

Parameters
type string optional
only the peripherals of that type, like "inventory"
Returns
table
their names: the faces first (in the order of rs.sides), then the blocks of the data cable
Brass
for _, name in ipairs(peripheral.list()) do
  print(name, peripheral.type(name))
end

On a Minicomputer driven by a shaft at the back, with a Millstone on its left and two chests on its cable, it shows:

Screen
back    kinetic
left    kinetic
inventory@120,64,-35    inventory
inventory@121,64,-35    inventory

Sum a resource over the whole storage. Every inventory on the cable, read once, then counted every 10 seconds on a Display Link:

Brass
local chests = {}
for _, name in ipairs(peripheral.list("inventory")) do
  if string.find(name, "@") then  -- cable names only: see below
    table.insert(chests, peripheral.wrap(name))
  end
end
print(#chests .. " inventories on the cable")

while true do
  local iron = 0
  for _, chest in ipairs(chests) do
    iron = iron + chest.count("minecraft:iron_ingot")
  end
  display.set({"Iron in storage", tostring(iron)})
  sleep(10)
end
Watch out

A block that touches both the computer and its cable is listed twice: once by its face, once by its network name. Keeping only the names with @ counts each chest once, as long as the chests hang on the cable rather than against the computer.

If a chest is broken while the program runs, its object fails with not an inventory anymore and stops the program: scan again, or protect the count with pcall (see Every device).

See also peripheral.find() peripheral.type() rs.sides()

#

peripheral.find(type)

→ table⚙ cost 16

The first peripheral of a type, already wrapped: the shortest way to reach a block when there is only one of its kind. It looks at the faces first, then at the cable. It costs as much as peripheral.list, plus the lookup of a network name when the block it finds is on the cable.

Parameters
type string
a type, like "traffic_light"
Returns
table
the first peripheral of that type, ready to use, or nil when there is none
Brass
local light = peripheral.find("traffic_light")
if light == nil then
  error("no traffic light found")
end
light.set("green")

A type that does not exist is not an error: peripheral.find("chest") simply returns nil (chests are "inventory").

Note

Since the faces come first, peripheral.find("kinetic") usually returns the shaft that drives the computer, at the back. For a Create machine, wrap it by its face or its network name, or look for its other type (peripheral.find("inventory") for a Millstone).

A program that adapts to what it finds. A small control panel that works wherever you put it: it looks for each kind of block it knows and shows only what is there.

Brass
local storage = peripheral.find("inventory")
local tank = peripheral.find("tank")
local light = peripheral.find("traffic_light")

while true do
  term.clear()
  term.set_cursor(1, 1)
  if storage then
    print("items: " .. storage.count() .. " in " .. storage.size() .. " slots")
  end
  if tank then
    for _, t in ipairs(tank.tanks()) do
      print((t.fluid or "empty") .. ": " .. t.amount .. "/" .. t.capacity .. " mB")
    end
  end
  if light then
    print("traffic light: " .. light.get())
  end
  if not (storage or tank or light) then
    print("nothing to watch here")
  end
  sleep(1)
end

See also peripheral.list() peripheral.wrap()

#

peripheral.type(name)

→ string

The type of the block behind a name: "inventory", "kinetic", "traffic_light"... nil when the face is empty (or holds a block that is no peripheral, like stone), and for a name that matches nothing.

Parameters
name string
a face ("left") or a network name ("inventory@120,64,-35")
Returns
string
the first type of the block, or nil when there is nothing to talk to

A cheap way to check a setup before using it:

Brass
while peripheral.type("left") ~= "inventory" do
  print("place a chest on the left")
  sleep(2)
end
print("chest found")

See also peripheral.wrap() peripheral.list()

Driving a peripheral

#

peripheral.wrap(name)

→ table⚙ cost 8

The object that drives the block behind a name. It is a table of functions: call them with a dot, chest.count(), never with a colon. Every device tells what every object has in common.

Parameters
name string
a face ("left") or a network name ("inventory@120,64,-35")
Returns
table
an object with the methods of the block, or nil when there is nothing to talk to
Brass
local vault = peripheral.wrap("left")
if vault == nil then
  error("put the vault on the left")
end
print(vault.type())   -- inventory
print(vault.count())

Never stale. Each method finds the block again when it is called. Break the chest on the left and put another one there: the same object reads the new chest. If the block is gone, or is no longer of that kind, its methods fail with an error such as not an inventory anymore or traffic light removed, and with peripheral is not loaded when its chunk is not loaded. The methods of an object are chosen when it is wrapped: if a different kind of block takes the place, wrap it again.

Keep the object. Wrap once, then call the methods as often as needed: each call of a method only costs that method. Wrapping in every turn of a loop costs 8 instructions each time, and more for a network name.

Brass
local controller = peripheral.wrap("right")   -- a Rotation Speed Controller
local stock = peripheral.wrap("left")         -- the vault of raw iron
while true do
  if stock.count("minecraft:raw_iron") > 1000 then
    controller.set_speed(32)
  else
    controller.set_speed(128)
  end
  sleep(5)
end

See also peripheral.find() peripheral.call()

#

peripheral.call(name, method, ...)

→ any

Calls one method of a peripheral without keeping an object: peripheral.call("left", "set", "red") does the same as peripheral.wrap("left").set("red").

Parameters
name string
a face or a network name
method string
the name of the method, like "count"
... any optional
the arguments of the method
Returns
any
what the method returns
Brass
peripheral.call("left", "set", "red")
local coal = peripheral.call("inventory@120,64,-35", "count", "minecraft:coal")
print(coal .. " coal")

It finds the block at each call, so it suits a one-off action. For repeated calls, peripheral.wrap once is clearer.

It stops the program with no peripheral 'chest' when the name is neither a face nor a known network name, and with peripheral 'left' has no method 'set' when the block there has no such method. An empty face has only the method type, which answers "none".

See also peripheral.wrap()