Sections

1. Studio Interface Deep Dive Beginner

The Roblox Studio interface is your home for the entire development cycle. Mastering where everything lives and the shortcut for each panel will save you hundreds of hours.

Pro tip: Right-click the toolbar area and Customize to build your own tab with only the tools you use every day. Undock panels and drag them to a second monitor for dual-screen workflows.

Exercise:

Open Roblox Studio. Create a new Baseplate project. Use Explorer to rename "Baseplate" to "Ground". Open Properties and change its Color to dark green. Open the Toolbox, search "Created by Roblox" and insert a tree model. Run the game with F5.

2. Parts, Materials & Colors Beginner

Parts are the atomic building blocks of every Roblox experience. Understanding the full palette of shapes, material behaviors, and how to script them is foundational.

-- Scripting part properties
local part = Instance.new("Part")
part.Size = Vector3.new(10, 2, 5)
part.Position = Vector3.new(0, 10, 0)
part.Color = Color3.fromRGB(255, 100, 50)
part.Material = Enum.Material.Metal
part.Transparency = 0.2
part.Reflectance = 0.4
part.Anchored = true
part.Parent = workspace

Pro tip: Use Part.Shape = Enum.PartType.Block to force a part to stay a block after resizing. For dynamic shapes, set Part.Shape = Enum.PartType.Cylinder — but note that mesh-based cylinders cost more than six-sided approximations.

Exercise:

Create a tower of 5 colored blocks stacked vertically. Each block should be a different Material type. Use a script in ServerScriptService to set all properties at runtime. Change the top block to a Sphere with Neon material and Transparency 0.5.

3. Modeling & CSG Intermediate

Constructive Solid Geometry (CSG) lets you combine, subtract, and intersect parts to create complex shapes without external modeling tools.

-- Manual weld: attach handle to door
local door = script.Parent
local handle = door.Handle
local weld = Instance.new("Weld")
weld.Part0 = door
weld.Part1 = handle
weld.C1 = CFrame.new(1.5, 0.5, 0)  -- offset relative to Part0
weld.Parent = door

-- Model primary part movement
model.PrimaryPart = model.Door
model:SetPrimaryPartCFrame(CFrame.new(20, 0, 10))
local cf = model:GetPrimaryPartCFrame()

Pro tip: Always set Model.PrimaryPart before calling SetPrimaryPartCFrame. Without a PrimaryPart, the method errors. Weld-related lag can be debugged by checking JointCount on parts.

Exercise:

Build a table using CSG: create a flat top (Union of 4 corner-rounded blocks) and 4 cylindrical legs. Negate a hole in the center for a "glass panel" insert. Add a Weld to attach a lamp on top. Then write a script that uses SetPrimaryPartCFrame to move the entire table 10 studs to the right.

4. Terrain & Environment Intermediate

Roblox's native voxel terrain system lets you sculpt vast landscapes with performance-friendly generated geometry. Use it for outdoor environments, caves, islands, and procedural worlds.

-- Script a crater with terrain
local terrain = workspace.Terrain
local region = Region3.new(
    Vector3.new(-20, 0, -20),
    Vector3.new(20, 20, 20)
)
local material = Enum.Material.Grass
terrain:FillRegion(region, 4, material)

-- Remove a spherical area
local center = Vector3.new(0, 5, 0)
local radius = 8
terrain:FillBall(center, radius, Enum.Material.Air)

Pro tip: Terrain cells are only visible when the Terrain object's Decoration thickness is above 0. Use terrain.Decoration = true to enable grass/rocks on the surface. Disable it for top-down or performance-critical games.

Exercise:

Generate a 200x200 island with the "Island" preset. Use the Smooth brush to flatten a 50x50 area in the center. Paint a sand beach around the edge and place a water region. Then add a Part-based house anchored to the terrain surface.

5. Lighting & Atmosphere Advanced

Roblox's Lighting service defines the mood, visibility, and visual quality of your entire experience. Modern rendering features (Future/PBR) rival AAA mobile graphics when configured properly.

-- Scripted lighting change for night cycle
local lighting = game:GetService("Lighting")

