Skip to content

Standard Library

Dimitri edited this page Aug 29, 2026 · 5 revisions

Every builtin lives in the global scope. Argument counts are enforced; [x] marks an optional argument.

Console

Function Returns Description
print(...) nil Prints up to 16 values, space-separated, to the console. Long lines wrap at 256 columns.
clear() nil Clears the console for every viewer.
read() string Blocks until a line is typed into the terminal, then returns it.
print("what is your name?")
let name = read()
print("hello, " + name)

Timing

Function Returns Description
sleep(ticks) nil Blocks for ticks game ticks (20 = 1 second). Non-positive returns instantly.
gametime() number Total ticks the world has existed. Monotonic.
daytime() number Overworld clock time; 0–23999 per day cycle.
day() number floor(daytime() / 24000) — the current day number.
uptime() number Ticks since this program started (0 when not running).
realtime() number Real-world Unix time, in whole seconds.
if daytime() > 13000 and daytime() < 23000 { print("night time") }

Wifi networking

Pots reach each other by hostname across any distance and across dimensions, as long as both chunks are loaded. Names are lowercase, 1–16 characters of a-z 0-9 - _.

Function Returns Description
hostname() string This pot's name.
sethost(name) bool Renames the pot. false if invalid or already taken.
send(host, value) bool Sends to one host. false if the host is unknown/unloaded or its mailbox is full.
broadcast(value) number Sends to every other host; returns the delivery count.
peers() list Sorted hostnames of all reachable pots, including this one.
has_msg() bool Whether a message is waiting.
recv() list Blocks forever until a message arrives.
recv(timeout) list or nil Blocks up to timeout ticks; nil on timeout.
ping(host) bool Whether that hostname is reachable right now (loaded and online).

A received message is always a two-element list: [sender_hostname, payload].

Payloads may be nil, bools, numbers, strings and lists (nested up to 8 deep). Sending a function raises send: cannot send a function. Payloads are deep-copied on delivery.

# door controller
sethost("door")
while true {
    let msg = recv()
    let from = msg[0]
    let body = msg[1]
    if body == "open" {
        rs_set("north", 15)
        send(from, "ok")
    } else if body == "close" {
        rs_set("north", 0)
        send(from, "ok")
    }
}

Redstone

Sides are up, down, north, south, east, west. An unknown side is a runtime error.

Function Returns Description
rs_set(side, level) nil Emit level (clamped 0–15) out of that side. Both weak and strong power.
rs_get(side) number The redstone signal the neighbour on that side is feeding into the pot.
rs_pulse(side, level, [ticks]) nil Emit level out of that side, then drop back to 0 after ticks game ticks (default 2).
rs_reset() nil Set all six outputs to 0.
rs_wait([timeout]) list or nil Blocks until any incoming signal changes, up to timeout ticks (forever if omitted). Returns [side, level] for the side that changed, or nil on timeout.

Output levels persist when the program stops and when the chunk unloads. reboot clears them. A pulse's countdown runs in the block entity's own tick, so it keeps counting even while the program is stopped or the chunk is unloaded; rs_set/rs_reset on that side cancels it. ticks must be positive.

rs_wait is the event-driven way to react to redstone: instead of polling rs_get in a loop, the program sleeps until an input actually changes, costing nothing per tick while it waits.

# repeater with a delay: mirror the east input onto the west output, 1s later
while true {
    let level = rs_get("east")
    sleep(20)
    rs_set("west", level)
}
# doorbell: chime whenever the button on the north side is pressed
while true {
    let change = rs_wait()
    if change[0] == "north" and change[1] > 0 {
        tone("bell", 19)
    }
}

Signs

Sides are up, down, north, south, east, west, same as redstone. Looks at the sign block on that side, if any — standing signs, wall signs and hanging signs all work. Reads and writes always target the sign's front text (4 lines).

Function Returns Description
sign_read(side) list or nil The 4 front-text lines as strings, or nil if there's no sign on that side.
sign_write(side, lines, [color]) bool Writes lines (a list of up to 4 elements, or a single value) to the sign's front text. false if there's no sign on that side.

