📚 All Courses
9 courses · beginner → expert
COURSE 01
Lua Fundamentals
Variables, data types, conditionals, loops, and functions. Start from absolute zero — no experience needed.
COURSE 02
Roblox Studio Setup
Navigate Studio like a pro. Explorer, Properties, Output window, and your first Part script.
COURSE 03
Your First Game Script
Make things happen! Click buttons, open doors, change colors, and give players tools.
COURSE 04
Game Systems & Logic
Leaderboards, round systems, teams, kill bricks, checkpoints, and win conditions.
COURSE 05
NPCs, AI & Pathfinding
Build enemies that chase players, guards that patrol, and bosses with health bars.
COURSE 06
DataStore & Saving Data
Save coins, levels, and inventory so player progress persists between sessions.
COURSE 07
Remote Events & Client-Server
Master RemoteEvents, RemoteFunctions, and the client/server model for real multiplayer.
COURSE 08
Anti-Cheat & Security
Validate on the server, detect exploiters, rate-limit remotes, and protect your game.
COURSE 09
Build a Full Roblox Game
Combine everything into a complete Obby with checkpoints, saving, a shop, leaderboard, and full polish to publish.
📋 Full Curriculum
Check off each lesson as you complete it
💻 Sample Lesson: Kill Brick
Lesson 21 · Intermediate · ~40 min
Script Editor — KillBrick.lua
📖 WHAT YOU'LL LEARN
A Kill Brick destroys a player's character on touch. This lesson covers the Touched event, finding a Humanoid, and using :TakeDamage().
- ✅ Detecting when a Part is touched
- ✅ Finding the Humanoid in a character
- ✅ Instant kill vs. damage
- ✅ The debounce pattern to stop spam
- ✅ Team-only kill brick challenge
⚙ HOW IT WORKS
The Touched event fires every frame something touches the Part. We find the Humanoid and zero its Health. A debounce table stops it firing 60+ times per second.
⚠ COMMON MISTAKES
Forgetting debounce causes lag and duplicate kills. Not checking for Humanoid throws errors when non-character parts touch the brick.
⌨ CODE — Script inside the Part
-- KillBrick.lua
-- Place as Script inside the Part
local part = script.Parent
local debounce = {}
part.Touched:Connect(function(hit)
local humanoid =
hit.Parent:FindFirstChild(
“Humanoid”
)
if humanoid
and not debounce[hit.Parent]
then
debounce[hit.Parent] = true
humanoid.Health = 0
task.wait(1)
debounce[hit.Parent] = nil
end
end)
```
🔥 BONUS: DAMAGE BRICK
-- Deal 25 damage instead of killing
```
– Replace: humanoid.Health = 0
– With:
humanoid:TakeDamage(25)
```
📌 CHALLENGE: TEAM-ONLY KILL
local player =
```
game.Players:GetPlayerFromCharacter(
hit.Parent
)
if player
and player.Team.Name
== “Red Team”
then
humanoid.Health = 0
end
📄 Lua & Roblox Cheatsheet
Keep this open while you code
🔢 Variables
local x = 10 — number
local s = "hi" — string
local b = true — boolean
local n = nil — nothing
🔁 Loops
for i=1,10 do
while true do
repeat ... until cond
for k,v in pairs(t) do
⚡ Functions
local function f(a)
return value
f(arg) — call it
pcall(f) — safe call
📦 Tables
local t = {1,2,3}
table.insert(t, val)
table.remove(t, i)
#t — length
🌍 Services
game:GetService("Players")
game:GetService("TweenService")
game:GetService("DataStoreService")
game:GetService("RunService")
👤 Players
game.Players.LocalPlayer
player.Character
player.CharacterAdded
Players.PlayerAdded
💥 Humanoid
humanoid.Health
humanoid.MaxHealth
humanoid:TakeDamage(n)
humanoid.WalkSpeed
🎯 Events
part.Touched:Connect(fn)
btn.MouseButton1Click
RunService.Heartbeat
event:Disconnect()
🌐 Remotes
remote:FireServer(data)
remote:FireClient(plr,data)
remote.OnServerEvent:Connect
remote.OnClientEvent:Connect
🗄 DataStore
ds:GetAsync(key)
ds:SetAsync(key, val)
ds:UpdateAsync(key, fn)
Always wrap in pcall!
⏱ Timing
task.wait(n) — pause
task.spawn(fn) — new thread
task.delay(n, fn)
os.time() — unix time
🛠 Debugging
print("debug")
warn("warning")
error("msg")
tostring() tonumber()
💡 Pro Scripting Tips
Avoid the most common beginner mistakes
⚠️
ALWAYS USE task.wait() NOT wait()
The old wait() is deprecated and inconsistent. Use task.wait(n) — it's faster, accurate, and supported by Roblox's task scheduler.
🔒
NEVER TRUST THE CLIENT
Data from RemoteEvents can be faked by exploiters. Always validate on the server. Never give rewards or deal damage based purely on client data.
📦
USE MODULESCRIPTS FOR EVERYTHING
Don't copy-paste the same code into 10 scripts. Put shared logic in a ModuleScript and require() it wherever needed. This is how real devs work.
🐛
ALWAYS WRAP DATASTORES IN pcall()
DataStores can fail. If you don't wrap :GetAsync() and :SetAsync() in pcall(), one network hiccup silently crashes your entire server script.
🔍
USE THE OUTPUT WINDOW CONSTANTLY
Use print() everywhere while debugging. Red = error, yellow = warning. Read them — they tell you exactly what went wrong and on what line.
🧱
DEBOUNCE EVERY TOUCHED EVENT
Touched fires dozens of times per second. Without a debounce table or boolean flag your code runs way too many times, causing bugs, lag, and duplicate rewards.
🗂
ORGANIZE YOUR EXPLORER FROM DAY ONE
Use Folders in ServerScriptService, ReplicatedStorage, and StarterGui. Name everything clearly. A messy Explorer will cripple you in large projects.
🚀
PLAYTEST IN MULTIPLAYER MODE
Use the dropdown next to Play and pick "2 Players" server test. Many bugs only appear in multiplayer due to replication. Test early and often.