Roblox Scripting for Beginners: Getting Started With Luau

Quick answer: Open Roblox Studio, insert a Script into ServerScriptService, write a few lines of Luau such as print("Hello world"), and press Play. Then build up through variables, functions, events, and instances in that order.

Roblox scripting means writing code in Luau, the language built into every Roblox experience. To get started, you open Roblox Studio, insert a Script into ServerScriptService, type a few lines of Luau such as print("Hello world"), press Play, and watch the result appear in the Output window. Everything else builds on that one loop: write code, run the game, read the output, adjust.

If you have never written any code before, this guide assumes nothing. Each concept below is introduced from zero, in the order most beginners find easiest to absorb.

What is a script, and where does it go?

A script is a text file of instructions that Roblox runs while your game is running. In Roblox Studio you create one through the Explorer panel: hover over a service, click the plus icon, and choose Script or LocalScript.

Where you place the script decides where its code runs:

A common beginner mistake is dropping a LocalScript into Workspace or a Script into StarterPlayerScripts and wondering why nothing happens. When a script seems dead, check its location first.

Roblox also has ModuleScripts, which store reusable functions other scripts can import. You can ignore those until your projects grow; the guide to setmetatable and OOP covers them later.

Your first script: Hello world

Create a Script in ServerScriptService and replace its contents with:

print("Hello world")

Press the Play button at the top of Studio. The phrase appears in the Output window. If you do not see that window, enable it from the View tab — it will be your most important debugging tool for everything that follows. print() simply writes a message to the Output, and you will use it constantly to check what your code is actually doing.

Variables: giving names to values

A variable is a named container for a value. You create one with local, and you can change what it holds later:

local playerName = "Ana"
local coins = 10

coins = coins + 5
print(playerName) -- Ana
print(coins)      -- 15

Always start variables with local. It keeps the variable scoped to your script instead of leaking into the whole game, and it is faster too. Anything written after two dashes (--) is a comment: Roblox ignores it, but humans reading your code will thank you.

Types: the shapes your values take

Every value in Luau has a type. The ones you will use daily are strings (text in quotes), numbers, booleans (true/false), and instances (actual objects in your game, like a Part). Two quick checks come in handy:

local speed = 16
print(typeof(speed)) -- "number"

local door = workspace.Door
print(typeof(door)) -- "Instance"

typeof() tells you what kind of value you are holding, which is often the fastest way to understand an error message.

Making decisions with if/then

Code becomes interesting when it reacts differently depending on the situation:

local coins = 25

if coins >= 20 then
    print("You can afford the sword!")
else
    print("Not enough coins.")
end

The comparison operators are == (equal), ~= (not equal), and the familiar >, <, >=, <=. Note that == compares while a single = assigns — mixing those up is the classic beginner bug.

Repeating work with loops

Loops run code multiple times. A for loop repeats a known number of times; a while loop repeats as long as a condition stays true:

for i = 1, 5 do
    print("Wave " .. i)
end

while true do
    print("Checking for players...")
    task.wait(2) -- pause 2 seconds without freezing the game
end

Two rules keep loops safe. First, use task.wait() inside any long-running loop — a loop without a wait freezes the entire server. Second, prefer task.wait() over the old global wait(); it is the current, more accurate API. The article on task.wait vs wait explains why in depth.

Functions: packaging instructions

A function is a named block of code you can run whenever you need it:

local function greet(playerName)
    print("Welcome, " .. playerName .. "!")
end

greet("Ana")
greet("Ben")

Functions can receive inputs (parameters like playerName) and hand back results with return. Whenever you copy-paste the same lines twice, that is usually a sign a function wants to exist.

Events: reacting when something happens

Games are mostly about waiting for things to happen: a player touches a part, clicks a button, joins the game. Roblox calls these events, and you listen to one by connecting a function to it:

local part = script.Parent

part.Touched:Connect(function(hit)
    print(hit.Name .. " touched the part!")
end)

-- To stop listening later:
-- connection = part.Touched:Connect(...)
-- connection:Disconnect()

:Connect() tells Roblox "run this function every time the event fires." The Touched event passes along the instance that made contact, so you can check whether it belongs to a player.

Instances and properties: objects in your game

Everything in the Explorer window — Parts, Models, Scripts — is an instance. Every instance has properties you can change from code. Two tools cover most needs:

local part = script.Parent

-- Read and write properties of an existing object
part.BrickColor = BrickColor.new("Bright red")
part.Anchored = true

-- Create a brand-new object from scratch
local sparkles = Instance.new("ParticleEmitter")
sparkles.Parent = part

script.Parent deserves special attention: it means "the object this script lives inside." Placing a script directly under a part is the simplest way for that script to control the part.

Putting it together: a part that changes color when touched

Here is a complete, working example combining events, properties, and randomness. Place a Part in Workspace, insert a Script inside it, and paste:

local part = script.Parent
local colors = {
    BrickColor.new("Bright red"),
    BrickColor.new("Bright blue"),
    BrickColor.new("Bright green"),
}

part.Touched:Connect(function(hit)
    local character = hit.Parent
    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if humanoid then
        local randomIndex = math.random(1, #colors)
        part.BrickColor = colors[randomIndex]
    end
end)

Press Play and walk into the part: it changes color each time a player touches it. The script checks that whatever touched the part contains a Humanoid (the component every player character has), so falling debris or random parts will not trigger it. Small additions — a debounce variable, a sound effect, a point counter — turn this exact pattern into real gameplay.

Where to go from here

Once this example feels comfortable, you know the core loop of Roblox development: place a script, connect to an event, change properties, test in Studio. From there, natural next steps are learning what Luau actually is, finding the study routine that fits you in the best way to learn Roblox scripting, and connecting client and server with the RemoteEvents guide.

Learn Luau by doing

Reading gets you oriented, but repetition is what makes the syntax stick. On Luablox you can work through interactive Luau lessons, drill concepts in /theory, and solve hands-on challenges in /problems — right in your browser, no setup required.

Frequently asked questions

How do I write my first Roblox script?

Open Roblox Studio, hover over ServerScriptService in the Explorer, click the plus icon, and insert a Script. Type print("Hello world"), press Play, and check the Output window (View tab). That message confirms your script ran.

What is the difference between a Script and a LocalScript?

A Script runs on the Roblox server and belongs in ServerScriptService, so all players see its effects. A LocalScript runs on one player's device and belongs in StarterPlayerScripts, StarterCharacterScripts, or StarterGui.

Is Luau hard to learn for complete beginners?

No. Luau reads much like plain English and shares syntax with Python-style languages. Most beginners can write their first working script within an hour and build small interactive games within a few weeks of regular practice.

Why does my script do nothing in Roblox Studio?

Check three things first: the script type matches its location (Scripts in ServerScriptService, LocalScripts in StarterPlayerScripts), there are no red errors in the Output window, and any loops include task.wait() so they do not freeze the game.

Should I use task.wait() or wait() in my scripts?

Use task.wait(). It is the current, more accurate scheduling API; the old global wait() is deprecated and less precise. The same applies to task.spawn() and task.defer() versus the deprecated spawn() and delay().

Understand loop structures in Luau, including numeric, while, generic pairs, and ipairs iterators.

Related pages