Create logistics
Create's packages driven by a program: Packagers, Frogports and Postboxes, the Redstone Requester, the Stock Ticker of a storage network, and the shops on Table Cloths.
Create moves items in Cardboard Packages: a Packager packs them, belts, Chain Conveyors and trains carry them, and the address written on each package says where it goes. A computer takes part in all of it: it packs on demand, readdresses packages, orders items from a whole storage network, and runs a shop.
local ticker = peripheral.find("stock_ticker")
local n = ticker.request("Workshop", {name = "minecraft:iron_ingot", count = 64})
print(n .. " iron ingots on their way")packager.make_package() | Packs the inventory behind the Packager now, like a redstone pulse would. If the computer gave an address with set_address, the package gets it. |
packager.list() | What the Packager would pack: the items of the inventory behind it, read like inventory.list(). |
packager.get(slot) | One slot of the inventory behind the Packager. A slot outside the inventory stops the program with bad argument #1 to 'get' (slot 30 out of range, 1 to 27). |
packager.address() | The address the packages made by make_package will get. |
packager.set_address(address) | Sets the address of the packages this computer makes with make_package. It does not change the sign, nor the address of the packages the Packager makes on its own. |
packager.package() | The package the Packager holds right now: one it just made, before it leaves. |
packager.set_package_address(address) | Changes the address of the package the Packager holds, before it leaves. When it holds none, the program stops with the packager holds no package. |
port.address() | The address the port catches packages for. Create allows * in it ("Kitchen*"), and an empty address catches the packages that have none. |
port.set_address(address) | Changes the address the port catches packages for, as its screen does. |
port.configuration() | What the port does: |
port.set_configuration(mode) | Chooses what the port does. Another word stops the program; "send_recieve", the spelling of Create's ComputerCraft peripheral, works too. |
port.list() | The packages waiting in the port, read like inventory.list(). |
port.get(slot) | One slot of the port. A slot outside it stops the program, as with packager.get(). |
req.request() | Sends the order now, like a redstone pulse. Once per tick at most: a second call in the same tick fails and says to wait (sleep(0)). |
req.set_request(...) | Replaces the order. An id alone asks for one item. |
req.set_crafting_request(count, ...) | Orders ingredients together with their recipe, for an automatic crafting line. |
req.get_request() | The order the requester sends, indexed by square as it was set: a crafting pattern keeps its holes, so set_crafting_request(1, "oak_planks", nil, "stick") reads back with a square 1 and a square 3, and no square 2. Go through it with pairs, which skips the holes. |
req.configuration() | Whether the requester sends what there is ("allow_partial") or waits until everything is in stock ("strict"). |
req.set_configuration(mode) | Chooses the mode. Another word stops the program. |
req.address() | Where the packages of the order go. |
req.set_address(address) | Changes where the packages of the order go. |
ticker.stock() | The whole stock of the network. count is the total of that item in all the inventories, often far more than 64. |
ticker.stock_item(n) | One entry of the stock, without building the whole list. The order of the list changes when the stock changes. |
ticker.request(address, ...) | Sends items of the network to an address, in packages. Once per tick at most, since the stock it reads is counted once per tick: a second call in the same tick fails and says to wait (sleep(0)). |
ticker.list() | The payments the Stock Ticker received from the shops of its network, read like inventory.list(). |
ticker.get(slot) | One payment slot. A slot outside them stops the program, as with packager.get(). |
shop.shop() | Whether the cloth sells something. All the other methods, except set_wares, need a shop: on a plain cloth, they stop the program with this table cloth is not a shop. |
shop.wares() | The wares of the shop. |
shop.set_wares(...) | Sets what one purchase gives, and makes the cloth a shop. Called with nothing, it turns the shop back into a plain cloth. |
shop.price_item() | The payment item. Its count is 1: the price itself is price_count(). |
shop.set_price_item(id) | Sets the item asked as payment. A shop without a price item refuses to sell. |
shop.price_count() | The price, in payment items. |
shop.set_price_count(n) | Sets the price, in payment items. |
shop.address() | The address of the packages of goods: usually a Frogport or a Postbox at the shop counter. |
shop.set_address(address) | Changes where the shop sends what it sells. |
Setting up
The blocks and their types. Put the block against a face of the computer, or against a Data Cable of its network (Minicomputer and newer), then wrap it, for example with peripheral.find("stock_ticker"). See Peripherals.
| type | block | methods |
|---|---|---|
packager | Packager | Packager |
repackager | Re-Packager | the same as the Packager |
frogport | Package Frogport | package ports |
postbox | Postbox, of any colour | package ports |
redstone_requester | Redstone Requester | Redstone Requester |
stock_ticker | Stock Ticker | Stock Ticker |
table_cloth | Table Cloth of any colour, Andesite, Brass and Copper Table Covers | shop |
Items. An item a program names is its id, like "minecraft:iron_ingot" or "create:andesite_alloy" (a name without : means minecraft:). An id that names no item stops the program with bad argument to 'set_request' (unknown item 'minecraft:iron_ingott'). Items come back as tables {name =, count =, display =}, as on the Inventories page.
Addresses. A package carries an address, a short text. Package Filters, Frogports and Postboxes read it to send the package the right way, and Create lets * stand for any text in theirs. The addresses a program gives are cut to 128 characters.
No events: ask in a loop. Create's own ComputerCraft peripherals send events when a package is made or received. Brass has no peripheral events: look at package() or list() again every second or so.
When a block is broken, its methods stop the program with packager removed, package port removed, redstone requester removed, stock ticker removed or table cloth removed.
Packager
A Packager packs the items of the inventory behind it into a package when it receives a redstone pulse, and unpacks the packages it receives into that inventory. A Re-Packager (type repackager) has the same methods, and peripheral.find("packager") finds it too.
The Packager writes the address of the sign on it. With set_address, the computer gives another address, but **only to the packages it makes itself with make_package**. The packages the Packager makes without the computer (a redstone pulse) still get the address of the sign, and those it packs for an order of the network get the address of that order. (In Create, only a ComputerCraft computer changes the others.)
Packs the inventory behind the Packager now, like a redstone pulse would. If the computer gave an address with set_address, the package gets it.
- boolean
- true when a package was made
local packager = peripheral.find("packager")
packager.set_address("Smeltery")
if packager.make_package() then
print("a package leaves for the Smeltery")
endIt returns false, and packs nothing, when:
- the Packager still holds the previous package (a belt, a chute or a Frogport must take it away first);
- the inventory behind it is empty, or missing;
- it made a package less than two seconds ago, as with a button;
- a Stock Link is on it: it then works for its logistics network only.
See also packager.set_address() packager.package()
packager.list()
What the Packager would pack: the items of the inventory behind it, read like inventory.list().
- table
- the stacks of the inventory behind it, indexed by slot number; empty slots are missing
Without an inventory behind it, the program stops with the packager has no inventory behind it.
See also packager.get() inventory.list()
packager.get(slot)
One slot of the inventory behind the Packager. A slot outside the inventory stops the program with bad argument #1 to 'get' (slot 30 out of range, 1 to 27).
slotnumber- a slot of the inventory behind it, from 1
- table|nil
- the stack in that slot, or nil when it is empty
See also packager.list()
packager.address()
The address the packages made by make_package will get.
- string
- the address this computer gave, else the one on the Packager's sign,
""without either
See also packager.set_address()
packager.set_address(address)
Sets the address of the packages this computer makes with make_package. It does not change the sign, nor the address of the packages the Packager makes on its own.
addressstring|nil- the address, cut to 128 characters; nil to use the sign's again
packager.package()
The package the Packager holds right now: one it just made, before it leaves.
- table|nil
- the package the Packager holds, or nil
| field | content |
|---|---|
address | the address of the package, "" when it has none |
items | what is inside: a list of {name =, count =, display =} |
order | only for a package made for an order of the network (Stock Ticker, Redstone Requester) |
order holds id (the number of the order), index (the place of this package among those this Packager makes for the order, from 1), final (true for its last one), link_index and final_link (the same, among the Packagers of the network that share the order), and items, every item of the order.
A package only stays a moment: ask often (every 0.1 second) to see each one.
local packager = peripheral.find("packager")
local box = packager.package()
if box then
print("to " .. box.address .. ": " .. #box.items .. " stacks")
endSee also packager.set_package_address()
packager.set_package_address(address)
Changes the address of the package the Packager holds, before it leaves. When it holds none, the program stops with the packager holds no package.
addressstring- the new address, cut to 128 characters
A Packager that empties a mine's chest, and sends what has no address to the warehouse:
local packager = peripheral.find("packager")
while true do
local box = packager.package()
if box and box.address == "" then
packager.set_package_address("Warehouse")
end
sleep(0.1)
endSee also packager.package()
Package ports
A Package Frogport (type frogport) hangs on a Chain Conveyor; a Postbox (type postbox) stands next to a Train Station. Each has an address: it takes the packages for that address, and sends on the packages put into it. Their methods are the same, written port here.
local port = peripheral.find("frogport")
print("this frog catches packages for " .. port.address())port.address()
The address the port catches packages for. Create allows * in it ("Kitchen*"), and an empty address catches the packages that have none.
- string
- the address it takes packages for
See also package_port.set_address()
port.set_address(address)
Changes the address the port catches packages for, as its screen does.
addressstring- the new address, cut to 128 characters
See also package_port.address()
port.configuration()
What the port does:
- string|nil
"send_receive","send", or nil when the port has no target
"send_receive": it catches the packages for its address, and sends the others on;"send": it only sends the packages put into it, and catches nothing;nil: it is not linked yet to a Chain Conveyor or a Train Station.
See also package_port.set_configuration()
port.set_configuration(mode)
Chooses what the port does. Another word stops the program; "send_recieve", the spelling of Create's ComputerCraft peripheral, works too.
modestring"send_receive"or"send"
- boolean
- true, or false when the port has no target
See also package_port.configuration()
port.list()
The packages waiting in the port, read like inventory.list().
- table
- the packages the port holds, indexed by slot number; empty slots are missing
local port = peripheral.find("postbox")
local known = 0
while true do
local count = 0
for _, stack in pairs(port.list()) do
count = count + stack.count
end
if count > known then
print("You have mail: " .. count .. " package(s)")
end
known = count
sleep(5)
endSee also package_port.get()
port.get(slot)
One slot of the port. A slot outside it stops the program, as with packager.get().
slotnumber- a slot of the port, from 1
- table|nil
- the package in that slot, or nil when it is empty
See also package_port.list()
Redstone Requester
A Redstone Requester belongs to the logistics network of a Stock Link (right-click the Stock Link with it before placing it). On each redstone pulse, it orders the same items from the network, sent to its address. A program changes the order and sends it without redstone.
Sends the order now, like a redstone pulse. Once per tick at most: a second call in the same tick fails and says to wait (sleep(0)).
In "strict" mode nothing leaves unless every item is in stock; in "allow_partial" mode, what there is leaves.
See also redstone_requester.set_request() redstone_requester.set_configuration()
req.set_request(...)
Replaces the order. An id alone asks for one item.
...string|table- up to 9 items: an id,
{name =, count =}with a count from 1 to 256, or nil for an empty slot
local req = peripheral.find("redstone_requester")
req.set_request("minecraft:bread", {name = "minecraft:coal", count = 32})More than 9 items stops the program with too many items for 'set_request' (9 at most), a count out of range with bad argument #2 to 'set_request' (count 1 to 256).
See also redstone_requester.get_request() redstone_requester.request()
req.set_crafting_request(count, ...)
Orders ingredients together with their recipe, for an automatic crafting line.
countnumber- how many times to craft, from 1 to 256
...string|table- the 9 squares of the crafting grid, row by row: an id,
{name =, count =}, or nil for an empty square
The items are sent like with set_request, the recipe attached: at the other end, a Re-Packager makes one package per craft, and a Packager unpacking them into Mechanical Crafters lays each item on its square. The count of an item is how many of it the order asks for, so give each square as many items as there are crafts:
local req = peripheral.find("redstone_requester")
local plank = {name = "minecraft:oak_planks", count = 4}
-- 4 crafting tables: planks on the first two squares of the first two rows
req.set_crafting_request(4, plank, plank, nil, plank, plank)See also redstone_requester.set_request()
req.get_request()
The order the requester sends, indexed by square as it was set: a crafting pattern keeps its holes, so set_crafting_request(1, "oak_planks", nil, "stick") reads back with a square 1 and a square 3, and no square 2. Go through it with pairs, which skips the holes.
- table
- the items of the order,
{name =, count =, display =}indexed by square, from 1 to 9; empty squares are missing
local req = peripheral.find("redstone_requester")
for square, item in pairs(req.get_request()) do
print(square .. ": " .. item.count .. " x " .. item.display)
endSee also redstone_requester.set_request()
req.configuration()
Whether the requester sends what there is ("allow_partial") or waits until everything is in stock ("strict").
- string
"allow_partial"or"strict"
req.set_configuration(mode)
Chooses the mode. Another word stops the program.
modestring"allow_partial"or"strict"
See also redstone_requester.configuration()
req.address()
Where the packages of the order go.
- string
- the address its packages go to
See also redstone_requester.set_address()
req.set_address(address)
Changes where the packages of the order go.
addressstring- the new address, cut to 128 characters
Keeping the furnaces fed: the coal chest on the left of the computer never runs low.
local req = peripheral.find("redstone_requester")
local chest = peripheral.wrap("left")
req.set_request({name = "minecraft:coal", count = 64})
req.set_address("Furnaces")
req.set_configuration("allow_partial")
while true do
if chest.count("minecraft:coal") < 32 then
req.request()
sleep(30) -- the time for the package to arrive
end
sleep(5)
endSee also redstone_requester.address()
Stock Ticker
A Stock Ticker joins the logistics network of a Stock Link: it sees every item of the inventories that the Packagers of that network reach. It sends items from it to any address, the way its Stock Keeper (a mob seated in front of it) does for players, and it keeps the payments of the shops.
ticker.stock()
The whole stock of the network. count is the total of that item in all the inventories, often far more than 64.
- table
- every item of the network, a list of
{name =, count =, display =}, one entry per kind of item
local ticker = peripheral.find("stock_ticker")
for _, entry in ipairs(ticker.stock()) do
print(entry.count .. " x " .. entry.display)
endticker.stock_item(n)
One entry of the stock, without building the whole list. The order of the list changes when the stock changes.
nnumber- the place of the entry in the list, from 1
- table|nil
- entry
nof the liststock()gives, or nil past its end
See also stock_ticker.stock()
ticker.request(address, ...)
Sends items of the network to an address, in packages. Once per tick at most, since the stock it reads is counted once per tick: a second call in the same tick fails and says to wait (sleep(0)).
addressstring- where the packages go, cut to 128 characters
...table- filters
{name =, count =};nameis an item id (a plain name is a Minecraft item), with*and?allowed, 256 characters at most; withoutcount, all of it
- number
- how many items were asked for in all, 0 when nothing matched
Each filter picks items of the stock:
nameis compared with the complete id:"minecraft:iron_ingot".*stands for any text and?for one character:"minecraft:*_log"takes every kind of log,"create:*"everything from Create. A plain name without:is a Minecraft item, as everywhere else:"iron_ingot"is"minecraft:iron_ingot". A pattern is compared with the whole id:"*_ingot"takes the ingots of every mod.countis the most to take, over all the items the name matches, in the order ofstock(). Without it, the filter takes all of them.- The filters take one after the other: a second filter only finds what the first one left.
local ticker = peripheral.find("stock_ticker")
local n = ticker.request("Workshop",
{name = "minecraft:iron_ingot", count = 64},
{name = "minecraft:*_log", count = 128},
{name = "create:andesite_alloy"})
print(n .. " items on their way to the Workshop")It returns how many items were asked for. They leave from the Packagers of the network, so they arrive a while later, in several packages. A filter that is not a table with a name stops the program with bad argument #3 to 'request' ({name = id, count = n} expected).
See also stock_ticker.stock()
ticker.list()
The payments the Stock Ticker received from the shops of its network, read like inventory.list().
- table
- the payments it holds, indexed by slot number; empty slots are missing
See also stock_ticker.get()
ticker.get(slot)
One payment slot. A slot outside them stops the program, as with packager.get().
slotnumber- a payment slot, from 1
- table|nil
- the stack in that slot, or nil when it is empty
See also stock_ticker.list()
Table Cloth shop
A Table Cloth that sells something is a shop. Players click it to fill a Shopping List, pay at the Stock Keeper of a Stock Ticker, and the goods leave the network in packages for the shop's address; the payment stays in the Stock Ticker.
The shop must know its Stock Ticker. Create links them when you make the shop in game: right-click the Stock Keeper while holding a Table Cloth, choose the wares, place the cloth. A program then changes its wares, price and address.
shop.shop()
Whether the cloth sells something. All the other methods, except set_wares, need a shop: on a plain cloth, they stop the program with this table cloth is not a shop.
- boolean
- true when the cloth is a shop (it has wares)
See also table_cloth.set_wares()
shop.wares()
The wares of the shop.
- table
- what one purchase gives, a list of
{name =, count =, display =}
local shop = peripheral.find("table_cloth")
for _, ware in ipairs(shop.wares()) do
print(ware.count .. " x " .. ware.display)
endSee also table_cloth.set_wares()
shop.set_wares(...)
Sets what one purchase gives, and makes the cloth a shop. Called with nothing, it turns the shop back into a plain cloth.
...string|table- up to 9 items: an id or
{name =, count =}with a count from 1 to 256
local shop = peripheral.find("table_cloth")
shop.set_wares({name = "minecraft:bread", count = 8}, "minecraft:cake")Items lying on the cloth, put there by a player, stop the program with the table cloth holds items: take them off first.
See also table_cloth.wares() table_cloth.shop()
shop.price_item()
The payment item. Its count is 1: the price itself is price_count().
- table|nil
- the item asked as payment,
{name =, count =, display =}, or nil when none is set
See also table_cloth.set_price_item() table_cloth.price_count()
shop.set_price_item(id)
Sets the item asked as payment. A shop without a price item refuses to sell.
idstring|nil- an item id; nil takes the price away
See also table_cloth.price_item()
shop.price_count()
The price, in payment items.
- number
- how many of the payment item one purchase costs
See also table_cloth.set_price_count()
shop.set_price_count(n)
Sets the price, in payment items.
nnumber|nil- from 1 to 100 (kept within); nil gives 1
See also table_cloth.price_count()
shop.address()
The address of the packages of goods: usually a Frogport or a Postbox at the shop counter.
- string
- where the shop sends what it sells
See also table_cloth.set_address()
shop.set_address(address)
Changes where the shop sends what it sells.
addressstring- the new address, cut to 128 characters
A bakery whose price follows the stock: bread is dearer when little is left.
local shop = peripheral.find("table_cloth")
local ticker = peripheral.find("stock_ticker")
shop.set_price_item("minecraft:emerald")
while true do
local bread = 0
for _, entry in ipairs(ticker.stock()) do
if entry.name == "minecraft:bread" then
bread = entry.count
end
end
if bread < 64 then
shop.set_price_count(3)
else
shop.set_price_count(1)
end
sleep(30)
endSee also table_cloth.address()