§ How to · with Picoo
How to make a main menu and loading screen in Roblox
By Sametcan Tasgiran, Founder & Developer·Published ·Updated
Two UI bugs account for most of the time people lose on Roblox menus: the menu that disappears when you respawn, and the loading screen that never replaces Roblox's own.
Both are one property and one location — and once they are right, the rest is layout.
Persistent menu
ResetOnSpawn handled so the menu survives death and respawn.
Real loading screen
Roblox's default screen removed from ReplicatedFirst and replaced with your own.
Asset preloading
ContentProvider:PreloadAsync with genuine progress, not a fake timer.
Phone-safe scaling
UIScale and aspect-ratio constraints so a 6-inch screen is not a wall of text.
Camera framing
A scripted menu camera looking at the map instead of a spawned character.
Settings and credits
Sub-panels with a single navigation stack rather than a pile of visibility toggles.
Files Picoo ships for this prompt
2 files · 190 lines · ~30s · 1 credit
MenuController
Panel stack, camera framing, button wiring, play transition.
130 lines
LoadingScreen
ReplicatedFirst loading screen with real preload progress.
60 lines
Sample output: ReplicatedFirst.LoadingScreen
-- A custom loading screen ONLY works from ReplicatedFirst. That container is
-- replicated before anything else, which is the entire point: by the time a
-- LocalScript in StarterPlayerScripts runs, the default screen has already gone.
local ReplicatedFirst = game:GetService("ReplicatedFirst")
ReplicatedFirst:RemoveDefaultLoadingScreen()
local gui = script:WaitForChild("LoadingGui"):Clone()
gui.Parent = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")
-- Real progress beats a fake timer: PreloadAsync yields per asset, so the bar
-- tracks actual work and the screen closes when the game is genuinely ready.
local assets = collectAssets()
local done = 0
for _, asset in assets do
pcall(function() ContentProvider:PreloadAsync({ asset }) end)
done += 1
bar.Size = UDim2.fromScale(done / #assets, 1)
end
--------------------------------------------------------------------
-- And the menu itself, in StarterGui:
-- ScreenGui.ResetOnSpawn defaults to TRUE. Every death destroys and recreates
-- the GUI, so state resets and any connection you made points at a dead
-- instance. This is the "my menu disappeared" bug, every time.
menuGui.ResetOnSpawn = false
menuGui.IgnoreGuiInset = true -- draw under the top bar, not below itBuilding a main menu and loading screen in Roblox
A main menu is the first thing a player sees and the first thing that breaks in a way nobody explains properly.
Start with the disappearing menu. ScreenGui has a property called ResetOnSpawn, and it defaults to true. That means every time the player dies, the GUI is destroyed and re-cloned from StarterGui. Your carefully built panel stack is reset, and worse, every connection you made now points at an instance that no longer exists — so the buttons stop responding even though the menu looks fine. One property fixes it, and it is the single most common Roblox UI bug there is.
The loading screen has a similar shape: right code, wrong place. Roblox will let you remove its default loading screen, but only from ReplicatedFirst, which is delivered ahead of everything else. A LocalScript in StarterPlayerScripts runs after the default screen has already come and gone, so the call succeeds and appears to do nothing. Put the script and its GUI in ReplicatedFirst and it works immediately.
While you are there, make the progress real. PreloadAsync yields per asset, so stepping a bar through your asset list reflects genuine loading. A bar tweened over three seconds is a decoration that lies on slow connections — it completes while the game is still fetching, which is exactly when the player needed it to be honest.
The last piece is scaling, and it is worth caring about because most Roblox players are on phones. Scale-based sizing keeps layout proportional; Offset keeps small details from vanishing. Mixing them deliberately — Scale for containers, Offset for padding and strokes — plus a UIScale you can tune per device gives you a menu that reads on a 6-inch screen without looking sparse on a monitor.
See more on the Luau generator, the game builder, or browse the full blog.
Frequently asked
Why does my GUI disappear when I respawn?+
ScreenGui.ResetOnSpawn is true by default. On every respawn the GUI is destroyed and a fresh copy is cloned from StarterGui, so your state is lost and every connection you made is now attached to a destroyed instance. Set it to false for anything that should persist across deaths.
Where does a custom loading screen go?+
In ReplicatedFirst, as a LocalScript, calling ReplicatedFirst:RemoveDefaultLoadingScreen(). ReplicatedFirst is delivered before the rest of the game, which is why it is the only place that can replace the default screen. The same code in StarterPlayerScripts runs too late to remove anything.
Should I use Scale or Offset for sizing?+
Scale for layout, Offset for things that must not shrink — a 4-pixel border stays 4 pixels. Sizing everything in Offset produces a menu that fits your monitor and overflows a phone; sizing everything in Scale produces text too small to read on that same phone. UIScale plus a UIAspectRatioConstraint gives you one dial to tune per device class.
How do I show the map behind the menu?+
Set the camera to Scriptable and place its CFrame somewhere flattering before the character exists. Loading into a spawn point and covering the character with UI works, but the character is simulated, other players can see it standing there, and it drops into the world during the menu.
How do I know preloading is real?+
PreloadAsync yields until each asset resolves, so advancing your bar one asset at a time reflects actual work. A bar animated over three fixed seconds says nothing about readiness — and on a slow connection it finishes while the game is still loading, which is the worst of both.
Related Picoo prompts
lobby in Roblox Studio
Spawn, gather, count, launch. The part that breaks is almost always the launch: teleporting a group and keeping them together.
custom camera in Roblox
Cameras are client-only, and every reliable camera in Roblox comes down to three things: the right CameraType, the right update event, and framerate-independent smoothing.
Roblox shop system
5 files · 180 lines · 47 seconds · 1 credit. Robux + in-game currency, both server-validated.