Skip to content

Limits and refusals

Every ceiling in one place, and what every refusal message means.

Nothing here crashes a script. A verb that cannot do what you asked answers nil and a reason in plain words, and your script carries on.

luau
local ok, why = self:move_to(0, 5, 0)
if not ok then
    print("could not move: " .. why)
end

Ceilings

Per slice

A slice is one event firing, or the script being loaded.

LimitValue
Instruction units50,000
World effects8
Events sent (emit + send)16
print lines32
Length of one print line512 bytes

A world effect is anything that changes the world: a move, a rotation, a tween, a spawn, a property write, a sound, a terrain stroke, a block edit, damage. Reads are free — raycast, players:list, world:clock, self:get and the whole of vec cost nothing.

Per script

LimitValue
Memory4 MB
Keys in one self:set32
Animation layers8
Locomotion overrides16

Per object

LimitValue
Scripts8
Tags16
Store keys256
Store key length256 bytes
Store value size64 KB
Store total1 MB

A personal HUD is tighter, because its memory lives on the central server for everyone, forever:

LimitValue
Store keys64
Store value size8 KB
Store total32 KB
All your HUDs together1 MB

Per player, per experience

What one person keeps in a world — players.store. It lives on the central server and follows them between machines:

LimitValue
Store keys128
Store key length256 bytes
Store value size64 KB
Store total256 KB
All your experiences together16 MB

Per region

The region's shared memory — world.store — is one drawer for the whole world, not one per object:

LimitValue
Store keys4096
Store key length256 bytes
Store value size64 KB
Store total8 MB

The loading screen

What world.loading accepts. Past any of these the call is refused with a reason, not silently trimmed — a screen that quietly dropped four of your twelve tips is a bug you would hunt in the wrong place.

LimitValue
Headline80 characters
Subtitle160 characters
Tips8
One tip160 characters
Tip dwell2–30 seconds
Background / logo, longest side4096 px
LimitValue
Active scripts768
Script-made objects alive at once256
Named actions32
Objects one tagged query may return256
Pieces in a copied group64

http

What one world may send outside. The request count is generous because requests are cheap; the ceiling that actually binds is in bytes, because bandwidth is what costs.

LimitValue
Requests a second10, banking up to 60
Bytes a second512 KB, banking up to 16 MB
Bytes a day5 GB
Requests in the air, per script8
Requests in the air, per world64
Requests waiting for a slot64
Body sent64 KB
Answer accepted256 KB
Time before it gives up10 s (5 s to connect)
Headers16, up to 1 KB each and 4 KB in total
URL2 KB

The per-second budgets bank quiet time. A world that has been idle for a minute can fire all 60 at once — which is what makes forty players arriving together work — and then settles back to 10 a second.

A destination that fails 5 times in a row is left alone for 30 seconds, and calls to it answer http cooling immediately. A 404 is not a failure.

HUD stages

A stage is a live 3D render every frame — the most expensive thing a HUD can hold, by a wide margin.

LimitValue
Stages in one HUD4
Pieces on one stage64
Parts in a set on the shelf256

Over either of the first two, the HUD is refused with a reason. A menu backdrop is dozens of pieces, not a city.

A set counts as the one piece you wrote, however many parts it brings — the ceiling on those is the shelf's own, applied when you publish it.

Ranges

ThingRange
Coordinates±100 km
Scale0.01 – 10,000
Velocity and pushup to 100 m/s
Tween length0.05 – 600 s
Region radius0.5 – 96 m
Raycast reachup to 512 m
Spawn lifedefault 30 s, max 300 s (0 = while the region runs)
Rate of fire and cycle0.05 – 5 s
Light radius0 – 96 m
Sound volume0 – 4
Sound pitch0.25 – 4
Windup to 40 m/s
Terrain brush radius0.5 – 64 m
Terrain brush strength0 – 8 m
Animation speed−8 to 8
Event payload3 levels deep, 32 entries, 512-byte strings
Channel name1 – 64 characters

What stops a script

Two very different outcomes.

The event is abandoned, the script lives

An ordinary mistake — indexing something that is nil, calling a method that does not exist, arithmetic on text. The error is written to your console and the next event runs normally.

The script is killed

MessageMeaning
script budget exceededone slice used more than 50,000 instruction units
script memory limit exceededthe script went over 4 MB

It does not run again until you save it. Both mean the same thing in practice: a loop without an exit. Use a timer instead — a slice may not take long, but you may have as many slices as you like.


Refusal reasons

Anywhere

ReasonWhat happened
permissionthis world, or this player, has not granted what the verb needs. See Permissions
too many commandsmore than 8 world effects in one event
too many movesthe same, from a movement verb
read-only keythat property is not writable by scripts — see the list

Moving and physics

ReasonWhat happened
not dynamicpush or set_velocity on an object that is not a physics body. Set dynamic = true first
unknown partthat part was deleted, or never existed
look_at: target is not a directionthe target is directly above, directly below, or the object's own position

Memory

ReasonWhat happened
store fullthe key ceiling is reached (256 per object, 4096 for the world). Existing keys still read, overwrite and delete
value too largeover 64 KB (8 KB on a HUD)

Carrying

ReasonWhat happened
permissionthat player has not interacted with this object
socketno attachment point by that name — see Sockets
childhold the root of a group, not one of its pieces
heldsomebody else has it
fulltheir hands are full
not helddrop on something nobody was carrying

Making things

ReasonWhat happened
too many spawned objectsthe region already has 256 script-made objects alive
a spawn is made of one thingyou named more than one of shape, model, copy

Damage

ReasonWhat happened
this object has no max_health — it cannot be damagedset max_health first. This is how a world says what is breakable

Terrain and blocks

ReasonWhat happened
invalid brushradius or strength outside the allowed range
invalid positionoutside the world
box too biga fill covering too many cells — refused whole, and said now rather than half-done later

Modules

ReasonWhat happened
unknown module '…'built-ins are self, events, players, vec, world, objects. For your own module, attach a sibling script with that name to the same object and re-save this one
cyclic require of module '…'two of your modules require each other

Reading a refusal

Three shapes, and they mean different things:

luau
local hit = world:raycast(...)
AnswerMeaning
a valueit worked
nila real answer meaning "nothing" — no hit, no such item, nobody here
nil, reasonthe call could not be carried out

world:raycast returning plain nil is a clear line of sight, not an error. self.contents:get returning plain nil means there is no such item. Absent is an answer.

See also

Hungrit scripting documentation.