Scripting overview

Studz games are scripted in Lua 5.4 with an API that grew out of Roblox's. If you have written Roblox scripts, most of what you know carries over, and the Roblox spellings still run (with a warning that names the Studz one). This page covers what you need before writing your first script: where scripts run, what the language is, and the rules every script lives by.

The language

Scripts are plain Lua 5.4, not Luau. These Luau conveniences do not exist:

  • compound assignment (x += 1; write x = x + 1)
  • continue
  • type annotations
  • string interpolation (use .. or string.format)

Some Luau library functions are provided anyway: math.clamp, math.sign, math.round, math.lerp, table.find, table.clone, table.clear, typeof, task.* and tick. See Globals and services.

How the API is named

The API has one official spelling for everything, in PascalCase.

Kind of nameExamplesNotes
Studz namesinst:FindChild, inst:Children(), signal:On, Players:List(), humanoid.Speed, game:Service("Players"), track.FinishedThe spellings the docs use. They are shorter, and read the same everywhere.
Studz additionspart.PlayerTouched, part.Clicked, Instance.Create, inst:GetChild, character.Animator, remote:ListenThey remove common Roblox traps. See Roblox compatibility.
Roblox spellingsFindFirstChild, :Connect, GetPlayers, WalkSpeed, game:GetServiceDeprecated. They still work, print one warning that names the Studz spelling, and will be removed in a later release.
Older spellingson_touch, world:spawn, part.pos, findFirstChildDeprecated too, with the same warning.

A few names are shared with Roblox on purpose and are not deprecated: Instance.new, Destroy, Clone, IsA, Touched, TweenService:Create, Raycast, CFrame, Vector3, Color3 and the other value types.

Where scripts run

There are three kinds of script. Add them from the Script ribbon or the Explorer in Polycarbonate.

ClassRuns onUse it for
ScriptThe game serverGame rules, physics, awards, saving data, anything that must be trusted.
LocalScriptEach player's computerThat player's interface, input, camera and sounds.
ModuleScriptWhoever calls require on itCode shared between scripts.

What the server shows to everyone

Everything a server Script does to the world is replicated, so every player sees it:

  • Parts it creates, moves, recolours, resizes, makes transparent or non-collidable, or destroys. This includes unanchored parts that physics moves.
  • The Lighting service (time of day, brightness).
  • GUI made with Instance.new("TextLabel"), "TextButton" or "Frame" in a server script. All players see it, and a click on a button runs its handler on the server.
  • Sounds started with Sound.play, or by setting a Sound object's Playing, which play on every client.

Positions a script assigns are authoritative. Setting part.Position on an unanchored part teleports its physics body there. The source of a server Script is never sent to players.

What fires on the server

Touched, TouchEnded and PlayerTouched fire on the server with the touching player's character. Clicking a part runs its ClickDetector.MouseClick or part.Clicked handler for that player, provided they are within 64 studs.

Testing

Use Test > Local Server in Polycarbonate to run the server and a player separately, the way the live game runs. LocalScripts and remotes only work there. The single-process Play (F5) playtest does not run them. See Client and server.

Errors that help

Studz turns many silent mistakes into errors that say what to fix.

Errors name the script

Scripts load under their own name, so an error in the Output window reads DoorOpener:14: attempt to .... Unnamed scripts appear as Script#<id>. A required module reports under the module's name.

Unknown members are errors

A member the object does not have raises an error with a suggestion. This is checked for each kind of object (parts, lights, value objects, sounds, GUI elements, humanoids):

part.Transparancy = 1
-- 'Transparancy' is not a valid property of Part (did you mean 'Transparency'?)
print(part.Health)
-- 'Health' is not a valid member of Part

Containers, services and players are open ended instead: workspace.Foo is nil when nothing is called Foo.

Wrong types are errors

part.Transparency = "high"
-- Part.Transparency expects a number, got string

Numbers and vectors must be finite. NaN and infinity are refused, so one bad calculation cannot corrupt a position.

Other checks

You writeWhat happens
Assign to a read-only member (ClassName, an event)Error.
game:Service("Playrs")Error: 'Playrs' is not a service (did you mean 'Players'?).
Instance.new("Prt") (one edit from a real class)Error with a suggestion.
Instance.new("Seat") (a class Studz does not have)Makes a plain Part and warns once.
part.Parent = partError (parenting loop).
A Roblox service Studz lacks (MarketplaceService, TeleportService, Teams, ...)Returns an inert object and warns once, so scripts that only declare it still run.
A Roblox-only property (Archivable, Locked, Massless, CanTouch, Reflectance, BrickColor, ...)Setting does nothing, reading gives nil, and a warning says so once.

Limits

Game servers share a machine, so everything a script can allocate has a ceiling. Hitting one raises an error in the script that did it. Nothing else is affected.

WhatLimit
Time per event, frame or step0.25 s (5 s while a script starts): script exceeded its time limit. Applies to every coroutine, including task.spawn, event handlers and coroutine.wrap.
Lua memory64 MB per game server and 48 MB per player's client. All scripts of one server or client share the budget.
Objects in a place20,000. Cloning refuses to go over it.
GUI elements alive at once500
Handlers on one signal500. Call :Off() on handlers you no longer need.
Output keptThe last 2,000 lines. A single line is cut at 2,048 characters.
Data stores600 requests per minute per game server, 64 waiting at once. See Saving data.
Remote arguments4 levels deep, 64 entries, about 1 KB. Clients may make 60 remote calls per second.

Sandbox

Scripts cannot reach the machine they run on. There is no io, no package, no dofile or loadfile, no debug, no binary chunks and no collectgarbage control. os offers only os.time, os.clock, os.date and os.difftime. HttpService cannot make web requests.

Where to go next

If you want to...Read
React to touches, clicks and timersEvents, signals and tasks
Create, find and change objects and partsInstances and parts
Work with players, health and outfitsPlayers and characters
Send messages between server and clientClient and server
Save scores and progressSaving data
Raycast, tween, light, play soundsWorld, tweens and effects
Look up a global, service or helperGlobals and services
Copy a working scriptExamples