Roblox GUI Maker logoRoblox GUI Maker
Unofficial third-party tool · Not affiliated with Roblox Corporation

Global Leaderboard Roblox GUI Template with OrderedDataStore Powered

A top-10 global leaderboard GUI with player name, avatar placeholder, and score. Auto-refreshes every minute. This template provides a production-ready leaderboard system that displays the highest-scoring players across your entire Roblox game. It features a clean, modern design with automatic data synchronization, smooth entry animations, and a responsive layout that works on all screen sizes.

LeaderboardFree
Global Leaderboard Roblox GUI template — OrderedDataStore Powered, clean leaderboard layout, screenshot 1
Global Leaderboard Roblox GUI template — screenshot 1 of 1, showing ordereddatastore powered on a clean leaderboard layout for desktop.
Open in Web EditorJoin Studio plugin waitlist

Live preview

Global Leaderboard

1920×1080
Zoom100%
Desktop (FHD)
ScreenGui
Frame
🏆 Global Leaderboard
Frame
#1
Player_100
10000
Frame
#2
Player_101
9100
Frame
#3
Player_102
8200
Frame
#4
Player_103
7300
Frame
#5
Player_104
6400
Frame
#6
Player_105
5500
Frame
#7
Player_106
4600
Frame
#8
Player_107
3700
Frame
#9
Player_108
2800
Frame
#10
Player_109
1900
A top-10 global leaderboard GUI with player name, avatar placeholder, and score. Auto-refreshes every minute. This template provides a production-ready leaderboard system that displays the highest-scoring players across your entire Roblox game. It features a clean, modern design with automatic data synchronization, smooth entry animations, and a responsive layout that works on all screen sizes.

Includes real, production-ready Luau logic — not a static mockup.

What's inside

How to use this template

The Global Leaderboard template shows the top 10 players by score, auto-refreshing every minute. Paste the server Luau into ServerScriptService and the client Luau into StarterGui. The server uses OrderedDataStore to rank players and pushes the top 10 to all clients via a RemoteEvent. The client renders the rows with player name, avatar placeholder, and score. The layout uses UIListLayout so rows stack cleanly and scroll on mobile. To customize, replace the score key with your own stat (coins, wins, level). The auto-refresh interval is configurable in the server Luau. Note that OrderedDataStore has rate limits - the default 60-second refresh avoids throttling. Test in Studio by adding fake entries to the OrderedDataStore and confirming they appear in the correct order.

Add it to your game in 3 steps

  1. 1

    Copy the Luau

    Open the template in the web editor and click Export. Choose LocalScript to copy the full client Luau to your clipboard.

  2. 2

    Paste into StarterGui

    In Roblox Studio, right-click StarterGui in the Explorer, insert a LocalScript, and paste the copied Luau. Rename it to match the template.

  3. 3

    Press Play to verify

    Click Play in Studio. The GUI should appear exactly as designed. Tweak any Size or Position values in the script if you want to adjust the layout.

