Roblox Studio tutorial · Intermediate

How to Make a Loading Screen in Roblox Studio (with a Progress Bar)

Learn how to make a loading screen in Roblox Studio that replaces the default Roblox screen, shows a real progress bar while assets load, and disappears when your game is ready.

  • LocalScript in ReplicatedFirst runs before anything else
  • Progress bar driven by ContentProvider:PreloadAsync
  • Removes the default screen with RemoveDefaultLoadingScreen

Step by step

  1. Open ReplicatedFirst

    In the Explorer, find the ReplicatedFirst service. It is sent to players before anything else, so scripts inside it run first. That is exactly what a loading screen needs.

  2. Insert a LocalScript

    Hover over ReplicatedFirst, click the plus button and insert a LocalScript. Rename it LoadingScreen. It must be a LocalScript, because the loading screen appears on each player's own device.

  3. Paste the loading screen code

    Delete the default print line and paste the script below. Read the four numbered parts in the comments: build the screen, remove the default one, preload in batches, then clean up.

  4. Make it visible while testing

    Studio loads your game almost instantly, so the screen only flashes. While testing, add task.wait(3) just before the preload loop, press Play and admire your screen. Remove the wait when you are done.

  5. Customise the design

    Change BackgroundColor3, the bar colour, the Font and the Loading text to match your game. Add an ImageLabel with your logo as a child of the label. Keep using fromScale sizes so it works on every screen.

  6. Test on a real device

    Publish the game, join it from the Roblox app on a phone or another computer, and watch the whole loading process. Check that the bar moves, the text is readable and the screen disappears.

The script

LocalScript — put inside ReplicatedFirst
-- LocalScript inside ReplicatedFirst
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local ContentProvider = game:GetService("ContentProvider")

local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")

-- 1. Build the loading screen: a full-screen label and a progress bar
local screen = Instance.new("ScreenGui")
screen.IgnoreGuiInset = true -- also cover the top bar area
screen.ResetOnSpawn = false  -- don't vanish when the character spawns
screen.DisplayOrder = 100    -- draw on top of your other GUIs
screen.Parent = playerGui

local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1) -- fill the whole screen
label.BackgroundColor3 = Color3.fromRGB(15, 20, 40)
label.Font = Enum.Font.FredokaOne
label.TextColor3 = Color3.new(1, 1, 1)
label.TextSize = 36
label.Text = "Loading..."
label.Parent = screen

local bar = Instance.new("Frame")
bar.Position = UDim2.fromScale(0.25, 0.56)
bar.Size = UDim2.fromScale(0, 0.03) -- starts empty, grows to half the screen
bar.BackgroundColor3 = Color3.fromRGB(0, 200, 120)
bar.Parent = label -- a child is always drawn on top of its parent

-- 2. Our screen is visible, so remove the default Roblox one
ReplicatedFirst:RemoveDefaultLoadingScreen()

-- 3. Wait for the game to load, then preload assets 50 at a time
if not game:IsLoaded() then
	game.Loaded:Wait()
end
local items = workspace:GetDescendants()
local batch = {}
for i, item in items do
	table.insert(batch, item)
	if #batch == 50 or i == #items then
		ContentProvider:PreloadAsync(batch) -- waits until these are loaded
		batch = {}
		local progress = i / #items
		bar.Size = UDim2.fromScale(0.5 * progress, 0.03)
		label.Text = "Loading... " .. math.floor(progress * 100) .. "%"
	end
end

-- 4. All done: short pause, then remove the loading screen
task.wait(0.5)
screen:Destroy()

Not working? Common mistakes

The default Roblox loading screen still appears.

The LocalScript must be directly in ReplicatedFirst. Scripts in other places start too late to replace the default screen.

My loading screen disappears as soon as the character spawns.

Keep screen.ResetOnSpawn = false. Without it, the ScreenGui is removed every time the character respawns.

There is a strip at the top that my screen does not cover.

Set IgnoreGuiInset = true on the ScreenGui so it also covers the area behind Roblox's top bar.

The screen never goes away.

Open the Output window. An error earlier in the script stops it before screen:Destroy(). Fix the line the error points to.

How to make a loading screen in Roblox Studio: why ReplicatedFirst

When a player joins, Roblox shows its own loading screen while your map, scripts and images download. A custom screen with your game's name and colours makes a much better first impression. The key to how to make a loading screen in Roblox Studio is where you put the script: ReplicatedFirst.

Everything in ReplicatedFirst is sent to the player before anything else in the game. A LocalScript there starts running while the rest of your world is still loading. That is why it can show your screen almost immediately.

The script builds a ScreenGui in code, so you do not need to design anything in StarterGui first. Three properties matter:

  • IgnoreGuiInset stretches it over the top bar area so there is no gap.
  • ResetOnSpawn = false stops it from disappearing when the character spawns.
  • DisplayOrder keeps it above your other GUIs.

Once your screen is visible, ReplicatedFirst:RemoveDefaultLoadingScreen() hides the Roblox one.