lines shorter than 4 elements blanks out the remaining rows; a line over 48 characters is truncated. color is a dye color name ("red", "lime", "cyan", ...) recoloring all 4 lines; an unknown name is a runtime error.

sign_write("north", ["temperature", str(light()) + " light"], "cyan")
let lines = sign_read("north")
if lines != nil { print(lines[0]) }

Inventories

Sides are up, down, north, south, east, west, same as redstone. Reads look at whatever inventory-holding block is on that side — chest, barrel, furnace, hopper, shulker box, even a chest minecart parked in the space. Double chests are merged into one 54-slot container. A side with no inventory reads as nil (or 0/-1 where the function returns a number).

Function Returns Description
block(side) string Registry id of the block on that side, e.g. "minecraft:chest", "minecraft:air".
inv_size(side) number or nil Slot count, or nil if the neighbour has no inventory.
inv_get(side, slot) list or nil [item_id, count], or nil for an empty slot, an out-of-range slot, or no inventory.
inv_count(side, item) number Total of item across every slot. 0 if there's no inventory.
inv_find(side, item) number First slot holding item, or -1 if not found / no inventory.
inv_move(from, to, [item], [max]) number Moves items from one neighbour to another; returns how many actually moved.

Item names take the same shorthand as block ids — "coal" resolves to "minecraft:coal". A name that isn't in the item registry is a runtime error (inv_count: unknown item 'coal_ore', say), not a silent 0, so typos get caught instead of hidden.

inv_move moves through the same slot rules a hopper would: which slot it lands in depends on which face of the target block is touched, so feeding a furnace from the side fills fuel while feeding it from above fills the input, exactly like placing a hopper there. Omit item to move anything; omit max to move as much as fits. from and to must be different sides.

print(block("north"))                    # minecraft:chest
print(inv_count("north", "coal"))

while true {
    if inv_count("east", "coal") < 8 {
        inv_move("north", "east", "coal", 8)   # feeds the furnace's fuel slot, hopper-style
    }
    sleep(20)
}

World sensors

Function Returns Description
pos() list [x, y, z] of the pot.
dim() string Dimension id, e.g. "minecraft:overworld".
biome() string Biome id, e.g. "minecraft:plains".
weather() string "clear", "rain" or "thunder".
light() number Light level (0–15) of the block directly above the pot.
moon() number Moon phase 0–7; 0 is the full moon.

Players and sound