for t = 0, 1, 0.01 do
    lighting.ClockTime = 12 + t * 12  -- noon to midnight
    lighting.Brightness = 2 * (1 - t)
    lighting.OutdoorAmbient = Color3.new(1 - t, 1 - t, 1 - t)
    task.wait(0.1)
end

-- Add a flickering point light
local light = Instance.new("PointLight")
light.Brightness = 3
light.Range = 15
light.Color = Color3.fromRGB(255, 200, 50)
light.Shadows = true
light.Parent = script.Parent

Pro tip: Set Lighting.GlobalShadows = true first, then tune shadow quality per light. Avoid more than 4 shadow-casting lights visible at once on mobile. Use Lighting.MinimumPartSize to skip shadow rendering on tiny parts.

Exercise:

Build a campfire scene. Place 5 logs with a PointLight in the center. Add a Fire (ParticleEmitter) from the Toolbox. Script a 60-second day/night cycle that smoothly transitions ClockTime, Ambient, and Brightness. Add a Sky with a starfield at night.

6. Physics & Constraints Intermediate

Roblox physics runs on a deterministic solver. Understanding anchored state, force-based movement, and constraints lets you build anything from vehicles to ragdolls.

-- Launch a part with velocity
local ball = script.Parent
ball.Anchored = false
ball.AssemblyLinearVelocity = Vector3.new(50, 30, 0)

-- HingeConstraint door hinge
local hinge = Instance.new("HingeConstraint")
hinge.Attachment0 = doorAttachment  -- on door
hinge.Attachment1 = frameAttachment  -- on frame
hinge.ActuatorType = Enum.ActuatorType.Servo
hinge.Servo.MaxTorque = 100
hinge.TargetAngle = 90
hinge.LimitsEnabled = true
hinge.UpperAngle = 120
hinge.LowerAngle = 0
hinge.Parent = door

-- Network ownership for player car
car.PrimaryPart:SetNetworkOwner(player)
car.PrimaryPart:SetNetworkOwnershipAuto()  -- let engine decide

Pro tip: Use AssemblyLinearVelocity instead of BodyVelocity for new code — it is faster, cleaner, and uses fewer instances. For angular constraints (wheels, doors), HingeConstraint is the only correct choice.

Exercise:

Build a simple car with 4 wheel parts, a chassis, and 4 HingeConstraints on each wheel. Set ActuatorType to "Motor" with a MaxTorque of 50 and TargetAngularVelocity of 20. Give network ownership to the player who clicks a "Drive" button. Add a SpringConstraint between chassis and each wheel for suspension.

7. Collisions & CanCollide Intermediate

Collision properties control what a part interacts with physically, how it detects overlap, and how efficiently the physics solver handles large scenes.

-- .Touched health pickup
local pickup = script.Parent
pickup.CanCollide = false
pickup.CanTouch = true

pickup.Touched:Connect(function(hit)
    local humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
    if humanoid and humanoid.Health > 0 then
        humanoid.Health = math.min(humanoid.MaxHealth, humanoid.Health + 20)
        pickup:Destroy()
    end
end)

-- CollisionGroup: bullets vs players
local physics = game:GetService("PhysicsService")
physics:CreateCollisionGroup("Bullets")
physics:CreateCollisionGroup("Players")
physics:CollisionGroupSetCollidable("Bullets", "Players", false)
physics:CollisionGroupSetCollidable("Bullets", "World", true)

-- Assign parts
physics:SetPartCollisionGroup(bulletPart, "Bullets")

Pro tip: For collectibles and triggers, always set CanCollide = false and CanTouch = true. This prevents physics simulation (cheap) while still detecting overlaps. Use CollisionGroups liberally in shooters — they reduce solver iterations by up to 60%.

Exercise:

Create 10 collectible coins with .Touched events that award points and destroy themselves. Set CanCollide = false on all coins. Create a CollisionGroup called "Coins" that does not collide with itself. Add a wall that is CanCollide = true but CanTouch = false (no .Touched trigger). Verify behavior in playtest.

8. Meshes & Imported Assets Advanced

When native parts aren't enough, import 3D models from Blender, Maya, or other DCC tools. Understanding format limitations, LODs, and workflow is essential for shipping polished experiences.

