Appearance
Functions and Scope
Written: 2026-10-14
Learning objectives
- You define functions and call them.
- You tell parameters apart from arguments.
- You return values, including more than one.
- You explain scope, upvalues, and shadowing.
- You store functions in variables like any other value.
Prerequisites
- Read First Script. You can run a Script and read output.
- Read Variables and Values. You create variables with
local. - Read Operators and Logic. You compute and compare values.
- Read Conditionals and Loops. You branch with
if.
Define a function, then call it
A function is a named block of code that runs when you call it. You define it once and call it as often as you like. Defining uses the word function, a name, parentheses, a body, and end. Calling uses the name plus parentheses.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function greet()
print("Hello!")
end
greet()
greet()txt
Hello!
Hello!Walkthrough:
- Line 1 turns on strict mode.
- Line 2 defines a function named
greet. Nothing runs yet. Defining only teaches Luau the steps. - Line 3 is the body. It prints
"Hello!"each time the function runs. - Line 4 ends the definition.
- Line 5 calls
greetfor the first time, printingHello!. - Line 6 calls it again, printing
Hello!a second time.
Always define with local function. The local keeps the name inside your script, exactly like variables. Name functions in camelCase with a verb first, like greetPlayer or addBonus.
Parameters receive, arguments deliver
Parameters and arguments are two sides of one handoff. Parameters are the placeholder names listed in the definition. Arguments are the real values you pass at the call. Think of parameters as labeled cups, and arguments as what you pour into them.
Two rules protect you. Extra arguments are dropped silently. Missing arguments arrive as nil.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function greetPlayer(playerName)
print("Hi, " .. playerName)
end
greetPlayer("Maya")
greetPlayer("Rio")txt
Hi, Maya
Hi, RioWalkthrough:
- Line 1 turns on strict mode.
- Line 2 defines
greetPlayerwith one parameter,playerName. It holds no value yet. - Line 3 joins
"Hi, "with whateverplayerNameholds and prints it. - Line 4 ends the definition.
- Line 5 calls with the argument
"Maya". Luau pours"Maya"intoplayerNameand printsHi, Maya. - Line 6 calls with
"Rio". The parameter now holds"Rio"and printsHi, Rio.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function addBonus(score, bonus)
print(score + bonus)
end
addBonus(10, 5)
addBonus(10, 5, 99)txt
15
15Walkthrough:
- Line 1 turns on strict mode.
- Line 2 defines
addBonuswith two parameters,scoreandbonus. - Line 3 prints their sum.
- Line 4 ends the definition.
- Line 5 passes
10and5. The sum15prints. - Line 6 passes a third argument,
99. Luau drops it silently, so15prints again.
Send answers back with return
print shows a value to you. return hands a value back to the caller. The caller can store it, print it, or feed it into more math. return also ends the function at once. Nothing after it in the same block runs.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function double(amount)
return amount * 2
end
local doubled = double(7)
print(doubled)
print(double(3))txt
14
6Walkthrough:
- Line 1 turns on strict mode.
- Line 2 defines
doublewith parameteramount. - Line 3 returns
amount * 2to the caller and ends the function. - Line 4 ends the definition.
- Line 5 calls
double(7), stores the returned14indoubled. - Line 6 prints
14. - Line 7 calls
double(3)and prints the returned6directly.
A function can return more than one value. List them after return with commas, and catch them in the same order. This is handy when one computation produces a pair, like a sum and a difference.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function addAndSubtract(first, second)
return first + second, first - second
end
local total, gap = addAndSubtract(9, 4)
print(total)
print(gap)txt
13
5Walkthrough:
- Line 1 turns on strict mode.
- Line 2 defines
addAndSubtractwith two parameters. - Line 3 returns two values: the sum and the difference.
- Line 4 ends the definition.
- Line 5 calls with
9and4. Luau assigns13tototaland5togap. - Lines 6 and 7 print
13then5.
A function with no return gives back nil. That is normal for functions that only do something, like printing.
Scope decides what code can see
Scope is the region of code where a name exists. A local name lives in the block where you declared it, from that line down to the block's end. A block is the body of a function, an if, or a loop. Outer blocks cannot see names declared in inner blocks. Inner blocks can read names from outer blocks.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local title = "Coach"
local function announce()
local message = "Team huddle!"
print(title)
print(message)
end
announce()
print(title)txt
Coach
Team huddle!
CoachWalkthrough:
- Line 1 turns on strict mode.
- Line 2 declares
titleat the top level, so the whole script can see it. - Line 3 defines
announce. - Line 4 declares
messageinside the function. Only the function can see it. - Line 5 prints
title. The function reads outward and finds it. This printsCoachfirst. - Line 6 prints
message. This printsTeam huddle!second. - Line 7 ends the function.
- Line 8 calls
announce, producing the first two output lines. - Line 9 prints
titleagain, producing the finalCoach.
Order matters here. Coach prints first because line 5 runs before line 6. If you tried print(message) on line 9 instead, you would get nil, because message does not exist outside the function.
When a function reads an outer local, programmers call that outer variable an upvalue. The function captures it. This is how small helper functions share data without globals.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local cheer = "Go team!"
local function chant()
print(cheer)
end
chant()txt
Go team!Walkthrough:
- Line 1 turns on strict mode.
- Line 2 declares
cheeroutside the function. - Line 3 defines
chant. - Line 4 prints
cheer. Herecheeris an upvalue: an outer local captured by the function. - Line 5 ends the function.
- Line 6 calls
chant, printingGo team!.
Shadowing happens when an inner block declares its own local with the same name as an outer one. The inner name wins inside its block. The outer one is untouched. Shadowing is legal but confusing, so treat a shadowed name as a smell and rename one of them.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local points = 5
local function showPoints()
local points = 99
print(points)
end
showPoints()
print(points)txt
99
5Walkthrough:
- Line 1 turns on strict mode.
- Line 2 declares outer
pointsas5. - Line 3 defines
showPoints. - Line 4 declares a new inner
pointsset to99. This shadows the outer one. - Line 5 prints the inner
99. - Line 6 ends the function.
- Line 7 calls it, printing
99. - Line 8 prints the outer
points, still5. The inner assignment never touched it.
Functions are values
In Luau, a function is a value like a number or a string. You can store it in a variable and pass it around under a new name. The variable holds the function itself, not a copy of its result. Add parentheses to run it.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function cheerLoud()
print("Go!")
end
local myCheer = cheerLoud
myCheer()txt
Go!Walkthrough:
- Line 1 turns on strict mode.
- Line 2 defines
cheerLoud. - Line 3 prints
"Go!"when called. - Line 4 ends the definition.
- Line 5 stores the function itself in
myCheer. No parentheses means no call yet. - Line 6 calls the function through
myCheer, printingGo!.
This idea powers events and callbacks later in the course. A system can keep your function in a variable and call it when something happens. For now, remember: parentheses run, no parentheses refer.
Common mistakes
Calling before defining.
Run this to see it fail: put it in a Script in ServerScriptService and press Play.
luau
--!strict
greet()
local function greet()
print("Hello!")
endtxt
ServerScriptService.Script:2: attempt to call a nil valueOn line 2, greet does not exist yet, so calling it fails. Fix it by defining first, calling after. Run the fix the same way.
luau
--!strict
local function greet()
print("Hello!")
end
greet()txt
Hello!Confusing parameters with arguments.
Run this to see it fail: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function greetPlayer(playerName)
print("Hi, " .. playerName)
end
greetPlayer()txt
Red error on line 3: you cannot join nil with "..". No argument arrived, so playerName is nil.No argument arrived, so playerName is nil and .. cannot join nil. Fix it by passing an argument. Run the fix the same way.
luau
--!strict
local function greetPlayer(playerName)
print("Hi, " .. playerName)
end
greetPlayer("Maya")txt
Hi, MayaPrinting instead of returning.
Run this to see it fail: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function double(amount)
print(amount * 2)
end
local doubled = double(7)
print(doubled + 1)txt
14
ServerScriptService.Script:6: attempt to perform arithmetic (add) on nil and numberLine 6 prints 14 first, then the error hits: double returns nil, and nil + 1 is illegal. Fix it by returning the result. Run the fix the same way.
luau
--!strict
local function double(amount)
return amount * 2
end
local doubled = double(7)
print(doubled + 1)txt
15Reading an inner variable from outside.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local function announce()
local message = "Team huddle!"
end
announce()
print(message)txt
nilThis prints nil because message lives only inside the function. Fix it by returning the value and storing it outside. Run the fix the same way.
luau
--!strict
local function announce()
return "Team huddle!"
end
local message = announce()
print(message)txt
Team huddle!Exercises
Run every solution below in a Script in ServerScriptService and press Play. Try each exercise yourself before you open its solution.
- Define
sayReadythat prints"Ready!". Call it twice.
Solution 1
luau
--!strict
local function sayReady()
print("Ready!")
end
sayReady()
sayReady()txt
Ready!
Ready!- Define
welcomewith one parameterplayerName. It prints"Welcome, "joined with the name. Call it with"Rio".
Solution 2
luau
--!strict
local function welcome(playerName)
print("Welcome, " .. playerName)
end
welcome("Rio")txt
Welcome, Rio- Define
triplethat returns its argument times3. Store the result oftriple(4)in a variable and print it.
Solution 3
luau
--!strict
local function triple(amount)
return amount * 3
end
local tripled = triple(4)
print(tripled)txt
12- Define
splitBillthat takestotalandfriendsand returns two values: each share (total / friends) and the leftover (total % friends). Call it with100and4. Print both results.
Solution 4
luau
--!strict
local function splitBill(total, friends)
return total / friends, total % friends
end
local share, leftover = splitBill(100, 4)
print(share)
print(leftover)txt
25
0Line 2 returns both values at once. Line 5 catches them in order into share and leftover.
Summary
You defined functions with local function and called them with parentheses. You passed arguments into parameters, remembered that extras drop and missing ones arrive as nil, returned single and multiple values, read outer locals as upvalues, spotted shadowing, and stored functions in variables.
Next: Tables, Part 1.