Docs

Loading screen for your script

Wide in-game loading bars while KeyForge authenticates and delivers your script. Pick a preset when creating a script, paste the Luau, set your loader URL.

Quick start

  1. Create a script in the dashboard and pick a loading screen preset (or none).
  2. Copy the matching Luau from the presets below.
  3. Paste your loader URL from the dashboard into LOADER_URL.
  4. Run as a LocalScript — the bar shows while KeyForge loads your script.

Keys stay in the loader URL from your dashboard — this is not a key-entry box.

Copy usage snippet:

4 wide loading bars (mobile-ready)

Centered horizontal strips with title, subtitle, and spinner. Each scales wider on desktop and nearly full-width on phone. Customize LOADING_TITLE, LOADING_SUBTITLE, and accent colors in the file.

loading-frost-bar.lua
local GuiService=game:GetService("GuiService")
local TweenService=game:GetService("TweenService")
local RunService=game:GetService("RunService")
local UserInputService=game:GetService("UserInputService")
local _kf_t=task or(type(wait)=="function"and{delay=function(s,f)if delay then delay(s,f)elseif f then f()end end}or{delay=function(_,f)if f then f()end end})
local function isMobile()return UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled end
local function corner(i,r)local c=Instance.new("UICorner")c.CornerRadius=UDim.new(0,r)c.Parent=i end
local function stroke(i,c,t,a)local s=Instance.new("UIStroke")s.Color=c s.Thickness=t or 1 s.Transparency=a or 0 s.Parent=i end
-- Apple-like motion: soft spring settle (Quint) + gentle fade, no bounce.
local function smoothTween(i,p,t,e,d)return TweenService:Create(i,TweenInfo.new(t or 0.55,e or Enum.EasingStyle.Quint,d or Enum.EasingDirection.Out),p)end
local function fadeIn(i,t)
	if i:IsA("GuiObject")then
		local a=i.BackgroundTransparency
		i.BackgroundTransparency=1
		smoothTween(i,{BackgroundTransparency=a},t or 0.5):Play()
	end
	if i:IsA("TextLabel")or i:IsA("TextButton")then
		local a=i.TextTransparency
		i.TextTransparency=1
		smoothTween(i,{TextTransparency=a},(t or 0.5)+0.05):Play()
	end
end
local function layoutBar(bar)
	local top=GuiService:GetGuiInset().Y
	local pos=type(LOADING_POSITION)=="string" and LOADING_POSITION or "bottom-left"
	if pos=="top" then
		bar.AnchorPoint=Vector2.new(0.5,0)
		bar.Position=UDim2.new(0.5,0,0,10+top)
		bar.Size=isMobile() and UDim2.new(0.94,0,0,66) or UDim2.fromOffset(280,52)
	elseif pos=="bottom-center" then
		bar.AnchorPoint=Vector2.new(0.5,1)
		bar.Position=UDim2.new(0.5,0,1,-(10+top))
		bar.Size=isMobile() and UDim2.new(0.94,0,0,66) or UDim2.fromOffset(300,52)
	elseif pos=="bottom-right" then
		bar.AnchorPoint=Vector2.new(1,1)
		bar.Position=UDim2.new(1,-14,1,-14)
		bar.Size=isMobile() and UDim2.new(0.94,0,0,66) or UDim2.fromOffset(260,50)
	elseif isMobile() then
		bar.AnchorPoint=Vector2.new(0.5,1)
		bar.Position=UDim2.new(0.5,0,1,-(10+top))
		bar.Size=UDim2.new(0.94,0,0,66)
	else
		bar.AnchorPoint=Vector2.new(0,1)
		bar.Position=UDim2.new(0,14,1,-14)
		bar.Size=UDim2.fromOffset(260,50)
	end
