Appearance
objects
Acting on other objects — the ones you did not spawn and are not standing in.
luau
local objects = require("objects")objects also works without the require, as a ready-made global.
Finding one
me
objects:me() → object, or nil
This script's own object, as an ordinary reference. This is how a script reads or changes its own tags.
nil on a personal HUD and on a worn item: neither is an object in the world.
get
objects:get(id) → object, or nil
One object by its id. Only persistent objects — things world:spawn made are not in here.
tagged
objects:tagged(tag) → list, or nil, reason
Every object carrying that tag.
luau
local lamps = objects:tagged("streetlight")
if lamps then
for _, lamp in ipairs(lamps) do
lamp:set({ light = true })
end
endRefused with a reason when more than 256 objects match — a query that broad is almost always a mistake, and answering it would stall the region.
named
objects:named(name) → list, or nil, reason
Exact display-name lookup, ignoring capitals. Names are not unique, so this always answers a list.
Prefer tags to names. A name is what a person reads and may rename on a whim; a tag is what a script means. Tagging every lamp "streetlight" survives somebody renaming one to "Lamp (broken)".
What you get back
Each result carries four readings:
| Field | Meaning |
|---|---|
id | its permanent id in this region |
name | its display name, or nil once it has been removed |
owner | the id of whoever owns it, or nil if unstamped |
tags | its tags, sorted — a snapshot, not a live view |
luau
obj:exists() -- is it still in the world?
obj:has_tag("door") -- ignoring capitalsMoving it
| Verb | Meaning |
|---|---|
obj:move_to(x, y, z) | put it there |
obj:rotate_to(x, y, z) | face that way, degrees |
obj:scale_to(n) | resize. One number is uniform, three are per axis |
obj:move_by(x, y, z) | move by a step, from wherever it actually is |
obj:rotate_by(x, y, z) | turn by an angle, about its own axes |
All answer true, or nil plus a reason. Coordinates are local to the parent when the object is inside a group and world coordinates when it stands alone — the same rule as everywhere else.
Requires that you own the object, or have been granted edit rights over it.
You cannot read another object's position, and this is deliberate. Doing so would mean mirroring the whole region's motion into every script on every tick, which is a cost every script would pay for a question few of them ask.
Say "a bit more" instead. move_by and rotate_by are added to the object's live transform at the moment they are applied — which is also the only version that survives somebody else moving the object in between.
Changing it
set
obj:set(changes) → true, or nil, reason
The same property table self:set takes.
luau
lamp:set({ light = true, emissive = 2, color = "#ffe9b0" })tween
obj:tween(opts) → true, or nil, reason
A smooth change, run by the region. Same options as self:tween.
No handle comes back — use self:after(seconds, ...) when something must happen on arrival.
add_tag / remove_tag
obj:add_tag(tag) → true, or nil, reasonobj:remove_tag(tag) → true, or nil, reason
One tag at a time, applied atomically. Up to 16 tags per object. Removing a tag that is not there is harmless.
Tags are how objects talk about each other without reading each other. A script cannot ask another object for its state — but it can ask whether it carries a tag, and the object's own script controls its tags. That makes a tag the public half of an object: "door.open" says something true that anyone may check.
damage / heal
obj:damage(amount, { by = uuid }) → true, or nil, reasonobj:heal(amount) → true, or nil, reason
Hurts or mends a damageable object — one with a max_health.
Unlike self:damage, these answer true, not the remaining health. No script holds a mirror of another object's life. For the outcome, listen for world.destroyed.
remove
obj:remove() → true, or nil, reason
Takes it out of the world, cascading through its group.
It goes to the world's trash, where it can be restored with its scripts and its memory intact. It is not an erasure.
A worked example
Every lamp in the world comes on at dusk and goes off at dawn, driven by one object:
luau
--!strict
local self = require("self")
local objects = require("objects")
local world = require("world")
local DAY = 600 -- a full cycle, in seconds
local lit = false
local function set_all(on: boolean)
local lamps = objects:tagged("streetlight")
if not lamps then
print("too many lamps to address at once")
return
end
for _, lamp in ipairs(lamps) do
lamp:set({
light = on,
emissive = on and 2.5 or 0,
})
end
end
self:on_timer(10, function()
local phase = world:clock() % DAY
local should = phase > DAY * 0.5
if should ~= lit then
lit = should
set_all(lit)
end
end)Two things worth stealing:
- It only acts when the answer changes, not every ten seconds. Writing the same properties over and over would spend the region's budget for nothing.
- The lamps are found by tag, so adding a lamp to the world is a build action, not a code change.
See also
- self — your own object
- events — telling other scripts, rather than reaching into them
- Object properties — every key
setaccepts