Function Returns Description
players([range]) list Names of players within range blocks (default 16, clamped 0–64).
say(text, [range]) number Sends <hostname> text to nearby players' chat; returns how many were reached. Text is truncated at 256 chars.
hear([timeout]) list or nil Blocks until a player chats within 16 blocks of the pot, up to timeout ticks (forever if omitted). Returns [player, text], or nil on timeout.
beep([pitch]) nil Plays a note block "bit" sound. pitch is a semitone 0–24, default 12 (F#4, the natural pitch).
tone(instrument, note) nil Plays any note-block instrument at semitone note 0–24. An unknown instrument is a runtime error.
instruments() list Every instrument name tone accepts: "harp", "bass", "bell", "flute", "pling", the trumpets, and the rest of the note-block roster.

Chat is only overheard while a program is running; up to 16 lines queue while the program is busy, oldest dropped first. The pot does not hear its own say, and commands are not chat.

# greeter
let seen = []
while true {
    for name in players(8) {
        if not contains(seen, name) {
            say("welcome, " + name)
            beep(18)
            push(seen, name)
        }
    }
    sleep(40)
}
# a pot you can talk to
while true {
    let msg = hear()
    if contains(lower(msg[1]), "open sesame") {
        say("as you wish, " + msg[0])
        rs_pulse("down", 15, 40)
    }
}

Hologram display

Function Returns Description
display(text) nil Floats text above the pot as a hologram, visible to everyone. Truncated at 128 chars; "\n" breaks lines.
display() nil Takes the hologram down (so does display("")).

The hologram is a real text display entity: it survives world reloads and keeps showing its last text while the program is stopped. Breaking the pot, or the reboot terminal command, removes it.

# a live clock face
while true {
    display("day " + str(day()) + "\n" + weather())
    sleep(100)
}

Mobs

Function Returns Description
entities([range]) list [type, name, distance] per living entity within range blocks (default 8, clamped 0–32), nearest first, capped at 32 results.

type is the entity's registry id, e.g. "minecraft:zombie" (players show as "minecraft:player"); name is its display name. distance is rounded to 1 decimal place.

for entry in entities(12) {
    if entry[0] == "minecraft:creeper" {
        say("creeper " + str(entry[2]) + " blocks out!")
    }
}

Persistent disk

A string-to-string key/value store saved with the block. Values are stringified on write, so what you read back is always a string — use num() to convert numbers back.

Function Returns Description
store(key, value) nil Writes. Errors if the key is over 64 chars, the value over 4,096, or the disk is at 256 keys.
load(key) string or nil Reads; nil if the key is absent.
delkey(key) bool Deletes; false if the key was absent.
keys() list All keys, in insertion order.
let runs = num(load("runs") or "0")
runs = runs + 1
store("runs", runs)
print("run number " + str(runs))

Note that a list written with store comes back as its printed form ("[1, 2, 3]"), not as a list. To round-trip a list, use join/split:

store("items", join(["axe", "rope"], ","))
let items = split(load("items") or "", ",")

Math

Function Returns Description
random() number Uniform in [0, 1).
randint(a, b) number Uniform integer, inclusive of both ends. Errors if b < a.
floor(x) ceil(x) round(x) number Rounding. round returns the nearest integer (halves go up).
abs(x) sqrt(x) number Absolute value, square root.
pow(a, b) number a to the power b.
min(a, b) max(a, b) number Exactly two arguments.
clamp(x, lo, hi) number x limited to [lo, hi]. Errors if hi < lo.
sin(x) cos(x) tan(x) number Trigonometry, in radians.
atan2(y, x) number The angle of the vector (x, y), in radians.
pi() number 3.14159..., for the trig functions.

Values and conversion

Function Returns Description
str(x) string The printed form of any value.
num(x) number or nil Parses a string (whitespace trimmed); passes numbers through; returns nil if unparseable. Errors on bools, lists and nil.
type(x) string "nil", "bool", "number", "string", "list" or "function".
len(x) number Length of a string or list. Errors on anything else.

Strings

Function Returns Description
upper(s) lower(s) string Case conversion.
trim(s) string Strips leading/trailing whitespace.
split(s, sep) list Splits on a literal separator (not a regex). An empty separator splits into single characters.
join(list, sep) string Joins stringified elements.
sub(s, from, [to]) string Substring; both bounds are clamped into range, so it never errors. to defaults to the end.
find(s, needle) number Index of the first occurrence, or -1.
contains(s, needle) bool Whether s has needle as a substring.
replace(s, old, new) string Every occurrence of old swapped for new. Errors if old is empty.
starts(s, prefix) ends(s, suffix) bool Whether s begins/ends with the given text.
repeat(s, n) string s concatenated n times.
chr(n) string The character with code n.
ord(s) number Code of the first character. Errors on an empty string.

Lists

Function Returns Description
push(list, value) list Appends and returns the same list (so calls chain).
pop(list) value Removes and returns the last element. Errors when empty.
remove(list, i) value Removes and returns index i; negative indices count from the end.
insert(list, i, value) list Inserts before index i (negative counts from the end; len(list) appends); returns the same list.
find(list, value) number Index of the first equal element, or -1.
contains(list, value) bool Whether the list has an equal element.
sort(list) list Sorts in place, ascending; the elements must be all numbers or all strings. Returns the same list.
reverse(list) list Reverses in place and returns the same list.
slice(list, from, [to]) list A new list of [from, to); both bounds are clamped, so it never errors. to defaults to the end.
range([from,] to) list [from, from+1, ..., to-1]; from defaults to 0. The end is exclusive.
len(list) number Element count.

find and contains dispatch on their first argument: given a list they search by equality, given a string they search for a substring.


See also: Errors & Gotchas · Examples · Wiki Home

Clone this wiki locally