end
local function animateBarIn(bar)
	local target=bar.Position
	bar.Position=target+UDim2.fromOffset(0,18)
	bar.BackgroundTransparency=1
	bar.Size=bar.Size-UDim2.fromOffset(0,4)
	local finalSize=bar.Size+UDim2.fromOffset(0,4)
	smoothTween(bar,{Position=target,BackgroundTransparency=0.04,Size=finalSize},0.62,Enum.EasingStyle.Quint):Play()
	for _,ch in ipairs(bar:GetChildren())do
		if ch:IsA("TextLabel")then
			ch.TextTransparency=1
			_kf_t.delay(0.08,function()smoothTween(ch,{TextTransparency=0},0.48,Enum.EasingStyle.Quint):Play()end)
		end
	end
end
local function addDotSpinner(parent,accent)
	local wrap=Instance.new("Frame")
	wrap.Size=UDim2.fromOffset(28,10)
	wrap.AnchorPoint=Vector2.new(0,0.5)
	wrap.Position=UDim2.new(0,12,0.5,0)
	wrap.BackgroundTransparency=1
	wrap.Parent=parent
	local dots={}
	for i=1,3 do
		local d=Instance.new("Frame")
		d.Size=UDim2.fromOffset(5,5)
		d.Position=UDim2.fromOffset((i-1)*9,2.5)
		d.BackgroundColor3=accent
		d.BorderSizePixel=0
		d.BackgroundTransparency=0.82
		d.Parent=wrap
		corner(d,99)
		dots[i]=d
	end
	local conn
	local t0=os.clock()
	conn=RunService.Heartbeat:Connect(function()
		if not wrap.Parent then if conn then conn:Disconnect()end return end
		-- Soft breathing pulse (Apple activity indicator feel)
		local p=(os.clock()-t0)*2.2
		for i,d in ipairs(dots)do
			local wave=0.5+0.5*math.sin(p-i*0.95)
			d.BackgroundTransparency=0.18+0.62*(1-wave)
			local s=3.6+1.4*wave
			d.Size=UDim2.fromOffset(s,s)
			d.Position=UDim2.fromOffset((i-1)*9+(5-s)*0.5,2.5+(5-s)*0.5)
		end
	end)
	return conn
end
local function dismissOverlay(gui,bar,spinConn)
	pcall(function()
		if spinConn then spinConn:Disconnect()end
		if bar and bar.Parent then
			local target=bar.Position
			for _,ch in ipairs(bar:GetChildren())do
				if ch:IsA("TextLabel")then smoothTween(ch,{TextTransparency=1},0.28,Enum.EasingStyle.Quad):Play()end
			end
			smoothTween(bar,{Position=target+UDim2.fromOffset(0,10),BackgroundTransparency=1},0.38,Enum.EasingStyle.Quint):Play()
		end
		_kf_t.delay(0.4,function()pcall(function()if gui and gui.Parent then gui:Destroy()end end)end)
	end)
end
local function waitForLocalPlayer()
	local Players=game:GetService("Players")
	local plr=Players.LocalPlayer
	if plr then return plr end
	local t0=os.clock()
	while not plr and (os.clock()-t0)<10 do
		pcall(function() RunService.Heartbeat:Wait() end)
		plr=Players.LocalPlayer
	end
	if not plr then
		local ok,res=pcall(function() return Players.PlayerAdded:Wait() end)
		if ok then plr=res end
	end
	return plr
