Bot Golem
The Bot Golem is a robot a block high, built like an iron golem: a computer you can walk anywhere. It holds a computer’s parts, its face is a tier 1 screen, and a robotics device soldered onto its board is the only way it moves. It never acts on its own: a program drives it.
Facts
| | | |—|—| | Kind | Robot (an entity) | | Stack | 1 (it keeps its parts) | | Size | A block high, through a one-block gap | | Speed | A player’s walking pace | | Slots | CPU, EEPROM, a battery, 2 RAM, 1 disk, a tier 1 screen (its face), 2 cards, its hands | | Soldered | Its robotics device, on its last expansion lane | | Getting one | Creative only, for now |
A golem with a tier 1 screen in its gold slot, and one without: its face an empty bezel.
Use
Use the golem item on a block: the golem stands there, facing you. Right-click it to see its screen (when its face has one), or crouch and right-click for its parts. Hit it to pick it up: it drops as its item, its parts and its board’s id kept in it, as a broken case keeps them. Holding that item (a golem’s or a torso’s), crouch and right-click, in the air or at a block, to open its parts right there: change its parts, what it holds and its crafting cards’ slots without setting it down (it’s off while it’s an item: no bus till it’s set down). Nothing else harms it. It’s solid: you walk into it, not through it, and can stand on it. While it stands on its legs nothing shoves it: not a player walking into it, a mob, or a blast.
Its parts view is a case’s, seen through its iron chest: the same board, the same slots, those its size has. Its gold slot takes only a tier 1 screen, which is its face. Its last expansion lane has its robotics device soldered on, so it has no slot there. Its parts are its own to change: none is soldered but the robotics device.
Its parts view: the bus order panel lists its robotics device, soldered on EXP 4.
Right of its board, under its buttons, are its hands: what it holds (a tool, blocks to place, a bucket), shown in its hand in the world, and under it its off hand, where it catches what it breaks when it has no storage. A program uses it as a player would: places blocks, opens doors and presses buttons, breaks blocks with a tool in a player’s time, hits mobs with a weapon, and moves items to and from a chest in front of it. When you pick the golem up, what it holds goes with it. On its legs it presses pressure plates, as anything walking does.
A crafting card gives it storage (a tiny chest appears on its back) and a crafting grid its programs craft with; what it breaks goes there first. Each card has a tab under its hands.
Its legs, and flight
A program can detach the golem’s legs (detachLegs). With an energy field card
holding the golem itself first, it flies on, much faster than it walks, its program moving the field,
its legs left standing below; in flight it still runs, crafts and works buttons and doors, but uses
no tools (it has no footing) and presses no pressure plates. With nothing holding it up, it falls
over and powers off. Its legs, emerald and redstone clamps on top, plug into sockets under its
torso: attachLegs, within three blocks of them, takes it to them and onto them.
A golem’s torso, beside its legs.
A right click on legs pops them up into your inventory (the golem’s use pops them into its own),
and their item, used on a block, stands them there. If its power runs out or it’s turned off in
flight, its field lets go and its torso falls: hit it to pick it up as a Bot Golem Torso (its parts
in it), or right-click it for its view. A torso crafted over its legs, in any crafting grid (2x2 is
enough), is the golem again, with all it kept.
It runs on its battery, as a case does: swap the battery, or walk it onto a charging pad. It does nothing until a program tells its robotics device to act. See Robotics device for what a program can do with it, and its examples.
A whole job: a tree on a ledge
This program uses all of it: the robotics device, a crafting card for storage, and an energy field card to fly. Set it up:
- A golem with a CPU, RAM, an EEPROM, a battery, a disk with mcos, a crafting card and an energy field card (a screen in its gold slot to watch it).
- A chest right in front of it, with an axe in it.
- A tree on a ledge: its trunk 5 blocks ahead of the golem, its lowest log 10 blocks up (the ledge under it, and under the spot beside it), the way up and over clear.
Save the program as /home/golem-tree.lua and run lua /home/golem-tree.lua (or lua
/home/golem-tree.lua 6 3 for a tree 6 up and 3 ahead). The golem takes the axe, holds itself in
its field and picks up its legs, flies up beside the trunk, stands on its legs there, cuts the
logs (its field lifting it, legs and all, to reach the ones above), flies home, stands on its legs
at the chest, and puts the wood and the axe away. It says each step as it goes, and why it stopped
if something’s in its way.
-- Cut down a tree up on a ledge and bring its wood home: a bot golem with a crafting card (its
-- storage) and an energy field card, a chest in front of it holding an axe, and a tree on a ledge
-- ahead of it: its trunk FORWARD blocks ahead and its lowest log UP blocks up, standing on the
-- ledge, the golem's way there clear.
-- lua golem-tree.lua [up [forward]] (10 and 5)
-- It takes the axe, holds itself in its field and leaves its legs (picking them up: no tools while
-- it flies), flies up to the ledge beside the trunk, sets its legs down and stands on them, cuts
-- the trunk (its field lifting it, legs and all, to reach the logs above), flies home, stands on
-- its legs at the chest again, and puts the wood and the axe in it (what else the tree dropped, its
-- saplings and sticks, it keeps).
local sys = require("sys")
local devices = require("devices")
local UP = tonumber(arg[1] or "10")
local FORWARD = tonumber(arg[2] or "5")
local LOG = "_log$" -- what wood's name ends with (minecraft:oak_log)
local SETTLE = 1 -- seconds legs dropped mid-air take to land
local robot = assert(devices.open("robotics0"))
local field = assert(devices.open("field0"))
local storage = assert(devices.open("crafting0"))
-- A call's answer, or the program ends with why it failed.
local function need(ok, why)
if ok == nil or ok == false then
io.stderr:write("golem-tree: ", tostring(why), "\n")
os.exit(1)
end
return ok, why
end
-- Waits for a device's next event, and gives it.
local function event(device)
local fd = devices.info(device).fd
while true do
local got = device.pull()
if got then
return got
end
sys.poll({[fd] = {PRI = true}})
end
end
-- Says what it's doing (its output: a service's log).
local function say(text)
print(text)
io.stdout:flush()
end
-- Flies (its field moves it) by forward, up; ends the program if something's in the way.
local function fly(forward, up)
need(field.move(forward, 0, up))
local moved = event(field)
need(moved.event == "arrived", "flying " .. forward .. " forward, " .. up .. " up: " .. moved.event .. " (" .. tostring(moved.why) .. ")")
end
-- The storage slot holding something whose name matches 'pattern', or nil.
local function slot(pattern)
for _, item in ipairs(storage.list()) do
if item.name:match(pattern) then
return item.slot
end
end
end
-- Off its legs, in its own field, holding them (it flies; a block up, they're below it to pop up).
local function takeOff()
if not robot.get().legs then
return
end
if field.get().state == "idle" then
need(field.capture("self"))
end
need(robot.detachLegs())
sys.sleep(SETTLE) -- (left mid-air, they fall to whatever's below)
fly(0, 1)
need(robot.use("down")) -- popped up into its storage
end
-- Onto its legs, set down below it.
local function land()
local held = robot.held()
need(storage.equip(need(slot("bot_golem_legs$"), "its legs aren't in its storage")))
need(robot.use("down"))
need(robot.attachLegs())
local on = event(robot)
need(on.event == "attached", "landing: " .. on.event .. " (" .. tostring(on.why) .. ")")
repeat until not field.pull() -- (its field let go as it landed: that's said, and done with)
if held then
need(storage.equip(need(slot(held.name), "what it held is gone"))) -- back in its hand
end
end
-- Breaks the block in front with what it holds, and says what it broke.
local function chop()
need(robot.swing("front"))
local swung = event(robot)
need(swung.event == "broke", "cutting: " .. swung.event .. " (" .. tostring(swung.why) .. ")")
return swung.block
end
say("taking the axe")
-- 1. The axe, from the chest.
need(robot.take("front") > 0 or nil, "no axe in the chest")
-- 2. Up to the ledge, beside the trunk, and onto its legs there.
say("taking off")
takeOff()
fly(0, UP)
fly(FORWARD - 1, 0)
say("landing by the tree")
land()
-- 3. The trunk: its lowest log, then each above it, its field lifting it (on its legs: it can cut),
-- clearing the leaves over its head as it goes up.
local LEAVES = "_leaves$"
local function ahead(pattern)
local name = robot.scan("front").name
return name and name:match(pattern)
end
local cut = 0
need(field.capture("self"))
while ahead(LOG) do
say("cutting a log")
chop()
cut = cut + 1
local above = robot.scan("up").name
if above and above:match(LEAVES) then
need(robot.swing("up"))
local swung = event(robot)
need(swung.event == "broke", "clearing the leaves: " .. swung.event .. " (" .. tostring(swung.why) .. ")")
end
fly(0, 1)
end
fly(0, -cut)
-- 4. Home: off its legs again, back over the chest's side, down, and onto them.
say("flying home")
takeOff()
fly(-(FORWARD - 1), 0)
fly(0, -UP)
land()
-- 5. The wood, then the axe, into the chest.
say("putting it away")
while slot(LOG) do
local stored, left = storage.store("front", slot(LOG))
need(stored, "the chest is full: " .. tostring(left) .. " left")
end
need(robot.store("front"))
print("cut " .. cut .. " logs, and brought them home")
Mobs
Spiders keep away from golems, as they keep away from armadillos, and a skeleton riding one is carried off with it. A flying golem scares chickens and cows (mooshrooms too) off as it comes near. Sheep don’t care.
Notes
- A golem and its parts are each one thing, by their ids: placing one you picked up moves it into the world, in creative too (it leaves your hand). A copy of one that’s in the world (creative’s Ctrl and pick block makes them) can’t be placed, and a copied part, a disk say, in another computer stays off its bus until the one in the world is gone. Nothing is given a new id.
- It knows nothing of where it is: a walk is given relative to itself (forward, right, up). A GPS card is planned.
- A walk under way when its world is saved doesn’t go on after a load: it ends then, blocked
(
interrupted), so a program waiting on it hears. - When its chunk unloads its program freezes, as a case’s does, and goes on when it loads.