What ContentProvider:PreloadAsync actually does

First the script waits for game:IsLoaded(), or the game.Loaded event, which means the first version of the world has arrived. But images, sounds and meshes can still be downloading in the background. That is where ContentProvider:PreloadAsync helps.

You give PreloadAsync a list of instances. It looks for content links inside them, such as a Decal's texture or a Sound's audio, and waits until those assets are loaded. The script takes everything in Workspace, splits it into batches of 50 and preloads one batch at a time. After each batch it updates the bar and the percentage.

This makes the progress bar honest: it moves because real work is being done, not because of a fake timer. If an asset fails to load, PreloadAsync writes a message in the Output but keeps going, so the loading screen never gets stuck forever.

Heads-up: with Instance Streaming (on by default in new places), players only receive the parts near them, so Workspace may be smaller at this moment. That is fine, the script simply preloads what is there.

Design tips for a roblox custom loading screen

Knowing how to make a loading screen in Roblox Studio is only half the job. A loading screen is part of your game's brand, and a few tips make it look professional:

  • Use scale, not pixels. The script uses UDim2.fromScale, so the bar is always half the screen wide on a phone or a big monitor.
  • Add your logo. Put an ImageLabel inside the label with your uploaded logo image.
  • Show tips. Change label.Text between batches to show gameplay hints, for example how the double jump works.
  • Animate it. Spin the logo with TweenService, the same tool used in our door tutorial.
  • Keep it short. Do not make players wait with a long fake delay. People who wait too long leave before they play.

A good loading screen fits your theme. If you are building an obby, use the same colours as your first stage so the jump from menu to game feels smooth.

Parent note: client code and user experience

Learning how to make a loading screen in Roblox Studio is a step up from beginner scripts. Your child works with the client side (code running on the player's device), creates user interface objects entirely in code, uses loops and batches, and does simple maths to turn progress into a percentage.

It also introduces an idea from real app development: user experience. A loading screen exists for the player, so kids start asking questions like what the player sees first, how long they wait and whether it works on a phone. That kind of thinking matters in web development as much as in games.

If the percentage maths or the batch loop is confusing, that is normal at this stage. It is a good topic to go through together with a teacher.

Want your child to build full games like this?

Want your child to build full games like this? First 1-on-1 lesson free.

Polish like a custom loading screen is what separates a first project from a game people want to play. In live 1-on-1 Zoom lessons, Vlad Pomazanets teaches students aged 8–17 to build complete Roblox games, including menus, interfaces and saving, at a pace that fits each student.

The first 60-minute lesson is free. After that, 4 lessons cost CA$280 (CA$70 per lesson), with a money-back guarantee on unused lessons within 14 days. Lessons are taught in English, Ukrainian or Russian, and we will match a time in your time zone.

Book the free Roblox class or see the Roblox course.

Questions parents ask

Why does my custom loading screen only flash for a second in Studio?

In Studio the game is already on your computer, so it loads almost instantly. To see your design, add task.wait(3) just before the preload loop while testing, then remove it. On a real device joining a published game, loading takes longer and the screen stays visible.

Does the loading screen script have to be in ReplicatedFirst?

Yes. Only ReplicatedFirst is guaranteed to reach the player before the rest of the game, so it is the place for loading screens. A LocalScript in StarterPlayerScripts or StarterGui starts later, after the default Roblox screen has already been shown.

Can I preload only some assets instead of the whole Workspace?

Yes, and for big games it is often better. Build a table of the important instances, such as your lobby model, main GUI images and the background music Sound, and pass that to PreloadAsync. Everything else keeps loading in the background while players start.

Will the loading screen work on phones and tablets?

Yes. The script sizes everything with UDim2.fromScale, so the label fills any screen and the bar is always half the width. IgnoreGuiInset also covers the top bar area. Test with Studio's device emulator to check that your text is readable on small screens.

Is it OK to make players wait on the loading screen for a few seconds?

A short pause so players can read your logo is fine, but long fake waits annoy players and some will leave. The best loading screens disappear as soon as the game is ready and use the waiting time to show useful tips.

Want your child to build full games like this?

Try a free first 1-on-1 Roblox lesson with Vlad: 60 minutes on Zoom for ages 8–17, in English, Ukrainian or Russian. We'll match a time in your time zone.

Book a free lesson

Book a free lesson

Money-back guarantee Not a fit? Unused lessons are refunded within 14 days.
CA$70 per 60-min private lesson ≈ US$50. Large US schools charge US$60–75 for 50–60 minutes.
One mentor, live, 1-on-1 English, Ukrainian or Russian. Vulnerable Sector Check. Parents welcome to watch.
★ What parents say

5 / 5 · 1 review

★★★★★

“We were looking for coding classes for kids in Hamilton and a friend recommended Exclusive-IT. My 11-year-old started the Roblox course one-on-one and built his first real game in a few weeks. The mentor is patient, the lessons are in plain English, and my son actually looks forward to them. Highly recommend for any parent who wants their child to learn to code.”

Parent · Hamilton · Roblox