API Documentation

Complete reference for the PLUTO-8 Lua API.

PLUTO-8 uses a sandboxed Lua 5.1 environment. Your cartridge code runs server-side; draw commands are sent to clients each frame. Optional parameters are shown as param?. Color values are integers 0–255.

Cartridge Format

A cartridge is a plain Lua source file. PLUTO-8 looks for three optional lifecycle functions:

lua
--[[__PLUTO8__
SPRITES:<hex data>
MAP:<hex data>
]]

function _init()
  -- called once when the cartridge loads
end

function _update()
  -- called 30 times per second; update game state here
end

function _draw()
  -- called after _update; issue draw commands here
end

Sprite and map data are stored as hex strings in the header comment and are loaded automatically at boot time.

Memory Map

PLUTO-8 provides 32 KB of addressable RAM:

AddressSizeContents
0x0000–0x0FFF4 KBSprite sheet (256 sprites × 8×8 pixels, 4-bit indexed)
0x1000–0x1FFF4 KBTilemap (128×64 tiles, 1 byte per tile)
0x2000–0x20FF256 BSprite flags (1 byte per sprite)
0x2100–0x21FF256 BPalette remapping table (draw palette)
0x2200–0x22FF256 BTransparency flags per color
0x3000–0x30FF256 BPersistent cart data (saved between runs)
0x4000–0x7FFF16 KBGeneral-purpose RAM (user variables)
0x8000–0xBFFF16 KBScreen buffer (256×256 × 1 byte)

Graphics — cls

cls(color?)

Clear the screen to color (default 0 = black). Also resets cursor to (0,0).

cls()         -- clear to black
cls(1)        -- clear to dark blue

Graphics — pset / pget

pset(x, y, color)

Set pixel at screen position (x, y) to color.

pget(x, y) → color

Return the color index of the pixel at (x, y). Returns 0 if out of bounds.

pset(10, 20, 8)
local c = pget(10, 20)  -- c == 8

Graphics — color

color(c)

Set the default draw color used when the optional c? argument is omitted from other drawing functions.

Graphics — line

line(x0, y0, x1, y1, c?)

Draw a line from (x0,y0) to (x1,y1) using Bresenham's algorithm.

line(0, 0, 255, 255, 7)   -- white diagonal

Graphics — rect / rectfill

rect(x, y, w, h, c?)

Draw a rectangle outline. (x,y) is the top-left corner; w and h are width and height in pixels.

rectfill(x, y, w, h, c?)

Draw a filled rectangle.

rectfill(10, 10, 50, 30, 8)  -- filled red box
rect(10, 10, 50, 30, 7)      -- white outline

Graphics — circ / circfill

circ(cx, cy, r, c?)

Draw a circle outline with center (cx,cy) and radius r.

circfill(cx, cy, r, c?)

Draw a filled circle.

circfill(128, 128, 40, 10)  -- filled yellow circle

Graphics — oval / ovalfill

oval(x0, y0, x1, y1, c?)

Draw an ellipse outline inscribed in the bounding box (x0,y0)–(x1,y1).

ovalfill(x0, y0, x1, y1, c?)

Draw a filled ellipse.

Graphics — print / cursor

print(text, x?, y?, c?)

Draw text at (x, y) in color c. Uses the built-in 4×6 bitmap font. If x/y are omitted, uses the current cursor position. Advances cursor after printing.

print("SCORE: "..score, 2, 2, 7)
cursor(x, y, c?)

Set the text cursor position (used by print when coordinates are omitted). Optionally sets default color.

Graphics — camera

camera(x, y)

Set the camera offset. All subsequent draw calls are offset by (-x, -y). Call camera(0,0) to reset.

camera(cam_x, cam_y)
map(0, 0, 0, 0, 16, 16)
camera(0, 0)   -- draw HUD at fixed position
print("HP: "..hp, 2, 2, 8)

Graphics — clip

clip(x, y, w, h)

Set the clipping region. Only pixels within this rectangle are drawn.

clip()

Reset clipping to full screen.

Graphics — pal / palt

pal(c0, c1, p?)

Remap color c0 to c1. p=0 (default) affects the draw palette; p=1 affects the display palette (applied at blit time).

pal()

Reset all palette mappings to identity.

palt(c, t)

Set transparency for color c. If t is true, pixels of color c are not drawn (transparent). Only color 0 is transparent by default.

palt()

Reset transparency table to defaults (color 0 transparent, all others opaque).

palt(0, false)  -- make black opaque
palt(3, true)   -- make dark green transparent

Sprites — spr

spr(n, x, y, w?, h?, flipX?, flipY?)

Draw sprite number n at screen position (x, y). w and h are the number of sprites wide/tall to draw (default 1×1). flipX/flipY mirror the sprite.

