Every complex Roblox script you have ever seen started with someone learning what a variable is. The scripting ecosystem in Roblox can seem intimidating at first glance, with thousands of community-made scripts ranging from simple teleportation commands to full combat systems with dozens of interconnected modules. But every one of those scripts is built from the same small set of foundational concepts. This guide breaks down those fundamentals piece by piece, using plain language and real examples, so you can go from zero scripting knowledge to writing and understanding functional Lua code for Roblox.
Roblox uses a language called Luau, which is a high-performance variant of Lua. If you have never programmed before, that is perfectly fine. Lua was designed from the ground up to be approachable, with a readable syntax that avoids the curly braces and semicolons that make other languages look like encrypted messages to newcomers. By the time you finish this article, you will understand the core building blocks well enough to read existing scripts, modify them for your needs, and start writing your own.
What Is Lua and Why Does Roblox Use It?
Lua is a lightweight, embeddable programming language created in Brazil in the early 1990s. Its name means "moon" in Portuguese. Game developers love Lua because it is fast, flexible, and easy to integrate into game engines. Roblox adopted Lua (and later created Luau, their optimized fork) because it offers the perfect balance between power and accessibility. You do not need to understand memory management, compilation, or complex type systems to write working Lua code.
Roblox's implementation extends standard Lua with game-specific features: access to the 3D world, player data, network communication between server and client, user interface creation, and thousands of built-in functions for interacting with game objects. The Roblox Creator Hub documentation is the authoritative reference for these extensions, and you will find yourself consulting it regularly as you grow more comfortable with scripting.
Variables: Storing Information
A variable is a named container that holds a value. Think of it as a labeled box where you put something you want to use later. In Lua, creating a variable is as simple as giving it a name and assigning it a value with the equals sign.
local playerName = "DeltaUser"
local health = 100
local isAlive = true
local speed = 16.5
The keyword local tells Lua that this variable exists only within the current scope (the block of code where it was created). You should almost always use local when declaring variables. Omitting it creates a global variable, which can cause conflicts when multiple scripts run simultaneously.
Data Types
Lua handles four primary data types that you will use constantly:
- Strings are text, wrapped in double quotes or single quotes:
"Hello"or'World'. You can join strings together with two dots:"Hello " .. "World"produces"Hello World". - Numbers cover both integers and decimals:
42,3.14,-7. Lua does not distinguish between integer and floating-point types internally. - Booleans are either
trueorfalse. They drive decision-making in your code. - Nil represents the absence of a value. A variable that has not been assigned anything is
nil, and you can set a variable tonilto effectively delete it.
Functions: Reusable Blocks of Code
A function is a named block of code that performs a specific task. Instead of writing the same instructions repeatedly, you write them once inside a function and then call that function whenever you need it.
local function greetPlayer(name)
print("Welcome to the game, " .. name .. "!")
end
greetPlayer("DeltaUser")
greetPlayer("RobloxFan")
The word inside the parentheses, name, is a parameter. It acts as a placeholder that gets replaced with an actual value when you call the function. Functions can accept multiple parameters separated by commas, and they can return values using the return keyword.
local function calculateDamage(baseDamage, multiplier)
return baseDamage * multiplier
end
local totalDamage = calculateDamage(25, 1.5)
print(totalDamage) -- Output: 37.5
The -- marks a comment. Everything after it on that line is ignored by the program. Comments are your notes to yourself and to anyone else who reads your code later.
Conditional Logic: Making Decisions
Programs need to make decisions based on conditions. Lua uses if, elseif, and else statements to branch code execution based on whether conditions are true or false.
local health = 35
if health <= 0 then
print("Player has been eliminated")
elseif health < 50 then
print("Player health is low")
else
print("Player health is fine")
end
The comparison operators you will use most frequently are: == (equals), ~= (not equals), < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to). You can combine conditions with and, or, and not.
local level = 10
local hasKey = true
if level >= 5 and hasKey then
print("Access granted to the dungeon")
end
Loops: Repeating Actions
Loops let you execute the same block of code multiple times without writing it out each time. Lua provides two main loop types for beginners.
For Loops
A for loop runs a set number of times. The syntax specifies a start value, an end value, and an optional step size.
-- Count from 1 to 5
for i = 1, 5 do
print("Count: " .. i)
end
-- Count from 10 to 0 by twos
for i = 10, 0, -2 do
print(i)
end
While Loops
A while loop continues running as long as its condition remains true. Be careful with while loops: if the condition never becomes false, the loop runs forever and locks up your script.
local countdown = 5
while countdown > 0 do
print(countdown)
countdown = countdown - 1
task.wait(1) -- Wait one second between counts
end
print("Go!")
The task.wait() function is a Roblox-specific call that pauses the script for a specified number of seconds. It is the recommended way to add delays in modern Roblox scripting, replacing the older wait() function.
Tables: Organizing Data
Tables are Lua's single compound data structure, and they are extraordinarily versatile. A table can function as an array (an ordered list), a dictionary (key-value pairs), or both simultaneously.
Arrays
local fruits = {"Apple", "Banana", "Cherry", "Date"}
print(fruits[1]) -- Output: Apple (Lua arrays start at 1, not 0)
print(#fruits) -- Output: 4 (# gives the length)
-- Loop through an array
for index, fruit in ipairs(fruits) do
print(index .. ": " .. fruit)
end
Dictionaries
local playerStats = {
name = "DeltaUser",
level = 25,
health = 100,
isVIP = true
}
print(playerStats.name) -- Output: DeltaUser
print(playerStats["level"]) -- Output: 25 (alternative syntax)
-- Loop through a dictionary
for key, value in pairs(playerStats) do
print(key .. " = " .. tostring(value))
end
The difference between ipairs and pairs matters. Use ipairs for arrays (it iterates in order, stopping at the first gap). Use pairs for dictionaries or when you need to iterate over all entries regardless of key type.
Roblox API Basics: Interacting with the Game World
Everything you see in a Roblox game is an object organized in a hierarchy called the DataModel. The top-level container is called game, and all services, players, workspace objects, and UI elements branch out from there.
Key Services
- Workspace contains all 3D objects visible in the game world: parts, models, terrain, and characters.
- Players manages all connected players and provides access to each player's character, backpack, and data.
- ReplicatedStorage holds objects and data accessible to both server and client scripts.
- Lighting controls ambient light, time of day, atmospheric effects, and post-processing filters.
-- Access the local player
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
-- Access workspace
local Workspace = game:GetService("Workspace")
-- Find a specific part in the workspace
local mysteryBlock = Workspace:FindFirstChild("MysteryBlock")
Your First Practical Script
Let us combine what you have learned into a script that actually does something visible in a Roblox game. This script changes the walk speed of your character, which is one of the most common and immediately satisfying scripts for beginners to run.
-- Speed modification script
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
-- Set walk speed (default is 16)
humanoid.WalkSpeed = 32
print("Walk speed set to " .. humanoid.WalkSpeed)
This script accesses the Players service, gets your local player, finds your character model, locates the Humanoid object inside it (which controls movement, health, and animations), and sets the WalkSpeed property to double its default value. The :WaitForChild() method is important because it pauses the script until the specified child object exists, handling cases where the character has not fully loaded yet.
Working with Game Objects
Roblox game objects have properties you can read and modify, methods you can call, and events you can listen to. Understanding how to work with these three aspects is the key to writing scripts that interact meaningfully with the game world.
Properties
-- Modify a part's properties
local part = Workspace:FindFirstChild("TestPart")
if part then
part.Color = Color3.fromRGB(255, 0, 0) -- Make it red
part.Size = Vector3.new(10, 5, 10) -- Resize it
part.Transparency = 0.5 -- Make it semi-transparent
part.Anchored = true -- Prevent it from falling
end
Methods
-- Clone an object and place it in the workspace
local original = Workspace:FindFirstChild("Coin")
if original then
local copy = original:Clone()
copy.Position = Vector3.new(0, 10, 0)
copy.Parent = Workspace
end
Events: Responding to What Happens
Events are signals that fire when something specific happens in the game. Connecting a function to an event is how you make your scripts reactive rather than linear. Instead of running once and stopping, an event-driven script sits and waits, executing its function every time the event fires.
-- Detect when the player's character touches a part
local part = Workspace:FindFirstChild("TrapPart")
if part then
part.Touched:Connect(function(hit)
local character = hit.Parent
local humanoid = character:FindFirstChild("Humanoid")
if humanoid then
humanoid.Health = 0
print(character.Name .. " touched the trap!")
end
end)
end
The :Connect() method links a function to an event. In this example, the anonymous function runs every time something touches the TrapPart. The hit parameter is the object that made contact, and we check whether its parent has a Humanoid to confirm it is a character rather than a random part bumping into it.
Common Events
- Touched / TouchEnded: Fires when a part makes or loses physical contact with another part.
- PlayerAdded / PlayerRemoving: Fires on the Players service when someone joins or leaves the game.
- CharacterAdded: Fires on a Player object when their character spawns or respawns.
- Changed: Fires on an Instance when any of its properties change.
- ChildAdded / ChildRemoved: Fires when a child object is added to or removed from a parent.
Practical Examples You Can Run Today
Here are several beginner-friendly scripts that demonstrate the concepts covered above in practical scenarios. Each one does something visible and useful, giving you immediate feedback on your learning.
Highlight All Players
local Players = game:GetService("Players")
for _, player in pairs(Players:GetPlayers()) do
if player.Character then
local highlight = Instance.new("Highlight")
highlight.FillColor = Color3.fromRGB(124, 106, 237)
highlight.OutlineColor = Color3.fromRGB(79, 143, 247)
highlight.FillTransparency = 0.5
highlight.Parent = player.Character
end
end
Auto-Jump When Touching Water
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
humanoid.StateChanged:Connect(function(oldState, newState)
if newState == Enum.HumanoidStateType.Swimming then
humanoid.Jump = true
end
end)
Print All Game Objects
local function listChildren(parent, depth)
depth = depth or 0
for _, child in pairs(parent:GetChildren()) do
print(string.rep(" ", depth) .. child.Name .. " [" .. child.ClassName .. "]")
if #child:GetChildren() > 0 and depth < 3 then
listChildren(child, depth + 1)
end
end
end
listChildren(game:GetService("Workspace"))
This recursive function walks through the workspace hierarchy and prints every object with its class name, indented to show the parent-child relationships. Limiting depth to 3 prevents the output from becoming overwhelming in complex games.
Where to Learn More
This guide covers the essential foundation, but Lua and the Roblox API have far more depth to explore. Here are the most valuable resources for continuing your learning journey:
- Roblox Creator Hub: The official documentation covers every service, class, method, property, and event available in the Roblox API. Bookmark this. You will use it constantly.
- Lua.org: The official Lua reference manual and "Programming in Lua" book (available free online for the first edition) provide deep understanding of the language itself.
- Roblox DevForum: An active community of developers who share tutorials, answer questions, and discuss scripting techniques. Search here when you encounter a specific problem.
- YouTube tutorials: Visual learners benefit from video walkthroughs. Look for channels that focus on Roblox scripting specifically, as general Lua tutorials will not cover the Roblox API.
Using Scripts with Delta Executor
Once you understand how scripts work, running them becomes much more powerful. Instead of blindly executing scripts you find online, you can read them, understand what they do, modify them for your specific needs, and even combine elements from different scripts into something new.
Delta Executor provides the execution environment where your scripts come to life inside Roblox games. The built-in script editor supports everything covered in this guide, with syntax highlighting that color-codes keywords, strings, numbers, and comments so your code is easier to read. The console output panel shows print() results and error messages, making it an essential debugging tool as you learn.
If you want to explore scripts that other people have built and learn from their code, our guide to the best Roblox scripts for Delta Executor includes scripts across a range of complexity levels. Reading and modifying existing scripts is one of the fastest ways to learn, because you start with working code and make incremental changes to understand what each part does. And for finding the best Roblox games for scripting practice, some games are particularly well-suited for beginners because of their simpler object hierarchies and more forgiving anti-cheat systems.
The best way to learn scripting is to write scripts. Start with the examples in this guide, modify them, break them on purpose, and figure out why they broke. Every error message is a lesson.
Common Beginner Mistakes to Avoid
As you start writing your own scripts, watch out for these frequent pitfalls that trip up nearly every beginner:
- Forgetting
local: Always declare variables withlocalunless you have a specific reason not to. Global variables leak across scripts and cause bugs that are extremely difficult to track down. - Using
=instead of==: A single equals sign assigns a value. A double equals sign compares two values. Writingif health = 0instead ofif health == 0is a syntax error. - Not checking for nil: If you try to access a property on a nil value, your script crashes. Always use
:FindFirstChild()and check the result before using it. - Infinite loops without yields: A
while true doloop without atask.wait()inside it freezes the game. Always include a yield in any loop that runs indefinitely. - String concatenation with non-strings: You cannot directly join a string with a number using
... Usetostring()to convert the number first, or Lua will throw an error.
Next Steps
You now have a working understanding of variables, functions, conditionals, loops, tables, game objects, and events. These are the building blocks that every Roblox script is constructed from, regardless of complexity. Your next move should be to practice. Open Delta Executor, join a game, and start experimenting with the code examples from this guide. Change values, add new conditions, combine scripts together.
As your confidence grows, explore more advanced topics like remote events for server-client communication, module scripts for code organization, tween services for smooth animations, and raycasting for line-of-sight detection. Each of these builds directly on the fundamentals you learned here.
Ready to Run Your First Script?
Download Delta Executor and start executing Lua scripts in Roblox games today. Free, fast, and beginner-friendly.
Download Delta Executor