--[[ Lunaris Z - Server Information (v2) by LunarisTeam Live information about the server you are in: players, ping, FPS, game name, Place / Universe / Job ID, server type, server time and your session time. - Drag the header to move the window. - [ - ] minimizes it to a compact bar that keeps showing live stats. - Click a Place ID / Universe ID / Job ID value to copy it. - "Copy Join Script" copies a snippet that teleports you back to this exact server. ]] local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local MarketplaceService = game:GetService("MarketplaceService") local TweenService = game:GetService("TweenService") local Stats = game:GetService("Stats") local LocalPlayer = Players.LocalPlayer local GUI_NAME = "LunarisZ_ServerInfo" -- Theme local ACCENT = Color3.fromRGB(255, 138, 0) local ACCENT_HOVER = Color3.fromRGB(255, 166, 48) local ACCENT_SOFT = Color3.fromRGB(34, 24, 10) local BG = Color3.fromRGB(17, 17, 20) local BG_TOP = Color3.fromRGB(34, 24, 12) local BG_DARK = Color3.fromRGB(10, 10, 12) local BORDER = Color3.fromRGB(38, 38, 44) local TEXT = Color3.fromRGB(236, 236, 239) local MUTED = Color3.fromRGB(133, 133, 141) local GOOD = Color3.fromRGB(80, 200, 120) local WARN = Color3.fromRGB(240, 190, 60) local BAD = Color3.fromRGB(235, 80, 80) local VIP = Color3.fromRGB(160, 120, 255) local MINUS = utf8.char(8211) -- en dash local PLUS = "+" local TIMES = utf8.char(215) local BULLET = utf8.char(8226) --------------------------------------------------------------------- -- Helpers --------------------------------------------------------------------- local function getGuiParent() if gethui then local ok, hui = pcall(gethui) if ok and hui then return hui end end local okCore, coreGui = pcall(function() return game:GetService("CoreGui") end) if okCore and coreGui then local probe = Instance.new("Folder") local canParent = pcall(function() probe.Parent = coreGui end) probe:Destroy() if canParent then return coreGui end end return LocalPlayer:WaitForChild("PlayerGui") end local function create(className, props, parent) local inst = Instance.new(className) for key, value in pairs(props) do inst[key] = value end inst.Parent = parent return inst end local function tween(object, duration, properties, style, direction) local t = TweenService:Create( object, TweenInfo.new(duration, style or Enum.EasingStyle.Quad, direction or Enum.EasingDirection.Out), properties ) t:Play() return t end local function formatTime(seconds) seconds = math.floor(seconds) return string.format("%02d:%02d:%02d", seconds // 3600, (seconds % 3600) // 60, seconds % 60) end local function getPing() local ok, value = pcall(function() return Stats.Network.ServerStatsItem["Data Ping"]:GetValue() end) if ok and value then return math.floor(value) end return nil end local function getGameName() local ok, info = pcall(function() return MarketplaceService:GetProductInfo(game.PlaceId) end) if ok and info and info.Name then return info.Name end return "Unknown" end local function getServerType() if game.PrivateServerId ~= "" then if game.PrivateServerOwnerId ~= 0 then return "VIP Server", VIP end return "Private Server", ACCENT end return "Public Server", GOOD end local clipboardFunction = setclipboard or toclipboard local function copyToClipboard(text) if clipboardFunction then local ok = pcall(clipboardFunction, text) return ok and "Copied!" or "Error" end print(text) return "No clipboard" end -- Temporarily replaces a button's text (used for "Copied!" feedback). local function flash(button, message, duration) if button:GetAttribute("OriginalText") == nil then button:SetAttribute("OriginalText", button.Text) end button.Text = message local token = (button:GetAttribute("Token") or 0) + 1 button:SetAttribute("Token", token) task.delay(duration, function() if button.Parent and button:GetAttribute("Token") == token then button.Text = button:GetAttribute("OriginalText") button:SetAttribute("OriginalText", nil) end end) end --------------------------------------------------------------------- -- Cleanup of any previous instance --------------------------------------------------------------------- local guiParent = getGuiParent() local old = guiParent:FindFirstChild(GUI_NAME) if old then old:Destroy() end local connections = {} --------------------------------------------------------------------- -- Window --------------------------------------------------------------------- local screenGui = create("ScreenGui", { Name = GUI_NAME, ResetOnSpawn = false, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, }, guiParent) local main = create("Frame", { Name = "Main", BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Position = UDim2.new(0, 40, 0.5, -210), Size = UDim2.new(0, 340, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, Active = true, }, screenGui) create("UICorner", { CornerRadius = UDim.new(0, 16) }, main) create("UIStroke", { Color = BORDER, Thickness = 1 }, main) create("UIGradient", { Rotation = 90, Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, BG_TOP), ColorSequenceKeypoint.new(0.28, BG), ColorSequenceKeypoint.new(1, BG), }), }, main) create("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 0), }, main) local scale = create("UIScale", { Scale = 0.92 }, main) tween(scale, 0.3, { Scale = 1 }, Enum.EasingStyle.Back, Enum.EasingDirection.Out) --------------------------------------------------------------------- -- Header --------------------------------------------------------------------- local header = create("Frame", { Name = "Header", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 58), LayoutOrder = 1, }, main) local dot = create("Frame", { Name = "LiveDot", BackgroundColor3 = GOOD, BorderSizePixel = 0, Position = UDim2.new(0, 18, 0.5, -4), Size = UDim2.new(0, 8, 0, 8), }, header) create("UICorner", { CornerRadius = UDim.new(1, 0) }, dot) TweenService:Create( dot, TweenInfo.new(0.9, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true), { BackgroundTransparency = 0.7 } ):Play() create("TextLabel", { Name = "Title", BackgroundTransparency = 1, Position = UDim2.new(0, 36, 0, 11), Size = UDim2.new(1, -120, 0, 18), Font = Enum.Font.GothamBold, RichText = true, Text = 'Lunaris Z', TextColor3 = TEXT, TextSize = 15, TextXAlignment = Enum.TextXAlignment.Left, }, header) local subtitle = create("TextLabel", { Name = "Subtitle", BackgroundTransparency = 1, Position = UDim2.new(0, 36, 0, 30), Size = UDim2.new(1, -120, 0, 16), Font = Enum.Font.Gotham, Text = "Server Information", TextColor3 = MUTED, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, }, header) local function headerButton(rightOffset, text) local button = create("TextButton", { BackgroundColor3 = BORDER, BackgroundTransparency = 1, Position = UDim2.new(1, rightOffset, 0.5, -14), Size = UDim2.new(0, 28, 0, 28), Font = Enum.Font.GothamBold, Text = text, TextColor3 = MUTED, TextSize = 15, AutoButtonColor = false, }, header) create("UICorner", { CornerRadius = UDim.new(1, 0) }, button) return button end local minimizeButton = headerButton(-72, MINUS) local closeButton = headerButton(-40, TIMES) minimizeButton.MouseEnter:Connect(function() tween(minimizeButton, 0.15, { BackgroundTransparency = 0, TextColor3 = TEXT }) end) minimizeButton.MouseLeave:Connect(function() tween(minimizeButton, 0.15, { BackgroundTransparency = 1, TextColor3 = MUTED }) end) closeButton.MouseEnter:Connect(function() tween(closeButton, 0.15, { BackgroundTransparency = 0, TextColor3 = BAD }) end) closeButton.MouseLeave:Connect(function() tween(closeButton, 0.15, { BackgroundTransparency = 1, TextColor3 = MUTED }) end) --------------------------------------------------------------------- -- Content (this is what the minimize button collapses) --------------------------------------------------------------------- local content = create("Frame", { Name = "Content", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, ClipsDescendants = true, LayoutOrder = 2, }, main) create("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 0), }, content) create("Frame", { Name = "Divider", BackgroundColor3 = BORDER, BorderSizePixel = 0, Size = UDim2.new(1, 0, 0, 1), LayoutOrder = 1, }, content) -- Stat tiles --------------------------------------------------------- local tilesHolder = create("Frame", { Name = "TilesHolder", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 94), LayoutOrder = 2, }, content) create("UIPadding", { PaddingTop = UDim.new(0, 14), PaddingLeft = UDim.new(0, 16), PaddingRight = UDim.new(0, 16), }, tilesHolder) local tilesRow = create("Frame", { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), }, tilesHolder) create("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 8), }, tilesRow) local function makeTile(order, labelText) local tile = create("Frame", { BackgroundColor3 = BG_DARK, BorderSizePixel = 0, Size = UDim2.new(1 / 3, -6, 1, 0), LayoutOrder = order, }, tilesRow) create("UICorner", { CornerRadius = UDim.new(0, 10) }, tile) create("UIStroke", { Color = BORDER, Thickness = 1 }, tile) local value = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 8), Size = UDim2.new(1, -20, 0, 28), Font = Enum.Font.GothamBold, Text = "-", TextColor3 = MUTED, TextSize = 22, TextXAlignment = Enum.TextXAlignment.Left, }, tile) local label = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 37), Size = UDim2.new(1, -20, 0, 14), Font = Enum.Font.GothamMedium, Text = labelText, TextColor3 = MUTED, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left, }, tile) local track = create("Frame", { BackgroundColor3 = BORDER, BorderSizePixel = 0, Position = UDim2.new(0, 10, 1, -14), Size = UDim2.new(1, -20, 0, 4), }, tile) create("UICorner", { CornerRadius = UDim.new(1, 0) }, track) local fill = create("Frame", { BackgroundColor3 = ACCENT, BorderSizePixel = 0, Size = UDim2.new(0, 0, 1, 0), }, track) create("UICorner", { CornerRadius = UDim.new(1, 0) }, fill) return { value = value, label = label, fill = fill } end local tiles = { players = makeTile(1, "PLAYERS / " .. tostring(Players.MaxPlayers)), ping = makeTile(2, "PING (ms)"), fps = makeTile(3, "FPS"), } local function setTile(tile, text, color, fraction) tile.value.Text = text tween(tile.value, 0.25, { TextColor3 = color }) tween(tile.fill, 0.35, { Size = UDim2.new(math.clamp(fraction, 0, 1), 0, 1, 0), BackgroundColor3 = color, }) end -- Info rows ---------------------------------------------------------- local rows = create("Frame", { Name = "Rows", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, LayoutOrder = 3, }, content) create("UIPadding", { PaddingTop = UDim.new(0, 10), PaddingBottom = UDim.new(0, 6), PaddingLeft = UDim.new(0, 16), PaddingRight = UDim.new(0, 16), }, rows) create("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 0), }, rows) local valueLabels = {} local function addRow(order, key, labelText, options) options = options or {} local row = create("Frame", { Name = key, BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 30), LayoutOrder = order, }, rows) create("TextLabel", { BackgroundTransparency = 1, Size = UDim2.new(0.34, 0, 1, 0), Font = Enum.Font.Gotham, Text = labelText, TextColor3 = MUTED, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, }, row) local value = create("TextButton", { BackgroundTransparency = 1, Position = UDim2.new(0.34, 0, 0, 0), Size = UDim2.new(0.66, 0, 1, 0), Font = Enum.Font.GothamMedium, Text = "...", TextColor3 = TEXT, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Right, TextTruncate = Enum.TextTruncate.AtEnd, AutoButtonColor = false, Active = options.copy ~= nil, }, row) valueLabels[key] = value if not options.last then create("Frame", { BackgroundColor3 = BORDER, BackgroundTransparency = 0.45, BorderSizePixel = 0, AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 0, 1, 0), Size = UDim2.new(1, 0, 0, 1), }, row) end -- Rows with "copy" copy their value when clicked. if options.copy then value.MouseEnter:Connect(function() tween(value, 0.12, { TextColor3 = ACCENT }) end) value.MouseLeave:Connect(function() tween(value, 0.12, { TextColor3 = TEXT }) end) value.MouseButton1Click:Connect(function() flash(value, copyToClipboard(options.copy()), 1.2) end) end end addRow(1, "Game", "Game") addRow(2, "PlaceId", "Place ID", { copy = function() return tostring(game.PlaceId) end }) addRow(3, "UniverseId", "Universe ID", { copy = function() return tostring(game.GameId) end }) addRow(4, "JobId", "Job ID", { copy = function() return game.JobId end }) addRow(5, "ServerType", "Server type") addRow(6, "ServerTime", "Server time") addRow(7, "Session", "Your session", { last = true }) -- Action buttons ----------------------------------------------------- local actions = create("Frame", { Name = "Actions", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 66), LayoutOrder = 4, }, content) create("UIPadding", { PaddingTop = UDim.new(0, 8), PaddingBottom = UDim.new(0, 16), PaddingLeft = UDim.new(0, 16), PaddingRight = UDim.new(0, 16), }, actions) create("UIListLayout", { FillDirection = Enum.FillDirection.Horizontal, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 8), }, actions) local function makeButton(order, text, filled) local button = create("TextButton", { BackgroundColor3 = filled and ACCENT or BG_DARK, Size = UDim2.new(0.5, -4, 1, 0), Font = Enum.Font.GothamBold, Text = text, TextColor3 = filled and Color3.new(0, 0, 0) or ACCENT, TextSize = 12, AutoButtonColor = false, LayoutOrder = order, }, actions) create("UICorner", { CornerRadius = UDim.new(0, 10) }, button) create("UIStroke", { Color = ACCENT, Thickness = 1 }, button) local normal = filled and ACCENT or BG_DARK local hovered = filled and ACCENT_HOVER or ACCENT_SOFT button.MouseEnter:Connect(function() tween(button, 0.15, { BackgroundColor3 = hovered }) end) button.MouseLeave:Connect(function() tween(button, 0.15, { BackgroundColor3 = normal }) end) return button end local copyJobButton = makeButton(1, "Copy Job ID", true) local copyJoinButton = makeButton(2, "Copy Join Script", false) copyJobButton.MouseButton1Click:Connect(function() flash(copyJobButton, copyToClipboard(game.JobId), 2) end) copyJoinButton.MouseButton1Click:Connect(function() local snippet = string.format( 'game:GetService("TeleportService"):TeleportToPlaceInstance(%d, "%s", game.Players.LocalPlayer)', game.PlaceId, game.JobId ) flash(copyJoinButton, copyToClipboard(snippet), 2) end) --------------------------------------------------------------------- -- Static values --------------------------------------------------------------------- local joinClock = os.clock() valueLabels.Game.Text = getGameName() valueLabels.PlaceId.Text = tostring(game.PlaceId) valueLabels.UniverseId.Text = tostring(game.GameId) valueLabels.JobId.Text = game.JobId ~= "" and game.JobId or "N/A (Studio)" local serverTypeText, serverTypeColor = getServerType() valueLabels.ServerType.Text = serverTypeText valueLabels.ServerType.TextColor3 = serverTypeColor --------------------------------------------------------------------- -- Real-time values --------------------------------------------------------------------- local minimized = false local frames, fps, lastFpsCheck = 0, 0, os.clock() local fpsMeasured = false connections[#connections + 1] = RunService.RenderStepped:Connect(function() frames += 1 local now = os.clock() if now - lastFpsCheck >= 1 then fps = frames / (now - lastFpsCheck) fpsMeasured = true frames = 0 lastFpsCheck = now end end) local function update() local count = #Players:GetPlayers() local maxPlayers = math.max(Players.MaxPlayers, 1) tiles.players.label.Text = "PLAYERS / " .. tostring(maxPlayers) setTile(tiles.players, tostring(count), ACCENT, count / maxPlayers) local ping = getPing() if ping then local color = ping < 100 and GOOD or (ping < 200 and WARN or BAD) setTile(tiles.ping, tostring(ping), color, 1 - ping / 300) else setTile(tiles.ping, "N/A", MUTED, 0) end local roundedFps = math.floor(fps + 0.5) if fpsMeasured then local color = roundedFps >= 50 and GOOD or (roundedFps >= 30 and WARN or BAD) setTile(tiles.fps, tostring(roundedFps), color, roundedFps / 60) else setTile(tiles.fps, "-", MUTED, 0) end valueLabels.ServerTime.Text = formatTime(workspace.DistributedGameTime) valueLabels.Session.Text = formatTime(os.clock() - joinClock) -- When minimized, the subtitle becomes a compact live summary. if minimized then subtitle.Text = string.format( "%d players %s %s ms %s %d FPS", count, BULLET, ping and tostring(ping) or "N/A", BULLET, roundedFps ) else subtitle.Text = "Server Information" end end update() local elapsed = 0 connections[#connections + 1] = RunService.Heartbeat:Connect(function(dt) elapsed += dt if elapsed < 0.5 then return end elapsed = 0 update() end) --------------------------------------------------------------------- -- Minimize / close --------------------------------------------------------------------- local expandedHeight = 0 local function setMinimized(state) if state == minimized then return end minimized = state minimizeButton.Text = state and PLUS or MINUS if state then expandedHeight = content.AbsoluteSize.Y content.AutomaticSize = Enum.AutomaticSize.None content.Size = UDim2.new(1, 0, 0, expandedHeight) tween(content, 0.25, { Size = UDim2.new(1, 0, 0, 0) }, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut) else local expand = tween(content, 0.25, { Size = UDim2.new(1, 0, 0, expandedHeight) }, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut) expand.Completed:Connect(function() if not minimized then content.AutomaticSize = Enum.AutomaticSize.Y end end) end update() end minimizeButton.MouseButton1Click:Connect(function() setMinimized(not minimized) end) closeButton.MouseButton1Click:Connect(function() for _, connection in ipairs(connections) do connection:Disconnect() end local closing = tween(scale, 0.15, { Scale = 0.9 }, Enum.EasingStyle.Quad, Enum.EasingDirection.In) closing.Completed:Connect(function() screenGui:Destroy() end) end) --------------------------------------------------------------------- -- Drag --------------------------------------------------------------------- local dragging = false local dragStart, startPosition header.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPosition = main.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) connections[#connections + 1] = UserInputService.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart main.Position = UDim2.new( startPosition.X.Scale, startPosition.X.Offset + delta.X, startPosition.Y.Scale, startPosition.Y.Offset + delta.Y ) end end)