Scripting Examples#
Paste an example into the Logic Terminal, press Save, then Run. Examples marked (IDs) need buses with identifiers: right-click each bus, type the ID in its GUI and press Set. Directions ("up", "north", …) are relative to the Logic Bus; change them to match your build. Item ids are 1.20.1 ids.
1. Import everything from a chest#
var chest = side("up");
function tick() {
if (chest) chest.pull(); // any item, as many as the budget allows
}
2. Import only some items#
var chest = side("up");
var wanted = ["minecraft:iron_ingot", "minecraft:gold_ingot", "minecraft:diamond"];
function tick() {
if (!chest) return;
for (var i = 0; i < wanted.length; i++) {
chest.pull(wanted[i]);
}
}
3. Keep a machine stocked#
var machine = side("north");
// Top up `id` in `ep` until it holds `amount`.
function ensure(ep, id, amount) {
var have = ep.count(id);
return have < amount ? ep.push(id, amount - have) : 0;
}
function tick() {
if (!machine) return;
ensure(machine, "minecraft:coal", 16);
}
4. Stock keeper with autocrafting and a cooldown#
Without a cooldown the script would order the same craft again and again while the first order is still running.
var targets = [
{ id: "minecraft:stick", min: 64, batch: 64 },
{ id: "minecraft:torch", min: 128, batch: 64 },
{ id: "minecraft:iron_block", min: 8, batch: 4 }
];
var lastOrder = {}; // id -> game time of the last order
var COOLDOWN = 20 * 60; // 1 minute
function tick() {
for (var i = 0; i < targets.length; i++) {
var t = targets[i];
var last = lastOrder[t.id];
if (last !== undefined && time() - last < COOLDOWN) continue;
if (net.count(t.id) < t.min) {
var crafts = net.craft(t.id, t.batch);
if (crafts > 0) {
lastOrder[t.id] = time();
log("ordered", t.batch, t.id);
} else {
log("cannot craft", t.id);
}
}
}
}
5. Sort a chest: ores and wood to separate chests, the rest to the network#
var input = side("up");
var ores = side("west");
var wood = side("east");
function tick() {
if (!input) return;
var stacks = input.list();
for (var i = 0; i < stacks.length; i++) {
var id = stacks[i].id;
if (ores && /_ore$|^minecraft:raw_/.test(id)) {
input.move(ores, id);
} else if (wood && /_log$|_planks$/.test(id)) {
input.move(wood, id);
} else {
input.pull(id); // everything else goes into the network
}
}
}
6. Overflow protection#
When free space gets low, dump junk into an overflow chest so the network never fills up.
var overflow = side("down");
var junk = ["minecraft:cobblestone", "minecraft:dirt", "minecraft:gravel",
"minecraft:cobbled_deepslate", "minecraft:rotten_flesh"];
var alarm = false;
function tick() {
var low = net.freeBytes() < 2000;
if (low !== alarm) { // log only when the state changes
alarm = low;
log(low ? "LOW SPACE: " + net.freeBytes() + " bytes free" : "space OK");
}
if (!low || !overflow) return;
for (var i = 0; i < junk.length; i++) {
overflow.push(junk[i], 256);
}
}
7. Round-robin feeding of two machines#
Global variables survive between runs, so a counter can alternate targets.
var machines = [side("east"), side("west")];
var turn = 0;
function tick() {
var target = machines[turn % machines.length];
turn++;
if (target) target.push("minecraft:raw_iron", 8);
}
8. Throughput meter#
Logs how many items per second flow into the network.
var ITEM = "minecraft:iron_ingot";
var lastCount = null;
var lastTime = 0;
function tick() {
var now = net.count(ITEM);
var t = time();
if (lastCount !== null && t > lastTime) {
var perSecond = (now - lastCount) / ((t - lastTime) / 20);
log(ITEM, perSecond.toFixed(2) + "/s");
}
lastCount = now;
lastTime = t;
}
9. Balance two chests#
Evens out a specific item between two chests by moving items directly from the fuller one to the emptier one.
var a = side("west");
var b = side("east");
var ID = "minecraft:cobblestone";
function tick() {
if (!a || !b) return;
var ca = a.count(ID), cb = b.count(ID);
var diff = Math.floor((ca - cb) / 2);
if (diff > 0) a.move(b, ID, diff);
else if (diff < 0) b.move(a, ID, -diff);
}
10. Self-diagnosing script#
Wrap the work in try/catch to keep running through ordinary errors (such as a mistyped item id) and report them.
var chest = side("up");
function tick() {
try {
chest.pull("minecraft:iorn_ingot"); // typo: throws "unknown item"
} catch (e) {
log("problem:", e.message);
}
}
Budget errors (instruction, time, call limits) cannot be caught, they stop the bus.
Examples with identifiers#
11. Feed a group of furnaces (IDs)#
Give every bus that sits next to a furnace the ID smelters. One script on any bus (even one without the ID) feeds all of them. push fills them in order.
function tick() {
var furnaces = side("north", "smelters"); // north of every "smelters" bus
if (!furnaces) return;
furnaces.push("minecraft:raw_iron", 16);
furnaces.push("minecraft:coal", 8);
}
12. Many input chests, many output chests (IDs)#
Buses with ID inbox have chests on top, buses with ID outbox have chests below.
function tick() {
var inbox = side("up", "inbox");
var outbox = side("down", "outbox");
if (inbox) inbox.pull(); // collect everything into the network
if (outbox) outbox.push("minecraft:cobblestone", 64);
}
13. Sorting by group (IDs)#
var sources = side("up", "sort_in");
var ores = side("up", "sort_ores");
var wood = side("up", "sort_wood");
function tick() {
if (!sources) return;
var stacks = sources.list();
for (var i = 0; i < stacks.length; i++) {
var id = stacks[i].id;
if (ores && /_ore$|^minecraft:raw_/.test(id)) sources.move(ores, id);
else if (wood && /_log$|_planks$/.test(id)) sources.move(wood, id);
}
}
14. Status report for several groups (IDs)#
var groups = ["smelters", "inbox", "outbox"];
function tick() {
var parts = [];
for (var i = 0; i < groups.length; i++) {
parts.push(groups[i] + "=" + buses(groups[i]));
}
log("buses:", parts.join(" "));
}
15. One script, behaviour chosen by ID (IDs)#
The same script text can be pasted into several buses; busId tells each one who it is.
function tick() {
var me = side("up");
if (!me) return;
if (busId === "importer") me.pull();
else if (busId === "coal") me.push("minecraft:coal", 32);
else log("no role for", busId || "(no id)");
}
16. Fail-safe group access (IDs)#
function group(dir, id) {
var ep = side(dir, id);
if (!ep) log("group", id, "not found on side", dir, "(" + buses(id) + " buses)");
return ep;
}
function tick() {
var ep = group("up", "furnaces");
if (ep) ep.push("minecraft:coal", 8);
}
17. Journal note when a resource runs low (journal)#
var warned = false;
function tick() {
var iron = net.available("minecraft:iron_ingot"); // stored minus reserved
if (iron < 64 && !warned) {
journal.warn("Iron is low: " + iron, "minecraft:iron_ingot");
warned = true;
} else if (iron >= 128) {
warned = false;
}
}
18. Stock rules managed by a script (stock)#
var wanted = {
"minecraft:iron_ingot": 256,
"minecraft:redstone": 128,
"minecraft:glass": 64
};
function tick() {
for (var id in wanted) {
stock.set(id, wanted[id]); // creates the rule, or updates the minimum
}
}
19. Save energy: pause bulk orders when the network is low on power (queue, energy)#
function tick() {
var e = net.energy();
if (!e) return;
var q = net.queue();
for (var i = 0; i < q.length; i++) {
if (q[i].id === "minecraft:iron_block") {
if (e.percent < 20) net.pause(q[i].id);
else if (e.percent > 50) net.resume(q[i].id);
}
}
}
20. Tell the player why a craft is impossible (why, alert)#
function tick() {
var why = net.why("minecraft:piston", 8);
if (why && why.code === "missing") {
alert("Piston: missing " + why.count + " x " + why.id);
}
}
21. Plan before ordering (plan)#
function tick() {
var p = net.plan("minecraft:hopper", 4);
if (p && p.ok) {
for (var i = 0; i < p.steps.length; i++) log(p.steps[i].id, "x" + p.steps[i].crafts);
net.craft("minecraft:hopper", 4);
}
}
22. Recipe settings at startup (recipes)#
The top level runs once when the script is compiled, so it is a good place for one-time setup.
recipes.block("minecraft:iron_block"); // never craft iron blocks automatically
recipes.prefer("minecraft:oak_planks"); // use oak when a recipe accepts any planks
recipes.skipUnpacking(true);
function tick() {}
23. Journal summary of the order queue (queue, journal)#
function tick() {
var q = net.queue();
var total = 0;
for (var i = 0; i < q.length; i++) total += q[i].crafts;
if (total > 200) journal.write("Queue is long: " + total + " crafts");
}
Found a mistake? This page is generated from docs/wiki/Scripting-Examples.md in the mod repository.