Table of Contents
Overview
In Roblox, you write Lua code inside special objects that run on Roblox servers and player devices. Roblox-specific scripting means using Lua together with Roblox’s own objects, services, and event system. In this chapter you will see how Roblox runs your code, where to put scripts, and how Roblox objects can be created and controlled through Lua.
Scripts inside the Roblox engine
Roblox runs your Lua code by attaching it to objects in the game world. These code containers are instances, just like Parts or Models, but they hold scripts instead of geometry.
The most common script types you will use are Script and LocalScript. Each type runs in a different environment and can access different things. You will focus on the difference between them in the dedicated chapter about Scripts vs LocalScripts. For now, it is enough to understand that you place these script objects into the hierarchy of your game, and Roblox automatically decides when and how they run.
When a script is enabled and the game starts, Roblox loads its Lua code and begins to execute it from the top of the file. Any code that is not inside a function runs immediately when the script starts. Code inside functions waits until you call those functions or until an event triggers them. This is how you connect your logic to what happens in the game, such as a player joining, a part being touched, or a button being clicked.
Exploring Roblox services and instances with scripts
Roblox offers many built-in services. Services are special singleton objects that provide core features, for example players, lighting, or data storage. You access them from scripts through the global game object. The game object is the root of the entire place hierarchy. Everything in your game is a descendant of game.
To access a service you often use GetService. For example:
local Players = game:GetService("Players")
local Lighting = game:GetService("Lighting")
This method is the Roblox specific way to find services safely. It tells Roblox that you want a particular service, and Roblox returns the same object every time. This is useful when your script runs on different machines and at different times, since GetService works even if the service is not yet visible as a child of game in the Explorer.
You can also access objects that live directly under game using dot notation or methods like WaitForChild. For example, the 3D world is represented by the Workspace object:
local Workspace = game.Workspace
If you know there is a Part named Platform inside Workspace, you can get it:
local platform = Workspace.Platform
Sometimes an object is created after your script starts. In this case WaitForChild tells your script to pause until the object exists. For example:
local platform = Workspace:WaitForChild("Platform")
Roblox-specific scripting heavily relies on this style of navigation through the game hierarchy. You move from game to services, then to models, parts, and other child objects as needed.
Creating and modifying objects with Lua
In Roblox Studio you can create parts and models by hand. Scripts can do the same thing at runtime. This allows you to build objects on demand, rearrange them, or remove them while the game is running.
To create a new instance you use the Instance.new constructor. The first argument is a string with the Roblox class name, for example "Part" or "Model":
local part = Instance.new("Part")
This creates a Part in memory, but it is not yet visible in the world. To make it appear, you must set its Parent to a container, such as Workspace:
part.Parent = WorkspaceOnce you have a reference to an object, you can change its properties with standard Lua assignment. For example, you can change size, color, or position:
part.Size = Vector3.new(4, 1, 4)
part.Color = Color3.new(1, 0, 0) -- Red
part.Position = Vector3.new(0, 10, 0)
These property types such as Vector3 and Color3 are Roblox specific data types that Lua uses to represent 3D values, colors, and other engine concepts. Later chapters will go deeper into these systems. For now it is enough to recognize that they are created with constructor functions and assigned like any other value.
You can also control behavior related properties through scripts. For example, to prevent a part from being pushed around, you might set:
part.Anchored = trueOr to make it not collide with players:
part.CanCollide = false
By combining Instance.new, property changes, and parenting, you can generate platforms, obstacles, and effects on the fly.
Finding and organizing objects
Roblox-specific scripting often involves searching for instances by name or structure. You must be able to find the objects your code will control.
One common method is FindFirstChild. This returns a child object with the given name or nil if it does not exist. For example:
local model = Workspace:FindFirstChild("ObbyCourse")
if model then
model.PrimaryPart.Anchored = true
end
Since Lua treats nil as false in condition checks, this pattern lets you safely attempt to use an object only if it was actually found.
WaitForChild is similar, but instead of returning nil when the object is missing, it makes the script yield until the object appears or until a timeout passes. This is very helpful when scripts and object creation happen at slightly different times, which is very common in multiplayer games.
Roblox rule: If your script needs an object that might not exist yet, use :WaitForChild("Name") instead of only :FindFirstChild("Name") to avoid errors from nil values.
Good organization in the Explorer window makes this searching easier. For example, you might group related parts in a Model and then call Model:WaitForChild("PartName") in your script. This keeps your game structure clear and your scripts simpler.
Connecting scripts to the game loop
In Roblox, you usually do not write your own main loop. Instead, Roblox triggers your code when interesting events occur. This event driven model is a core part of Roblox-specific scripting and will be expanded in the dedicated events chapters.
Every time a script is loaded, Roblox executes the code at the top level. After that, the script typically spends time waiting for events or running inside loops that you write. For example, you might have a loop that runs every frame or every second to control something over time:
while true do
part.CFrame = part.CFrame * CFrame.Angles(0, math.rad(5), 0)
task.wait(0.1)
end
Use task.wait to pause without freezing the engine. This tells Roblox to resume your script later and allows the rest of the game to keep running.
Events connect your script logic to player input and world interactions. For example, a Part has a Touched event that fires whenever something collides with it. In Roblox-specific scripting you use a colon method called Connect to attach one of your functions to an event. The details are covered in the events-related chapters, but you will often see code that follows this general shape:
part.Touched:Connect(function(hit)
print("Touched by", hit.Name)
end)
Here Touched is a Roblox event object, and Connect is how you subscribe to it. The engine calls your function automatically when the event occurs.
Working with Roblox specific data and types
Roblox extends Lua with types that represent points, rotations, colors, regions, and other 3D values. These types are not part of plain Lua but are essential for scripting inside Roblox.
For positions and sizes you often see Vector3. A vector of three numbers can be created as:
local offset = Vector3.new(0, 5, 0)
For colors there is Color3:
local blue = Color3.fromRGB(0, 0, 255)
For full object transformations you work with CFrame, which combines position and rotation in one value. CFrames can be multiplied to apply rotations or offsets. An example:
part.CFrame = CFrame.new(0, 5, 0)These Roblox specific types behave like regular Lua values in assignments and function calls, but they have their own constructors and methods. Understanding them is important for precise control of movement and appearance, and later chapters will go deeper into how to use them effectively.
Roblox APIs and documentation
Every service, instance, and property in Roblox scripting has a defined API. This API describes what functions, events, and properties are available. For example, the Players service has functions to get the current list of players, and the Workspace has properties to control gravity.
When you write Roblox-specific scripts you are really combining normal Lua syntax with calls to this API. A typical line can look like plain Lua, but the meaning comes from the Roblox engine. For instance:
local playerCount = #Players:GetPlayers()
Here # is Lua’s length operator, which counts elements in a table, and GetPlayers is a Roblox API method that returns a table of all current players.
To grow as a Roblox scripter you should get comfortable looking up classes and members in the official Roblox documentation, then using them in your scripts. Every new mechanic you build, from leaderboards to tools, will involve finding the right service or class, and then calling its methods or connecting its events with Lua code.
Putting it together
Roblox-specific scripting is the combination of three ideas. You write Lua code that lives inside Script and LocalScript instances. That code reaches into the game hierarchy through game, services, and object references. Then it reacts to events, creates and modifies objects, and uses Roblox data types and APIs to control how the game behaves.
Once you are comfortable with this pattern, you can build systems that respond to players, move parts, award points, and manage full game rules, all by connecting your Lua logic to the Roblox engine.