leaderboard.lua
lua
1--[[
2 Global Leaderboard - Client Side
3 A top-10 global leaderboard with OrderedDataStore integration
4 Features: Auto-refresh, smooth animations, avatar display, clean UI
5]]
6
7-- Services
8local Players = game:GetService("Players")
9local TweenService = game:GetService("TweenService")
10local ReplicatedStorage = game:GetService("ReplicatedStorage")
11local RunService = game:GetService("RunService")
12local HttpService = game:GetService("HttpService")
13
14local player = Players.LocalPlayer
15local playerGui = player:WaitForChild("PlayerGui")
16
17-- Constants
18local LEADERBOARD_SIZE = UDim2.new(0, 520, 0, 600)
19local LEADERBOARD_POSITION = UDim2.new(0.5, -260, 0.5, -300)
20local HEADER_HEIGHT = 70
21local ROW_HEIGHT = 56
22local FOOTER_HEIGHT = 36
23local REFRESH_INTERVAL = 60 -- seconds
24local TWEEN_DURATION = 0.35
25local STAGGER_DELAY = 0.05
26
27-- Colors
28local COLOR_BG = Color3.fromRGB(30, 30, 40)
29local COLOR_HEADER = Color3.fromRGB(40, 45, 60)
30local COLOR_ACCENT = Color3.fromRGB(255, 200, 50)
31local COLOR_TEXT_PRIMARY = Color3.fromRGB(255, 255, 255)
32local COLOR_TEXT_SECONDARY = Color3.fromRGB(180, 180, 190)
33local COLOR_RANK_GOLD = Color3.fromRGB(255, 215, 0)
34local COLOR_RANK_SILVER = Color3.fromRGB(192, 192, 192)
35local COLOR_RANK_BRONZE = Color3.fromRGB(205, 127, 50)
36local COLOR_ROW_EVEN = Color3.fromRGB(35, 38, 50)
37local COLOR_ROW_ODD = Color3.fromRGB(42, 45, 58)
38local COLOR_HIGHLIGHT = Color3.fromRGB(255, 200, 50)
39local COLOR_BUTTON_HOVER = Color3.fromRGB(60, 65, 85)
40local COLOR_CLOSE_RED = Color3.fromRGB(220, 60, 60)
41
42-- Tween presets
43local tweenInfoFade = TweenInfo.new(TWEEN_DURATION, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
44local tweenInfoSlide = TweenInfo.new(TWEEN_DURATION * 1.2, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
45local tweenInfoScale = TweenInfo.new(TWEEN_DURATION * 0.8, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out)
46local tweenInfoPulse = TweenInfo.new(0.6, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true)
47
48-- Remote events
49local LeaderboardEvents = ReplicatedStorage:WaitForChild("LeaderboardEvents")
50local RefreshEvent = LeaderboardEvents:WaitForChild("RefreshLeaderboard")
51local GetLeaderboardData = LeaderboardEvents:WaitForChild("GetLeaderboardData")
52
53-- GUI References (initialized in BuildUI)
54local gui, mainFrame, entriesContainer, loadingIndicator, lastUpdatedLabel
55local entryTemplate, closeButton, openButton, refreshButton
56
57-- State
58local isVisible = false
59local currentEntries = {}
60local refreshConnection = nil
61local lastRefreshTime = 0
62
63-----------------------------------------------------------
64-- Helper Functions
65-----------------------------------------------------------
66
67local function Create(className, props)
68 local instance = Instance.new(className)
69 for key, value in pairs(props or {}) do
70 instance[key] = value
71 end
72 return instance
73end
74
75local function Tween(instance, properties, tweenInfoOverride)
76 local info = tweenInfoOverride or tweenInfoFade
77 local tween = TweenService:Create(instance, info, properties)
78 tween:Play()
79 return tween
80end
81
82local function FormatNumber(num)
83 if num >= 1e9 then
84 return string.format("%.1fB", num / 1e9)
85 elseif num >= 1e6 then
86 return string.format("%.1fM", num / 1e6)
87 elseif num >= 1e3 then
88 return string.format("%.1fK", num / 1e3)
89 end
90 return tostring(math.floor(num))
91end
92
93local function GetRankColor(rank)
94 if rank == 1 then return COLOR_RANK_GOLD end
95 if rank == 2 then return COLOR_RANK_SILVER end
96 if rank == 3 then return COLOR_RANK_BRONZE end
97 return COLOR_TEXT_PRIMARY
98end
99
100local function GetRankSuffix(rank)
101 if rank == 1 then return "st" end
102 if rank == 2 then return "nd" end
103 if rank == 3 then return "rd" end
104 return "th"
105end
106
107-----------------------------------------------------------
108-- UI Construction
109-----------------------------------------------------------
110
111local function BuildUI()
112 -- ScreenGui
113 gui = Create("ScreenGui", {
114 Name = "LeaderboardGui",
115 ResetOnSpawn = false,
116 ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
117 Enabled = true,
118 Parent = playerGui,
119 })
120
121 -- Main Frame
122 mainFrame = Create("Frame", {
123 Name = "LeaderboardFrame",
124 Size = LEADERBOARD_SIZE,
125 Position = UDim2.new(0.5, 0, 0.4, 0), -- Start slightly above center for slide-in
126 AnchorPoint = Vector2.new(0.5, 0.5),
127 BackgroundColor3 = COLOR_BG,
128 BorderSizePixel = 0,
129 Visible = false,
130 ZIndex = 10,
131 Parent = gui,
132 })
133
134 Create("UICorner", {
135 CornerRadius = UDim.new(0, 12),
136 Parent = mainFrame,
137 })
138
139 Create("UIGradient", {
140 Color = ColorSequence.new({
141 ColorSequenceKeypoint.new(0, Color3.fromRGB(35, 35, 50)),
142 ColorSequenceKeypoint.new(1, Color3.fromRGB(25, 25, 35)),
143 }),
144 Rotation = 90,
145 Parent = mainFrame,
146 })
147
148 -- Shadow effect (behind main frame)
149 local shadow = Create("ImageLabel", {
150 Name = "Shadow",
151 Size = UDim2.new(1, 40, 1, 40),
152 Position = UDim2.new(0, -20, 0, -20),
153 BackgroundTransparency = 1,
154 Image = "rbxassetid://5554236805",
155 ImageColor3 = Color3.fromRGB(0, 0, 0),
156 ImageTransparency = 0.6,
157 ScaleType = Enum.ScaleType.Slice,
158 SliceCenter = Rect.new(23, 23, 277, 277),
159 ZIndex = 9,
160 Parent = mainFrame,
161 })
162
163 -- Header Frame
164 local headerFrame = Create("Frame", {
165 Name = "HeaderFrame",
166 Size = UDim2.new(1, 0, 0, HEADER_HEIGHT),
167 BackgroundColor3 = COLOR_HEADER,
168 BorderSizePixel = 0,
169 ZIndex = 11,
170 Parent = mainFrame,
171 })
172
173 Create("UICorner", {
174 CornerRadius = UDim.new(0, 12),
175 Parent = headerFrame,
176 })
177
178 -- Fix header bottom corners
179 local headerFix = Create("Frame", {
180 Name = "HeaderFix",
181 Size = UDim2.new(1, 0, 0, 12),
182 Position = UDim2.new(0, 0, 1, -12),
183 BackgroundColor3 = COLOR_HEADER,
184 BorderSizePixel = 0,
185 ZIndex = 11,
186 Parent = headerFrame,
187 })
188
189 -- Title
190 local titleLabel = Create("TextLabel", {
191 Name = "TitleLabel",
192 Size = UDim2.new(0.6, 0, 0, 36),
193 Position = UDim2.new(0, 20, 0, 8),
194 BackgroundTransparency = 1,
195 Text = "🏆 Global Leaderboard",
196 TextColor3 = COLOR_TEXT_PRIMARY,
197 TextSize = 24,
198 Font = Enum.Font.GothamBold,
199 TextXAlignment = Enum.TextXAlignment.Left,
200 ZIndex = 12,
201 Parent = headerFrame,
202 })
203
204 -- Subtitle
205 Create("TextLabel", {
206 Name = "SubtitleLabel",
207 Size = UDim2.new(0.6, 0, 0, 20),
208 Position = UDim2.new(0, 20, 0, 42),
209 BackgroundTransparency = 1,
210 Text = "Top 10 Players Worldwide",
211 TextColor3 = COLOR_TEXT_SECONDARY,
212 TextSize = 13,
213 Font = Enum.Font.Gotham,
214 TextXAlignment = Enum.TextXAlignment.Left,
215 ZIndex = 12,
216 Parent = headerFrame,
217 })
218
219 -- Refresh Button
220 refreshButton = Create("TextButton", {
221 Name = "RefreshButton",
222 Size = UDim2.new(0, 80, 0, 32),
223 Position = UDim2.new(1, -100, 0, 19),
224 AnchorPoint = Vector2.new(0, 0),
225 BackgroundColor3 = COLOR_BUTTON_HOVER,
226 Text = "🔄 Refresh",
227 TextColor3 = COLOR_TEXT_PRIMARY,
228 TextSize = 12,
229 Font = Enum.Font.GothamSemibold,
230 AutoButtonColor = false,
231 ZIndex = 12,
232 Parent = headerFrame,
233 })
234
235 Create("UICorner", {
236 CornerRadius = UDim.new(0, 8),
237 Parent = refreshButton,
238 })
239
240 -- Divider
241 Create("Frame", {
242 Name = "Divider",
243 Size = UDim2.new(1, -20, 0, 1),
244 Position = UDim2.new(0, 10, 0, HEADER_HEIGHT),
245 BackgroundColor3 = Color3.fromRGB(60, 60, 75),
246 BorderSizePixel = 0,
247 ZIndex = 11,
248 Parent = mainFrame,
249 })
250
251 -- Column Headers
252 local columnHeaders = Create("Frame", {
253 Name = "ColumnHeaders",
254 Size = UDim2.new(1, -20, 0, 28),
255 Position = UDim2.new(0, 10, 0, HEADER_HEIGHT + 6),
256 BackgroundTransparency = 1,
257 ZIndex = 11,
258 Parent = mainFrame,
259 })
260
261 Create("TextLabel", {
262 Name = "RankHeader",
263 Size = UDim2.new(0, 60, 1, 0),
264 Position = UDim2.new(0, 10, 0, 0),
265 BackgroundTransparency = 1,
266 Text = "RANK",
267 TextColor3 = COLOR_ACCENT,
268 TextSize = 12,
269 Font = Enum.Font.GothamBold,
270 TextXAlignment = Enum.TextXAlignment.Center,
271 ZIndex = 12,
272 Parent = columnHeaders,
273 })
274
275 Create("TextLabel", {
276 Name = "PlayerHeader",
277 Size = UDim2.new(0, 200, 1, 0),
278 Position = UDim2.new(0, 80, 0, 0),
279 BackgroundTransparency = 1,
280 Text = "PLAYER",
281 TextColor3 = COLOR_ACCENT,
282 TextSize = 12,
283 Font = Enum.Font.GothamBold,
284 TextXAlignment = Enum.TextXAlignment.Left,
285 ZIndex = 12,
286 Parent = columnHeaders,
287 })
288
289 Create("TextLabel", {
290 Name = "ScoreHeader",
291 Size = UDim2.new(0, 120, 1, 0),
292 Position = UDim2.new(1, -130, 0, 0),
293 BackgroundTransparency = 1,
294 Text = "SCORE",
295 TextColor3 = COLOR_ACCENT,
296 TextSize = 12,
297 Font = Enum.Font.GothamBold,
298 TextXAlignment = Enum.TextXAlignment.Right,
299 ZIndex = 12,
300 Parent = columnHeaders,
301 })
302
303 -- Entries Container (ScrollingFrame)
304 entriesContainer = Create("ScrollingFrame", {
305 Name = "EntriesContainer",
306 Size = UDim2.new(1, -20, 1, -(HEADER_HEIGHT + FOOTER_HEIGHT + 50)),
307 Position = UDim2.new(0, 10, 0, HEADER_HEIGHT + 38),
308 BackgroundTransparency = 1,
309 BorderSizePixel = 0,
310 ScrollBarThickness = 4,
311 ScrollBarImageColor3 = COLOR_ACCENT,
312 ScrollBarImageTransparency = 0.5,
313 CanvasSize = UDim2.new(0, 0, 0, 0),
314 ZIndex = 11,
315 Parent = mainFrame,
316 })
317
318 Create("UIListLayout", {
319 Padding = UDim.new(0, 4),
320 SortOrder = Enum.SortOrder.LayoutOrder,
321 Parent = entriesContainer,
322 })
323
324 -- Entry Template (hidden, cloned for each entry)
325 entryTemplate = Create("Frame", {
326 Name = "EntryTemplate",
327 Size = UDim2.new(1, 0, 0, ROW_HEIGHT),
328 BackgroundColor3 = COLOR_ROW_ODD,
329 BorderSizePixel = 0,
330 Visible = false,
331 ZIndex = 11,
332 })
333
334 Create("UICorner", {
335 CornerRadius = UDim.new(0, 8),
336 Parent = entryTemplate,
337 })
338
339 -- Rank background circle
340 local rankBg = Create("Frame", {
341 Name = "RankBg",
342 Size = UDim2.new(0, 36, 0, 36),
343 Position = UDim2.new(0, 12, 0.5, 0),
344 AnchorPoint = Vector2.new(0, 0.5),
345 BackgroundColor3 = COLOR_HEADER,
346 BorderSizePixel = 0,
347 ZIndex = 12,
348 Parent = entryTemplate,
349 })
350
351 Create("UICorner", {
352 CornerRadius = UDim.new(1, 0),
353 Parent = rankBg,
354 })
355
356 Create("TextLabel", {
357 Name = "RankLabel",
358 Size = UDim2.new(1, 0, 1, 0),
359 BackgroundTransparency = 1,
360 Text = "1",
361 TextColor3 = COLOR_RANK_GOLD,
362 TextSize = 16,
363 Font = Enum.Font.GothamBold,
364 TextXAlignment = Enum.TextXAlignment.Center,
365 TextYAlignment = Enum.TextYAlignment.Center,
366 ZIndex = 13,
367 Parent = rankBg,
368 })
369
370 -- Avatar
371 local avatarFrame = Create("Frame", {
372 Name = "AvatarFrame",
373 Size = UDim2.new(0, 40, 0, 40),
374 Position = UDim2.new(0, 58, 0.5, 0),
375 AnchorPoint = Vector2.new(0, 0.5),
376 BackgroundColor3 = COLOR_HEADER,
377 BorderSizePixel = 0,
378 ZIndex = 12,
379 Parent = entryTemplate,
380 })
381
382 Create("UICorner", {
383 CornerRadius = UDim.new(1, 0),
384 Parent = avatarFrame,
385 })
386
387 Create("ImageLabel", {
388 Name = "AvatarImage",
389 Size = UDim2.new(1, -4, 1, -4),
390 Position = UDim2.new(0, 2, 0, 2),
391 BackgroundTransparency = 1,
392 Image = "",
393 ZIndex = 13,
394 Parent = avatarFrame,
395 })
396
397 -- Player Name
398 Create("TextLabel", {
399 Name = "PlayerNameLabel",
400 Size = UDim2.new(0, 180, 0, ROW_HEIGHT),
401 Position = UDim2.new(0, 108, 0, 0),
402 BackgroundTransparency = 1,
403 Text = "PlayerName",
404 TextColor3 = COLOR_TEXT_PRIMARY,
405 TextSize = 15,
406 Font = Enum.Font.GothamSemibold,
407 TextXAlignment = Enum.TextXAlignment.Left,
408 TextTruncate = Enum.TextTruncate.AtEnd,
409 ZIndex = 12,
410 Parent = entryTemplate,
411 })
412
413 -- Score
414 Create("TextLabel", {
415 Name = "ScoreLabel",
416 Size = UDim2.new(0, 120, 0, ROW_HEIGHT),
417 Position = UDim2.new(1, -130, 0, 0),
418 BackgroundTransparency = 1,
419 Text = "0",
420 TextColor3 = COLOR_ACCENT,
421 TextSize = 16,
422 Font = Enum.Font.GothamBold,
423 TextXAlignment = Enum.TextXAlignment.Right,
424 ZIndex = 12,
425 Parent = entryTemplate,
426 })
427
428 -- Loading Indicator
429 loadingIndicator = Create("Frame", {
430 Name = "LoadingIndicator",
431 Size = UDim2.new(1, 0, 0, 100),
432 Position = UDim2.new(0, 0, 0, HEADER_HEIGHT + 40),
433 BackgroundTransparency = 1,
434 Visible = false,
435 ZIndex = 15,
436 Parent = mainFrame,
437 })
438
439 Create("TextLabel", {
440 Name = "LoadingText",
441 Size = UDim2.new(1, 0, 1, 0),
442 BackgroundTransparency = 1,
443 Text = "⏳ Loading leaderboard data...",
444 TextColor3 = COLOR_TEXT_SECONDARY,
445 TextSize = 16,
446 Font = Enum.Font.Gotham,
447 TextXAlignment = Enum.TextXAlignment.Center,
448 TextYAlignment = Enum.TextYAlignment.Center,
449 ZIndex = 16,
450 Parent = loadingIndicator,
451 })
452
453 -- Footer Frame
454 local footerFrame = Create("Frame", {
455 Name = "FooterFrame",
456 Size = UDim2.new(1, 0, 0, FOOTER_HEIGHT),
457 Position = UDim2.new(0, 0, 1, -FOOTER_HEIGHT),
458 BackgroundColor3 = COLOR_HEADER,
459 BorderSizePixel = 0,
460 ZIndex = 11,
461 Parent = mainFrame,
462 })
463
464 Create("UICorner", {
465 CornerRadius = UDim.new(0, 12),
466 Parent = footerFrame,
467 })
468
469 local footerFix = Create("Frame", {
470 Name = "FooterFix",
471 Size = UDim2.new(1, 0, 0, 12),
472 Position = UDim2.new(0, 0, 0, 0),
473 BackgroundColor3 = COLOR_HEADER,
474 BorderSizePixel = 0,
475 ZIndex = 11,
476 Parent = footerFrame,
477 })
478
479 lastUpdatedLabel = Create("TextLabel", {
480 Name = "LastUpdatedLabel",
481 Size = UDim2.new(0.7, 0, 1, 0),
482 Position = UDim2.new(0, 20, 0, 0),
483 BackgroundTransparency = 1,
484 Text = "Last updated: Never",
485 TextColor3 = COLOR_TEXT_SECONDARY,
486 TextSize = 11,
487 Font = Enum.Font.Gotham,
488 TextXAlignment = Enum.TextXAlignment.Left,
489 ZIndex = 12,
490 Parent = footerFrame,
491 })
492
493 -- Close Button
494 closeButton = Create("TextButton", {
495 Name = "CloseButton",
496 Size = UDim2.new(0, 70, 0, 26),
497 Position = UDim2.new(1, -90, 0, 5),
498 BackgroundColor3 = COLOR_CLOSE_RED,
499 Text = "✕ Close",
500 TextColor3 = COLOR_TEXT_PRIMARY,
501 TextSize = 12,
502 Font = Enum.Font.GothamSemibold,
503 AutoButtonColor = false,
504 ZIndex = 12,
505 Parent = footerFrame,
506 })
507
508 Create("UICorner", {
509 CornerRadius = UDim.new(0, 6),
510 Parent = closeButton,
511 })
512
513 -- Open Button (when leaderboard is closed)
514 openButton = Create("TextButton", {
515 Name = "OpenButton",
516 Size = UDim2.new(0, 160, 0, 44),
517 Position = UDim2.new(0, 20, 0.5, -22),
518 BackgroundColor3 = COLOR_HEADER,
519 Text = "🏆 Leaderboard",
520 TextColor3 = COLOR_ACCENT,
521 TextSize = 16,
522 Font = Enum.Font.GothamBold,
523 AutoButtonColor = false,
524 Visible = true,
525 ZIndex = 5,
526 Parent = gui,
527 })
528
529 Create("UICorner", {
530 CornerRadius = UDim.new(0, 10),
531 Parent = openButton,
532 })
533
534 -- Open button shadow
535 Create("ImageLabel", {
536 Name = "OpenShadow",
537 Size = UDim2.new(1, 20, 1, 20),
538 Position = UDim2.new(0, -10, 0, -10),
539 BackgroundTransparency = 1,
540 Image = "rbxassetid://5554236805",
541 ImageColor3 = Color3.fromRGB(0, 0, 0),
542 ImageTransparency = 0.7,
543 ScaleType = Enum.ScaleType.Slice,
544 SliceCenter = Rect.new(23, 23, 277, 277),
545 ZIndex = 4,
546 Parent = openButton,
547 })
548end
549
550-----------------------------------------------------------
551-- Entry Management
552-----------------------------------------------------------
553
554local function ClearEntries()
555 for _, entry in ipairs(currentEntries) do
556 Tween(entry, {BackgroundTransparency = 1})
557 task.delay(TWEEN_DURATION, function()
558 if entry and entry.Parent then
559 entry:Destroy()
560 end
561 end)
562 end
563 currentEntries = {}
564end
565
566local function CreateEntry(rank, playerName, score, userId, isLocalPlayer)
567 local entry = entryTemplate:Clone()
568 entry.Name = "Entry_" .. rank
569 entry.Visible = true
570 entry.LayoutOrder = rank
571 entry.BackgroundTransparency = 0
572
573 -- Alternate row colors
574 if rank % 2 == 0 then
575 entry.BackgroundColor3 = COLOR_ROW_EVEN
576 else
577 entry.BackgroundColor3 = COLOR_ROW_ODD
578 end
579
580 -- Highlight local player
581 if isLocalPlayer then
582 entry.BackgroundColor3 = Color3.fromRGB(55, 50, 35)
583 local stroke = Instance.new("UIStroke")
584 stroke.Color = COLOR_HIGHLIGHT
585 stroke.Thickness = 2
586 stroke.Transparency = 0.3
587 stroke.Parent = entry
588 end
589
590 -- Rank
591 local rankBg = entry:FindFirstChild("RankBg")
592 if rankBg then
593 local rankLabel = rankBg:FindFirstChild("RankLabel")
594 if rankLabel then
595 rankLabel.Text = tostring(rank) .. GetRankSuffix(rank)
596 rankLabel.TextColor3 = GetRankColor(rank)
597 end
598 end
599
600 -- Avatar
601 local avatarImage = entry:FindFirstChild("AvatarFrame")
602 if avatarImage then
603 local imgLabel = avatarImage:FindFirstChild("AvatarImage")
604 if imgLabel and userId then
605 imgLabel.Image = "rbxthumb://type=AvatarHeadShot&id=" .. userId .. "&w=48&h=48"
606 else
607 imgLabel.Image = "rbxassetid://0"
608 end
609 end
610
611 -- Player Name
612 local nameLabel = entry:FindFirstChild("PlayerNameLabel")
613 if nameLabel then
614 nameLabel.Text = playerName
615 if isLocalPlayer then
616 nameLabel.Text = playerName .. " (YOU)"
617 nameLabel.TextColor3 = COLOR_HIGHLIGHT
618 end
619 end
620
621 -- Score
622 local scoreLabel = entry:FindFirstChild("ScoreLabel")
623 if scoreLabel then
624 scoreLabel.Text = FormatNumber(score)
625 end
626
627 entry.Parent = entriesContainer
628 table.insert(currentEntries, entry)
629
630 -- Animate entry in
631 entry.Size = UDim2.new(0.9, 0, 0, ROW_HEIGHT)
632 entry.BackgroundTransparency = 1
633
634 task.delay((rank - 1) * STAGGER_DELAY, function()
635 if entry and entry.Parent then
636 Tween(entry, {
637 Size = UDim2.new(1, 0, 0, ROW_HEIGHT),
638 BackgroundTransparency = 0,
639 }, tweenInfoSlide)
640 end
641 end)
642end
643
644-----------------------------------------------------------
645-- Data Loading
646-----------------------------------------------------------
647
648local function UpdateLeaderboard(data)
649 -- Clear existing entries
650 ClearEntries()
651
652 -- Hide loading
653 loadingIndicator.Visible = false
654
655 if not data or #data == 0 then
656 -- Show "no data" message
657 local noDataLabel = Create("TextLabel", {
658 Name = "NoDataLabel",
659 Size = UDim2.new(1, 0, 0, 100),
660 BackgroundTransparency = 1,
661 Text = "📭 No data yet. Be the first to set a score!",
662 TextColor3 = COLOR_TEXT_SECONDARY,
663 TextSize = 15,
664 Font = Enum.Font.Gotham,
665 TextXAlignment = Enum.TextXAlignment.Center,
666 TextYAlignment = Enum.TextYAlignment.Center,
667 ZIndex = 14,
668 Parent = entriesContainer,
669 })
670 table.insert(currentEntries, noDataLabel)
671 entriesContainer.CanvasSize = UDim2.new(0, 0, 0, 120)
672 return
673 end
674
675 -- Create entries
676 for i, entryData in ipairs(data) do
677 if i > 10 then break end
678 local isLocalPlayer = entryData.UserId == player.UserId
679 CreateEntry(
680 i,
681 entryData.DisplayName or entryData.Name or "Unknown",
682 entryData.Score or 0,
683 entryData.UserId,
684 isLocalPlayer
685 )
686 end
687
688 -- Update canvas size
689 local contentHeight = math.min(#data, 10) * (ROW_HEIGHT + 4)
690 entriesContainer.CanvasSize = UDim2.new(0, 0, 0, contentHeight)
691
692 -- Update timestamp
693 lastRefreshTime = os.time()
694 lastUpdatedLabel.Text = "Last updated: " .. os.date("%H:%M:%S", lastRefreshTime)
695end
696
697local function RefreshLeaderboard()
698 -- Prevent spam refreshing
699 local timeSinceLastRefresh = os.time() - lastRefreshTime
700 if timeSinceLastRefresh < 5 then
701 return
702 end
703
704 -- Show loading
705 loadingIndicator.Visible = true
706
707 -- Request data from server
708 local success, data = pcall(function()
709 return GetLeaderboardData:InvokeServer()
710 end)
711
712 if success and data then
713 UpdateLeaderboard(data)
714 else
715 loadingIndicator.Visible = false
716 warn("[Leaderboard] Failed to refresh: " .. tostring(data))
717
718 -- Show error message
719 ClearEntries()
720 local errorLabel = Create("TextLabel", {
721 Name = "ErrorLabel",
722 Size = UDim2.new(1, 0, 0, 100),
723 BackgroundTransparency = 1,
724 Text = "❌ Failed to load data. Try again.",
725 TextColor3 = Color3.fromRGB(255, 100, 100),
726 TextSize = 15,
727 Font = Enum.Font.Gotham,
728 TextXAlignment = Enum.TextXAlignment.Center,
729 TextYAlignment = Enum.TextYAlignment.Center,
730 ZIndex = 14,
731 Parent = entriesContainer,
732 })
733 table.insert(currentEntries, errorLabel)
734 end
735end
736
737-----------------------------------------------------------
738-- Visibility Toggle
739-----------------------------------------------------------
740
741local function ShowLeaderboard()
742 if isVisible then return end
743 isVisible = true
744
745 mainFrame.Visible = true
746 openButton.Visible = false
747
748 -- Slide in animation
749 mainFrame.Position = UDim2.new(0.5, 0, 0.35, 0)
750 mainFrame.BackgroundTransparency = 1
751
752 Tween(mainFrame, {
753 Position = LEADERBOARD_POSITION,
754 BackgroundTransparency = 0,
755 }, tweenInfoSlide)
756
757 -- Fade in shadow
758 local shadow = mainFrame:FindFirstChild("Shadow")
759 if shadow then
760 shadow.ImageTransparency = 1
761 Tween(shadow, {ImageTransparency = 0.6}, tweenInfoFade)
762 end
763
764 -- Refresh data on open
765 RefreshLeaderboard()
766end
767
768local function HideLeaderboard()
769 if not isVisible then return end
770 isVisible = false
771
772 -- Fade out animation
773 Tween(mainFrame, {
774 Position = UDim2.new(0.5, 0, 0.35, 0),
775 BackgroundTransparency = 1,
776 }, tweenInfoFade)
777
778 -- Fade out shadow
779 local shadow = mainFrame:FindFirstChild("Shadow")
780 if shadow then
781 Tween(shadow, {ImageTransparency = 1}, tweenInfoFade)
782 end
783
784 task.delay(TWEEN_DURATION, function()
785 mainFrame.Visible = false
786 openButton.Visible = true
787
788 -- Pop in animation for open button
789 openButton.Size = UDim2.new(0, 0, 0, 0)
790 Tween(openButton, {
791 Size = UDim2.new(0, 160, 0, 44),
792 }, tweenInfoScale)
793 end)
794end
795
796-----------------------------------------------------------
797-- Button Interactions
798-----------------------------------------------------------
799
800local function SetupButtonAnimations()
801 -- Refresh button hover
802 refreshButton.MouseEnter:Connect(function()
803 Tween(refreshButton, {BackgroundColor3 = COLOR_ACCENT})
804 refreshButton.TextColor3 = COLOR_BG
805 end)
806
807 refreshButton.MouseLeave:Connect(function()
808 Tween(refreshButton, {BackgroundColor3 = COLOR_BUTTON_HOVER})
809 refreshButton.TextColor3 = COLOR_TEXT_PRIMARY
810 end)
811
812 refreshButton.MouseButton1Click:Connect(function()
813 -- Spin animation
814 local originalRotation = refreshButton.Rotation
815 Tween(refreshButton, {Rotation = 360}, TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out))
816 task.delay(0.5, function()
817 refreshButton.Rotation = 0
818 end)
819 RefreshLeaderboard()
820 end)
821
822 -- Close button hover
823 closeButton.MouseEnter:Connect(function()
824 Tween(closeButton, {BackgroundColor3 = Color3.fromRGB(255, 80, 80)})
825 end)
826
827 closeButton.MouseLeave:Connect(function()
828 Tween(closeButton, {BackgroundColor3 = COLOR_CLOSE_RED})
829 end)
830
831 closeButton.MouseButton1Click:Connect(HideLeaderboard)
832
833 -- Open button hover
834 openButton.MouseEnter:Connect(function()
835 Tween(openButton, {BackgroundColor3 = Color3.fromRGB(60, 65, 90)})
836 Tween(openButton, {Size = UDim2.new(0, 170, 0, 48)})
837 end)
838
839 openButton.MouseLeave:Connect(function()
840 Tween(openButton, {BackgroundColor3 = COLOR_HEADER})
841 Tween(openButton, {Size = UDim2.new(0, 160, 0, 44)})
842 end)
843
844 openButton.MouseButton1Click:Connect(ShowLeaderboard)
845end
846
847-----------------------------------------------------------
848-- Auto Refresh
849-----------------------------------------------------------
850
851local function StartAutoRefresh()
852 if refreshConnection then
853 refreshConnection:Disconnect()
854 end
855
856 refreshConnection = task.spawn(function()
857 while true do
858 task.wait(REFRESH_INTERVAL)
859 if isVisible then
860 RefreshLeaderboard()
861 end
862 end
863 end)
864end
865
866-----------------------------------------------------------
867-- Keyboard Shortcut
868-----------------------------------------------------------
869
870local function SetupKeyboardShortcut()
871 local UserInputService = game:GetService("UserInputService")
872
873 UserInputService.InputBegan:Connect(function(input, gameProcessed)
874 if gameProcessed then return end
875 if input.KeyCode == Enum.KeyCode.L then
876 if isVisible then
877 HideLeaderboard()
878 else
879 ShowLeaderboard()
880 end
881 end
882 end)
883end
884
885-----------------------------------------------------------
886-- Initialization
887-----------------------------------------------------------
888
889local function Initialize()
890 BuildUI()
891 SetupButtonAnimations()
892 StartAutoRefresh()
893 SetupKeyboardShortcut()
894
895 -- Listen for server-pushed updates
896 RefreshEvent.OnClientEvent:Connect(function(data)
897 if isVisible then
898 UpdateLeaderboard(data)
899 end
900 end)
901
902 print("[Leaderboard] Global Leaderboard initialized. Press 'L' to toggle.")
903end
904
905-- Wait for player to be ready
906if player.Character then
907 Initialize()
908else
909 player.CharacterAdded:Wait()
910 Initialize()
911end

Code preview

Global Leaderboard

Luau
Interactive visual preview is shown in the Live preview section above.Switch tabs to inspect the generated Luau client/server code.
Visual preview of the templateRoblox GUI Maker

Frequently asked questions

Keep going