Lua
Lightweight. Fast. Embeddable.
Lua is a small, fast scripting language designed to be embedded in other programs. It's the language behind Roblox scripting, and is also used in game engines, config systems, and embedded environments.
Core concepts
Variables and types
Lua uses dynamic typing — variables have no declared type, the value has a type. Use local to scope a variable to the current block. Without local, variables are global, which causes bugs in larger scripts.
-- Local variables (always prefer these) local name = "Sibah" local age = 17 local isActive = true local nothing = nil -- Type checking print(type(name)) -- string print(type(age)) -- number print(type(isActive)) -- boolean print(type(nothing)) -- nil -- String concatenation local greeting = "Hello, " .. name print(greeting) -- Hello, Sibah
Tables
Tables are Lua's only data structure. They work as arrays, dictionaries, objects, and more. An array-style table uses numeric indices starting at 1 (not 0 like most languages). Dictionary-style tables use string keys.
-- Array-style table
local fruits = {"apple", "banana", "cherry"}
print(fruits[1]) -- "apple" (index starts at 1!)
print(#fruits) -- 3 (length)
-- Add item
table.insert(fruits, "mango")
-- Dictionary-style table
local player = {
name = "Sibah",
level = 10,
alive = true
}
print(player.name) -- "Sibah"
print(player["level"]) -- 10
-- Mixed table
local data = {
"first",
key = "value",
nested = { x = 1, y = 2 }
}Functions
Functions in Lua are first-class values — you can store them in variables, pass them to other functions, and return them. Lua functions can return multiple values at once, which is used heavily in Roblox APIs.
-- Basic function
local function add(a, b)
return a + b
end
-- Assigned to variable
local multiply = function(a, b)
return a * b
end
-- Multiple return values
local function getCoords()
return 10, 20, 5 -- x, y, z
end
local x, y, z = getCoords()
print(x, y, z) -- 10 20 5
-- Variadic functions
local function sum(...)
local total = 0
for _, v in ipairs({...}) do
total = total + v
end
return total
end
print(sum(1, 2, 3, 4)) -- 10Conditions
Lua uses if/elseif/else/end — note the end keyword that closes blocks. Lua treats nil and false as falsy; everything else (including 0 and empty string) is truthy. This is different from JavaScript.
local score = 85
if score >= 90 then
print("A grade")
elseif score >= 80 then
print("B grade")
elseif score >= 70 then
print("C grade")
else
print("Below C")
end
-- Logical operators
local isAdmin = true
local isOnline = false
if isAdmin and isOnline then
print("Active admin")
elseif isAdmin or isOnline then
print("Partially active")
else
print("Inactive")
endLoops
Lua has four loop types. Numeric for iterates a range. Generic for with ipairs iterates arrays. Generic for with pairs iterates all table keys. while and repeat/until loop on conditions.
-- Numeric for loop
for i = 1, 5 do
print(i) -- 1, 2, 3, 4, 5
end
-- With step
for i = 10, 1, -2 do
print(i) -- 10, 8, 6, 4, 2
end
-- ipairs: array iteration (1-indexed, stops at nil)
local fruits = {"apple", "banana", "cherry"}
for index, value in ipairs(fruits) do
print(index, value)
end
-- pairs: all table keys
local player = { name = "Sibah", level = 10 }
for key, value in pairs(player) do
print(key, value)
end
-- while
local count = 0
while count < 5 do
count = count + 1
endModules
Lua modules are just tables returned from a file. require() loads a module and caches it. In Roblox, ModuleScript is the equivalent — a script that returns a table of functions for other scripts to use.
-- mymodule.lua
local M = {}
function M.greet(name)
return "Hello, " .. name
end
function M.add(a, b)
return a + b
end
return M
-- main.lua
local mymodule = require("mymodule")
print(mymodule.greet("Sibah")) -- Hello, Sibah
print(mymodule.add(3, 4)) -- 7Roblox basics
In Roblox, Lua scripts interact with the game engine through services. game:GetService() gets an engine service. Instance.new() creates a new object. The hierarchy is: game > Workspace/Players/etc > parts, scripts, etc.
-- Get services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- When a player joins
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined!")
-- Wait for character to load
local character = player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
print(player.Name .. " died")
end)
end)
-- Create a part
local part = Instance.new("Part")
part.Size = Vector3.new(4, 1, 4)
part.Position = Vector3.new(0, 5, 0)
part.BrickColor = BrickColor.new("Bright red")
part.Parent = workspace