Modular Computers the manual GitHub

Energy field card

An energy field card suspends a creature or an item in a sphere of translucent blue energy. What it holds falls in place and can’t act: it doesn’t move, attack or react (a creeper doesn’t blow, a player can’t hit or use anything). The field moves, and what it holds with it: lift a friend to a higher floor, or hold a mob out of the way. It never moves blocks. It hums up as it takes hold, hums softly round what it holds, and powers down as it lets go. In a Bot Golem holding itself, it’s how the golem flies.

Facts

| | | |—|—| | Type | field | | Where | Any expansion slot of a computer, an expansion hub, or a golem | | /dev | field0 (field1 the next) | | Reach | 16 blocks from its computer (a robot holding itself carries it along) | | Speed | 10 blocks a second | | Power | Two running CPUs’ a tick while it holds something, and a CPU’s tick a block moved | | Recipe | Ender pearl, chip, amethyst shard over three copper nuggets over three gold nuggets |

A pig held up in an energy field: a translucent blue sphere round it A pig held in a field, two blocks up.

Where things are

Positions are in its computer’s frame: forward out of its front, right, and up. On a block, right is as someone facing its front sees it (as every face is named); a robot’s is its own. So a program written for one computer works however the computer is turned.

The field holds one thing at a time. It lets go when told to, when what it holds is gone (it dies, it’s picked up), when it’s moved out of reach, when its computer has no power or stops its program, and when its world is saved and loaded (a field isn’t saved). What it held then falls. A move that meets a block stops there: its event says it was blocked.

In mcos

Reading /dev/field0 gives what it’s doing, and what it holds and where:

holding minecraft:pig 2.0 0.0 3.0
idle

A line written is an action:

Line Does
capture self Holds its own robot
capture ID Holds what has that id (from scan)
capture forward [right [up]] Holds what’s nearest that point, within a block and a half
move forward [right [up]] Moves the field by that much
release Lets go
echo "capture 2" > /dev/field0
echo "move 0 0 4" > /dev/field0
echo release > /dev/field0

Its ioctls are its methods, by name. Its events come as sys.poll’s PRI, and pull takes them. cat /sys/field0 lists its methods.

Methods

scan([range]) → list

What’s within range (16 at most) of its computer, nearest first: creatures (players too) and items, each {id, name, forward, right, up, distance}.

capture(target) → name, or nil and why

Holds a creature or an item: an id from scan, "self" (a robot holding itself), or a point forward[, right[, up]] (the nearest thing within a block and a half of it). Answers its name. Fails with already holding something, nothing there, nothing with that id here, too far, another field holds it, or in a block, no robot to hold.

move(forward[, right[, up]]) → true, or nil and why

Moves the field by that much, at 10 blocks a second, never through blocks. It answers at once; its event says how it went: arrived, or blocked. Fails with holding nothing, or too far (out of its reach, unless it holds its own robot).

release() → true

Lets what it holds go: it falls from where it is.

get() → {state, name, forward, right, up}

What it’s doing (idle, holding or moving), and what it holds and where.

set(action) → true

An action as a table: {action = "capture", target}, {action = "move", forward, right, up}, {action = "release"} (the file’s lines are these).

pull() → event or nil

Its oldest event, or nil.

Events

event Other fields When
arrived   a move got there
blocked why a move met a block
lost why it let go on its own: gone, out of range, no power, interrupted (its world saved and loaded)

Example

Lift the nearest player a floor or two, and set them down on the edge above:

-- Lift a friend to a higher floor: hold the nearest player (or any creature) in the energy field,
-- carry them up FLOORS floors and over onto the floor's edge in front of the computer, and let
-- them go there. Each move is waited for: its event says it arrived, or what stopped it.
local sys = require("sys")

local FLOOR = 4 -- blocks a floor
local FLOORS = tonumber(arg[1] or "1")
local OVER = 2 -- blocks forward, onto the floor above

local card = assert(sys.open("/dev/field0"))

-- Waits for the card's next event, and gives it.
local function event()
  while true do
    local got = sys.ioctl(card, "pull")
    if got then
      return got
    end
    sys.poll({[card] = {PRI = true}})
  end
end

local function go(forward, up)
  assert(sys.ioctl(card, "move", forward, 0, up))
  local moved = event()
  if moved.event ~= "arrived" then
    print(moved.event .. ": " .. tostring(moved.why))
    sys.ioctl(card, "release")
    os.exit(1)
  end
end

local near = assert(sys.ioctl(card, "scan"))
local friend
for _, seen in ipairs(near) do
  if seen.name == "minecraft:player" then
    friend = seen
    break
  end
end
friend = friend or near[1]
if not friend then
  print("no one near")
  os.exit(1)
end

assert(sys.ioctl(card, "capture", friend.id))
go(0, FLOOR * FLOORS)
go(OVER, 0)
sys.ioctl(card, "release")
print("lifted " .. friend.name .. " " .. FLOORS .. " floor(s)")