Modular Computers the manual GitHub

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 |

Two bot golems: one with a screen in, its face lit; one without, an empty bezel 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.

The golem's parts view: the board through its iron chest, its robotics chip soldered at the bottom right 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 on the ground beside its legs 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:

  1. 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).
  2. A chest right in front of it, with an axe in it.
  3. 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