Cheat sheet
Luau cheat sheet
What you need for your first month of Roblox scripting, on one page. Short, working code you can copy into Studio.
Variables
local keeps a variable to the block it's in. Use it every time.
local coins = 100 -- a numberlocal name = "Forja" -- a stringlocal ready = true -- true or falselocal nothing = nil -- no value at allcoins += 50 -- same as coins = coins + 50print(`{name} has {coins} coins`)Strings
Backticks fill in values. .. joins strings.
local text = "Hello"print(text .. " world") -- Hello worldprint(#text) -- 5, its lengthprint(text:upper()) -- HELLOprint(text:sub(1, 2)) -- Heprint(text:find("ll")) -- 3 4, where it starts and endsprint(tostring(5)) -- "5"print(tonumber("5")) -- 5Lists
A table with numbered slots. They start at 1, not 0.
local fruits = {"apple", "pear"}table.insert(fruits, "plum")print(fruits[1]) -- appleprint(#fruits) -- 3, how manyprint(table.find(fruits, "plum")) -- 3, where it istable.remove(fruits, 1) -- takes out applefor index, fruit in fruits do print(index, fruit)endDictionaries
A table with names instead of numbers. Setting a value to nil removes it.
local stats = { coins = 100, level = 3 }stats.coins += 10stats["level"] = 4stats.level = nil -- removes levelfor key, value in stats do print(key, value)endIf and else
~= means not equal. Only false and nil count as false, so 0 and "" are true.
local coins = 150if coins >= 100 and coins < 500 then print("Getting there")elseif coins >= 500 then print("Rich")else print("Keep going")endlocal label = if coins > 100 then "rich" else "poor"print(label)Loops
break leaves a loop. continue skips to its next turn. A while true loop needs a wait in it, or the game freezes.
for i = 1, 3 do print(i) -- 1, 2, 3endfor i = 10, 0, -2 do print(i) -- 10, 8, 6, 4, 2, 0endwhile true do task.wait(1) -- every second print("tick")endFunctions
A function can return several values. The : number parts are optional types, which help the editor catch mistakes.
local function add(a: number, b: number): number return a + bendprint(add(2, 3)) -- 5local function stats() return 100, 3endlocal coins, level = stats()Finding things
Get services with GetService. A LocalScript should use WaitForChild, because things may not have loaded yet.
local Players = game:GetService("Players")local door = workspace:WaitForChild("Door") -- waits for itlocal button = door:FindFirstChild("Button") -- nil if it isn't thereif button then print(button.Name)endfor _, child in door:GetChildren() do print(child.Name)endMaking parts
Set Parent last: it's what puts the part in the world.
local part = Instance.new("Part")part.Size = Vector3.new(4, 1, 4)part.Position = Vector3.new(0, 10, 0)part.Anchored = truepart.Color = Color3.fromRGB(255, 0, 0)part.Material = Enum.Material.Neonpart.Parent = workspacetask.wait(5)part:Destroy()Events
Connect runs your function each time something happens.
local Players = game:GetService("Players")Players.PlayerAdded:Connect(function(player) print(player.Name, "joined") player.CharacterAdded:Connect(function(character) local humanoid = character:WaitForChild("Humanoid") humanoid.WalkSpeed = 24 end)end)script.Parent.Touched:Connect(function(hit) local player = Players:GetPlayerFromCharacter(hit.Parent) if player then print(player.Name, "touched me") endend)Waiting
Use the task library. The old wait() and spawn() are out of date.
task.wait(2) -- wait 2 secondstask.spawn(function() -- run this alongside the rest print("right now")end)task.delay(3, function() -- run this in 3 seconds print("later")end)print(os.time()) -- seconds since 1970Where scripts go
A Script runs on the server, usually in ServerScriptService. A LocalScript runs on each player's device, usually in StarterPlayerScripts or StarterGui. A ModuleScript runs when something requires it, usually from ReplicatedStorage.
local RunService = game:GetService("RunService")if RunService:IsServer() then print("I'm on the server")else print("I'm on a player's device")endClient and server
A RemoteEvent in ReplicatedStorage lets them talk. Never trust what a client sends: check it on the server, because cheaters can send anything.
local ReplicatedStorage = game:GetService("ReplicatedStorage")local buyItem = ReplicatedStorage:WaitForChild("BuyItem")buyItem.OnServerEvent:Connect(function(player, itemName) print(player.Name, "wants", itemName)end)local ReplicatedStorage = game:GetService("ReplicatedStorage")local buyItem = ReplicatedStorage:WaitForChild("BuyItem")buyItem:FireServer("Sword")Attributes and tags
Attributes store a value on any object. Tags mark many objects, so one script can handle them all.
local CollectionService = game:GetService("CollectionService")local part = workspace:WaitForChild("Lava")part:SetAttribute("Damage", 25)print(part:GetAttribute("Damage"))for _, lava in CollectionService:GetTagged("Lava") do print(lava.Name)endSmooth movement
TweenService slides any property to a new value. Here's a door opening over a second.
local TweenService = game:GetService("TweenService")local door = workspace:WaitForChild("Door")local info = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)local goal = { Position = door.Position + Vector3.new(0, 10, 0) }local tween = TweenService:Create(door, info, goal)tween:Play()tween.Completed:Wait()Raycasts
Fires a line and tells you what it hit. It's how most guns and line-of-sight checks work.
local origin = Vector3.new(0, 10, 0)local direction = Vector3.new(0, -100, 0)local params = RaycastParams.new()params.FilterType = Enum.RaycastFilterType.Excludeparams.FilterDescendantsInstances = { workspace:WaitForChild("Ignore") }local result = workspace:Raycast(origin, direction, params)if result then print(result.Instance.Name, result.Position)endModules
Code to share between scripts. A ModuleScript returns one value, usually a table.
local Config = {}Config.MaxCoins = 1000function Config.double(n: number): number return n * 2endreturn Configlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Config = require(ReplicatedStorage:WaitForChild("Config"))print(Config.double(Config.MaxCoins))Things that can fail
Saving data and buying things go over the internet, so they can fail. pcall stops that from breaking your script.
local DataStoreService = game:GetService("DataStoreService")local store = DataStoreService:GetDataStore("Coins")local ok, result = pcall(function() return store:GetAsync("player_1")end)if ok then print("Saved coins:", result)else warn("Couldn't load:", result)endQuestions
What's the difference between Lua and Luau?
Luau is Roblox's language, built from Lua 5.1. It adds optional types, strings that fill in values, continue, += and a faster runtime. Most Lua you know still works.
What's the difference between a Script and a LocalScript?
A Script runs on the server, and everyone shares what it does. A LocalScript runs on one player's device, so it's for that player's screen, input and camera.
Where do I put my scripts?
Server code usually goes in ServerScriptService. Player code usually goes in StarterPlayerScripts, or StarterGui for screens. Shared code goes in ModuleScripts in ReplicatedStorage.
Why does my LocalScript say something is nil?
It probably ran before that thing loaded. Use WaitForChild instead of a plain dot on anything in the world.
How do I learn Roblox scripting fastest?
Change working scripts, one small thing at a time. Copy a free script, press F5, change a number, press F5 again.
Free scripts
Scripts to copy and paste
Whole working scripts, each with where it goes and how to change it.
Get a scriptFree tool
Roblox script generator
Say what you need in plain words, and get a working script.
Write a scriptCheat sheet
Roblox Studio shortcuts
Every keyboard shortcut, for Windows and Mac, on one page.
See the keys