Reference
Look something up
Every verb, every option and every refusal, with what each one is for.
This is the lookup half of the docs. If your question is how do I build a door, the recipes answer that faster, and every recipe links back here for the details.
The nine modules#
A script reaches the world through nine modules. You ask for the ones you need at the top of the file, and that line is the same in every script anyone ever writes.
local self = require("self")local world = require("world")local players = require("players")local events = require("events")local objects = require("objects")local vec = require("vec")local json = require("json")local http = require("http")local task = require("task")selfThe object your script is inside: react, move, look, carry, sit, sound.worldThe region around it: make things, weather, time, shared memory.playersWho is here, where they are, and what you can do to them.eventsMessages between scripts, like a switch telling a door to open.objectsFinding other objects and acting on them.vecPoints, directions and the maths on them.jsonA table turned into text a store can hold, and back.httpCalling a service outside the world.taskRoutines that pause: a step, a wait, the next step.Three of them are already there
self, objects and task work with no require at all, because a snippet you paste out of a page has to run. The other six do not: a script that calls world: without requiring it fails on the first line that touches it.
Writing the full list anyway is still the better habit. The require is what gives you autocomplete and red squiggles in VS Code.
Parts of the world#
The biggest parts of world have a page of their own.
world.terrainThe ground: its height, and brushes to reshape it.world.blocksCubic blocks on a one-metre grid, read and written one by one.world.buildPieces players raise themselves, and what holds them up.world.npcCharacters that walk on their own and find the way.JointsHinges, sliders, ropes and motors between objects.VehiclesCars, bikes, boats and planes people can drive.world.loadingThe screen people see on the way in.world.skyThe backdrop, the light, the haze and the hour.world.seaThe ocean's waves and colour, and the storm that rolls in.Tables and rules#
Long lists you look things up in.
self:set accepts.ParticlesEvery field of an emitter.SocketsThe places on a body an object can hang.PermissionsWhy a call answers "permission".Limits and refusalsEvery ceiling, and every refusal reason.Conventions#
Nine rules hold across the whole API. Read them once and most pages stop holding surprises.
Two answer shapes#
A reading hands you a value and never fails:
local here = self:position()local n = players:count()An action hands you true, or something useful, or nil plus a reason in plain words:
local ok, why = self:move_to(0, 5, 0)if not ok then print("could not move:", why)endNothing throws. A refused call is a value you can look at, so a script never dies halfway through because one line did not work out.
Three meanings of nil#
| Answer | What it means |
|---|---|
| a value | it worked |
nil | a real answer meaning nothing: no hit, no such item, nobody here |
nil, reason | the call could not be carried out |
world:raycast handing back plain nil is a clear line of sight, not a failure. The second return value is what tells the two apart.
Angles are degrees#
Everywhere, with no exceptions. Zero is the direction the object faces when you place it, and 90 is a quarter turn. The word for an orientation is rot on every verb that takes one.
ease names a curve, smooth counts seconds#
ease is always one of "linear", "in", "out" or "in_out". smooth is always a number of seconds. They are never swapped, and a name that is not on that list is refused rather than guessed at.
Points are interchangeable#
Anything that takes a point accepts a plain { x = , y = , z = } table or a vec, and every reading hands you a vec. You never have to repack a point to pass it somewhere else.
self:move_to(vec(0, 5, 0))self:move_to({ x = 0, y = 5, z = 0 })self:move_to(0, 5, 0)Coordinates follow the parent#
An object standing on its own reads and writes world coordinates. An object inside a group reads and writes coordinates local to that group, so moving the group moves everything in it and no script has to know.
Names, not hashes#
Scripts name what an object carries: a sound, a model, an item. No content hash ever appears in a script, which is what lets you swap a sound for a better one without touching a line of code.
The slash decides which shelf it comes from. A bare name lives inside the object and travels with it when the object is copied or sold. A world/ name lives in the world you are standing in.
self:play_sound("click") -- carried by this objectself:play_sound("world/bell") -- stored in this worldIds, not usernames#
player.id never changes. player.name is a display name the person can edit whenever they like. Save progress under id, always, or somebody renames themselves and loses everything.
Time is seconds#
Every duration in the API is a number of seconds, written as a decimal. 0.25 is a quarter of a second. Nothing anywhere is measured in ticks, frames or milliseconds.
See also#
- How scripts run covers slices, saving and budgets
- Recipes are the same verbs, already assembled
- Limits and refusals lists every ceiling in one table
Updated 17 October 2026