end
-- Mirrors the key GUI: PlayerGui gets swept by game anti-exploit scripts, so
-- prefer the executor's hidden container and fall back down the chain.
local function kfGuiHosts(plr)
	local hosts={}
	if type(gethui)=="function" then
		local ok,h=pcall(gethui)
		if ok and typeof(h)=="Instance" then hosts[#hosts+1]=h end
	end
	local okCore,cg=pcall(function() return game:GetService("CoreGui") end)
	if okCore and typeof(cg)=="Instance" then hosts[#hosts+1]=cg end
	if plr then
		local okPg,pg=pcall(function() return plr:FindFirstChildOfClass("PlayerGui") or plr:WaitForChild("PlayerGui",5) end)
		if okPg and typeof(pg)=="Instance" then hosts[#hosts+1]=pg end
	end
	return hosts
end
local function kfMountGui(gui,plr)
	if syn and type(syn.protect_gui)=="function" then pcall(syn.protect_gui,gui) end
	if type(protectgui)=="function" then pcall(protectgui,gui) end
	for _,h in ipairs(kfGuiHosts(plr)) do
		local ok=pcall(function() gui.Parent=h end)
		if ok and gui.Parent==h then return true end
	end
	return false
end
local function emptyLoadingGui()
	return { show=function()end, dismiss=function()end }
end
local LOADING_TITLE="Loading script"
local LOADING_SUBTITLE="Please be patient"
local LOADING_POSITION="bottom-left"
local LOADING_BAR_BG=Color3.fromRGB(10,14,24)
local LOADING_ACCENT=Color3.fromRGB(100,170,255)
local LOADING_TEXT=Color3.fromRGB(245,248,255)
local LOADING_SUBTEXT=Color3.fromRGB(130,145,175)
local LOADING_DIM=false
local LOADING_SCREEN_BG=Color3.fromRGB(10,14,24)
local function buildLoadingGui()
	local plr=waitForLocalPlayer()
	if not plr then return emptyLoadingGui() end
	local gui=Instance.new("ScreenGui")
	gui.Name="KeyForge_Loading"
	gui.ResetOnSpawn=false
	gui.IgnoreGuiInset=true
	gui.DisplayOrder=200
	gui.ZIndexBehavior=Enum.ZIndexBehavior.Sibling
	if not kfMountGui(gui,plr) then return emptyLoadingGui() end
	local bar=Instance.new("Frame")
	bar.BackgroundColor3=LOADING_BAR_BG
	bar.BorderSizePixel=0
	bar.Parent=gui
	layoutBar(bar)
	corner(bar,12)
	stroke(bar,Color3.fromRGB(90,150,255),1,0.4)
	local accent=LOADING_ACCENT
	local spinConn=addDotSpinner(bar,accent)
	local title=Instance.new("TextLabel")
	title.BackgroundTransparency=1
	title.Position=UDim2.fromOffset(38,8)
	title.Size=UDim2.new(1,-48,0,20)
	title.Font=Enum.Font.GothamMedium
	title.Text=LOADING_TITLE
	title.TextColor3=Color3.fromRGB(245,248,255)
	title.TextSize=isMobile()and 16 or 14
	title.TextXAlignment=Enum.TextXAlignment.Left
	title.TextTruncate=Enum.TextTruncate.AtEnd
	title.Parent=bar
	local sub=Instance.new("TextLabel")
	sub.Name="Subtitle"
	sub.BackgroundTransparency=1
	sub.Position=UDim2.fromOffset(38,26)
	sub.Size=UDim2.new(1,-48,0,16)
	sub.Font=Enum.Font.Gotham
	sub.Text=LOADING_SUBTITLE
	sub.TextColor3=Color3.fromRGB(130,145,175)
	sub.TextSize=isMobile()and 12 or 11
	sub.TextXAlignment=Enum.TextXAlignment.Left
	sub.TextTruncate=Enum.TextTruncate.AtEnd
	sub.Parent=bar
	local track=Instance.new("Frame")
	track.Size=UDim2.new(1,-20,0,2)
	track.Position=UDim2.new(0,10,1,-6)
	track.BackgroundColor3=Color3.fromRGB(30,40,60)
	track.BorderSizePixel=0
	track.BackgroundTransparency=0.2
	track.Parent=bar
	corner(track,99)
	local fill=Instance.new("Frame")
	fill.Size=UDim2.new(0.12,0,1,0)
	fill.BackgroundColor3=accent
	fill.BorderSizePixel=0
	fill.Parent=track
	corner(fill,99)
	smoothTween(fill,{Size=UDim2.new(0.92,0,1,0)},3.2,Enum.EasingStyle.Quint):Play()
	animateBarIn(bar)
	return{
		show=function(t,s)if t then title.Text=t end if s then sub.Text=s end end,
		dismiss=function()dismissOverlay(gui,bar,spinConn)end,
	}
end
local _kf_raw_build=buildLoadingGui
function buildLoadingGui()
	local result=_kf_raw_build()
	if type(result)~="table" then return result end
	pcall(function()
		local Players=game:GetService("Players")
		local plr=Players.LocalPlayer
		local hosts={}
		if type(gethui)=="function" then local ok,h=pcall(gethui) if ok and typeof(h)=="Instance" then hosts[#hosts+1]=h end end
		local okCore,cg=pcall(function() return game:GetService("CoreGui") end)
		if okCore and typeof(cg)=="Instance" then hosts[#hosts+1]=cg end
		if plr then local okPg,pg=pcall(function() return plr:FindFirstChildOfClass("PlayerGui") end) if okPg and typeof(pg)=="Instance" then hosts[#hosts+1]=pg end end
		local screen=nil
		for _,h in ipairs(hosts) do local g=h:FindFirstChild("KeyForge_Loading") if g then screen=g break end end
		if not screen then return end
		if LOADING_DIM then
			local veil=Instance.new("Frame")
			veil.Name="KeyForge_LoadingDim"
			veil.Size=UDim2.fromScale(1,1)
			veil.BackgroundColor3=LOADING_SCREEN_BG
			veil.BackgroundTransparency=0.42
			veil.BorderSizePixel=0
			veil.ZIndex=0
			veil.Parent=screen
		end
		local bar=screen:FindFirstChildWhichIsA("Frame")
		if bar then
			bar.BackgroundColor3=LOADING_BAR_BG
			for _,ch in ipairs(bar:GetDescendants()) do
				if ch:IsA("TextLabel") then
					if ch.Name=="Subtitle" then ch.TextColor3=LOADING_SUBTEXT else ch.TextColor3=LOADING_TEXT end
				elseif ch:IsA("Frame") and ch.BackgroundTransparency<1 then
					local parent=ch.Parent
					if parent and parent:IsA("Frame") and parent~=bar and ch.Size.Y.Scale==1 then ch.BackgroundColor3=LOADING_ACCENT end
				end
			end
		end
	end)
	return result
end
-- Pasteable loader from dashboard (use the dashboard-generated URL; it carries a signed load marker)
_G.script_key="YOUR_KEY"
loadstring(game:HttpGet("https://www.keyforge.win/v1/load/YOUR_PROJECT_ID?e=1&script=YOUR_SCRIPT&lsig=SIGNED_MARKER&key=".._G.script_key.."&_cb="..os.clock(),true))()

Copy selected preset:

Loader URL

Loader URLDashboard → Scripts → your project → copy the loader for the script. Keyed scripts include ?key=... in the URL.
KeylessUse the keyless loader URL — same loading overlay works without a key parameter.

Open visual previews in a new tab.

How it works

The preset builds a ScreenGui, shows the bar, runs loadstring(game:HttpGet(LOADER_URL))(), then dismisses the overlay. If load fails, check the output for the error.

usage.lua
-- Pasteable loader from dashboard (use the dashboard-generated URL; it carries a signed load marker)
_G.script_key="YOUR_KEY"
loadstring(game:HttpGet("https://www.keyforge.win/v1/load/YOUR_PROJECT_ID?e=1&script=YOUR_SCRIPT&lsig=SIGNED_MARKER&key=".._G.script_key.."&_cb="..os.clock(),true))()

Don't

  • Hardcode license keys in your game — use the dashboard loader URL.
  • Skip the loader and try to HttpGet the script directly. Delivery won't work.

Need help?

We can help with custom loading UIs, Discord panels, and ad gates.

Join support Discord and open a ticket. Include your project ID and a screenshot of what you want.

Chat: discord.gg/yupFgUkFfr