spr(1, x, y)               -- sprite 1, 8x8
spr(2, x, y, 2, 2)         -- 16x16 from sprites 2,3,18,19
spr(1, x, y, 1, 1, true)   -- flipped horizontally

Sprites — sget / sset

sget(x, y) → color

Get the color of pixel (x,y) in the sprite sheet. Coordinates are in sprite-sheet pixel space (0–127 × 0–127).

sset(x, y, c?)

Set pixel (x,y) in the sprite sheet to color c (or default color).

Map — map

map(tileX, tileY, sx, sy, tileW, tileH, layers?)

Draw a section of the tilemap. (tileX, tileY) is the top-left tile in map space; (sx, sy) is the screen destination; (tileW, tileH) is the number of tiles to draw. layers is a bitmask filtering sprite flags (e.g. 0x1 draws only tiles with flag 0 set).

map(0, 0, 0, 0, 32, 32)   -- draw 32x32 tiles at screen origin

Map — mget / mset

mget(x, y) → n

Return the sprite number stored at tilemap cell (x, y).

mset(x, y, val)

Set tilemap cell (x, y) to sprite number val.

Input — btn / btnp

btn(id) → boolean

Returns true while button id is held down. Button IDs:

IDButtonKeyboard
0Left← / A
1Right→ / D
2Up↑ / W
3Down↓ / S
4A / OZ
5B / XX
6StartEnter
btnp(id) → boolean

Returns true only on the first frame a button is pressed (not held). Useful for menus and single-press actions.

if btnp(4) then
  fire_bullet()
end

Sound — sfx

sfx(n, vol?)

Play sound effect number n (0–7). vol controls volume from 0.0 to 1.0 (default 1.0). Sound effects are defined in the cartridge SFX editor.

sfx(0)          -- play sfx 0 at full volume
sfx(2, 0.5)     -- play sfx 2 at half volume

Math — t / time

t() / time() → number

Return elapsed time in seconds since the cartridge started.

circfill(128 + cos(t()) * 50, 128, 4, 10)

Math — arithmetic functions

flr(x)

Floor (round down to nearest integer).

ceil(x)

Ceiling (round up).

sqrt(x)

Square root.

abs(x)

Absolute value.

min(a, b) / max(a, b)

Return the smaller/larger of two values.

mid(a, b, c)

Return the median (middle value) of three numbers. Useful for clamping: mid(0, x, 255).

sgn(x)

Return 1 if x ≥ 0, -1 if x < 0.

Math — trigonometry

sin(x) / cos(x)

Sine/cosine. Input is in turns (0–1 = full circle), not radians. sin(0.25) = 1, cos(0) = 1. Note: sin is negated compared to standard math (y increases downward).

local px = 128 + cos(t() * 0.5) * 40
local py = 128 + sin(t() * 0.5) * 40
atan2(dx, dy) → turns

Return angle in turns (0–1) from the origin to (dx, dy). Useful for aiming.

Math — rnd / srand

rnd(x) → number

Return a random number in [0, x). If x is a table, return a random element.

local n = flr(rnd(256))   -- random 0-255
local item = rnd(loot_table)
srand(seed)

Seed the random number generator for reproducible sequences.

Memory — peek / poke

peek(addr) → byte

Read one byte from memory address addr.

poke(addr, val)

Write one byte to memory address addr.

peek2/poke2 — 16-bit  |  peek4/poke4 — 32-bit

Multi-byte read/write variants. Values are little-endian.

Memory — memcpy / memset

memcpy(dst, src, len)

Copy len bytes from address src to address dst.

memset(dst, val, len)

Fill len bytes starting at dst with byte value val.

memset(0x4000, 0, 0x4000)  -- zero all user RAM

String functions

split(str, sep) → table

Split a string by separator sep and return a table of substrings.

sub(str, i, j) → string

Return a substring from index i to j (1-based, inclusive).

chr(n) → string

Return the single-character string for character code n.

ord(str, i?) → number

Return the character code at position i (default 1) in str.

tostr(x) / tonum(str)

Convert a number to string or string to number.

print(tostr(score), 2, 2, 7)
local n = tonum("42")  -- n == 42

Table functions

add(t, v)

Append value v to table t (equivalent to table.insert).

del(t, v)

Remove the first occurrence of value v from table t.

deli(t, i)

Remove element at index i from table t.

count(t) → number

Return the number of elements in table t (same as #t for sequences).

all(t) → iterator

Return an iterator for use in for … in all(t) loops.

foreach(t, fn)

Call fn(v) for each element v in table t.

foreach(bullets, update_bullet)
for b in all(bullets) do
  circfill(b.x, b.y, 2, 7)
end