-- MeshPart creation via script
local mesh = Instance.new("MeshPart")
mesh.MeshId = "rbxassetid://1234567890"
mesh.TextureID = "rbxassetid://1234567891"
mesh.Size = Vector3.new(4, 4, 4)
mesh.CollisionFidelity = Enum.CollisionFidelity.Hull
mesh.Material = Enum.Material.Plastic
mesh.Anchored = true
mesh.Parent = workspace

-- Assign to LOD group
local lodGroup = Instance.new("LODGroup")
lodGroup.Parent = mesh

local lodHigh = Instance.new("LOD")
lodHigh.LODData = "rbxassetid://1234567890"
lodHigh.LODApplied = Enum.LODHighlightState.High
lodHigh.Parent = lodGroup

Pro tip: Always set CollisionFidelity manually. The default "Default" mode uses PreciseConvexDecomposition which is expensive at load time. "Box" or "Hull" are sufficient for 90% of props. For animated characters, use "Default" only for the root part.

Exercise:

Create a simple asset in Blender (or download a free .gltf model from a site like Poly Pizza). Import it into Roblox Studio. Set its CollisionFidelity to "Box". Create 3 LOD levels: full detail at 0–50 studs, medium at 50–100, and a simple box at 100+. Position the asset on your terrain.

9. Animations & Rigging Advanced

Animations bring characters to life. Roblox's Animation Editor is a keyframe-based tool for posing rigs. You can export animations and script them with the AnimationController/Humanoid API.

-- Load and play an animation
local humanoid = script.Parent:FindFirstChildWhichIsA("Humanoid")
local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://123456789"

local track = humanoid:LoadAnimation(anim)
track:Play(0.1, 1, Enum.AnimationPriority.Action)

-- Blend two animations
track1:Play(0.3)
track2:Play(0.3)
track2:AdjustWeight(0.5)  -- 50% blend

-- IKControl for foot placement
local ik = Instance.new("IKControl")
ik.ChainRoot = rig.UpperLeg
ik.EndEffector = rig.Foot
ik.Target = footTarget
ik.Parent = rig

Pro tip: For layered animations (run while waving), use AnimationPriority: low for idle, medium for movement, high for actions like waving, Core for forced full-body. Use track:AdjustWeight() to blend smoothly. IKControl is expensive — limit to 2 IKControls per character.

Exercise:

Insert a R15 rig into your place. Open Animation Editor and create a "wave" animation (right arm up and rotates). Export it. Write a LocalScript that plays the animation when the "E" key is pressed, blending it over 0.2 seconds on top of the default idle. Add an IKControl on the right foot that follows a small hovering part.

10. Audio & Sound Intermediate

Audio is half of the player experience. Roblox's Sound objects support 3D spatial audio, streaming, volume fades, and dynamic soundscapes through SoundService.

-- Create a 3D positional sound on a part
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://9126489253"
sound.Volume = 0.8
sound.Pitch = 1.0
sound.Looped = true
sound.EmitterSize = 10
sound.RollOffMode = Enum.RollOffMode.Inverse
sound.RollOffMinDistance = 20
sound.RollOffMaxDistance = 100
sound.Parent = script.Parent
sound:Play()

-- Crossfade between two tracks
local tweenService = game:GetService("TweenService")

local fadeOut = tweenService:Create(songA, TweenInfo.new(1), { Volume = 0 })
local fadeIn = tweenService:Create(songB, TweenInfo.new(1), { Volume = 0.5 })

fadeOut:Play()
fadeOut.Completed:Connect(function()
    songA:Stop()
    songB:Play()
    fadeIn:Play()
end)

Pro tip: For ambient outdoor sounds (wind, birds, water), create a single Sound with Looped = true and parent it to the player's Character or PlayerGui — this avoids positional discontinuity. Use a soundbus architecture: one GlobalMixer SoundGroup that all sounds go through, then mute/unmute with one Volume change.

Exercise:

Find and import 3 free-to-use audio assets: a footsteps sound, an ambient wind loop, and a UI click. Create a 3D footstep system: each time a player's character steps (use RunService.Heartbeat + check velocity), play the footstep sound from the character's root part with a random pitch between 0.9–1.1. Add a wind loop on the PlayerGui that fades in over 3 seconds when the player enters a defined region.