-
Notifications
You must be signed in to change notification settings - Fork 0
Standard Library
Every builtin lives in the global scope. Argument counts are enforced; [x] marks an
optional argument.
| 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)
| 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") }
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")
}
}
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)
}
}
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]) }
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)
}
| 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. |
| 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)
}
}
| 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)
}
| 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!")
}
}
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 "", ",")
| 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. |
| 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. |
| 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. |
| 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