local players = game:GetService("Players") local player = players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") local logService = game:GetService("LogService") local userInputService = game:GetService("UserInputService") local runService = game:GetService("RunService") local tweenService = game:GetService("TweenService") local httpService = game:GetService("HttpService") -- Constants local maxLogEntries = 250 local logThrottleTime = 0.1 local font = Font.new("rbxasset://fonts/families/RobotoMono.json") local touchThreshold = 10 -- pixels for touch movement detection -- Platform detection local isMobile = userInputService.TouchEnabled and not userInputService.MouseEnabled local isDesktop = userInputService.MouseEnabled and not isMobile -- UI Configuration local uiConfig = { desktop = { size = UDim2.new(0.5, 0, 0.3, 0), position = UDim2.new(0.5, 0, 0.7, 0), fontSize = 14, headerHeight = 28, scrollBarThickness = 6 }, mobile = { size = UDim2.new(0.9, 0, 0.35, 0), position = UDim2.new(0.5, 0, 0.8, 0), fontSize = 16, headerHeight = 36, scrollBarThickness = 10 } } local currentConfig = isMobile and uiConfig.mobile or uiConfig.desktop -- Colors local colors = { info = Color3.fromRGB(240, 240, 240), warning = Color3.fromRGB(255, 220, 100), error = Color3.fromRGB(255, 100, 100), debug = Color3.fromRGB(100, 220, 255), system = Color3.fromRGB(180, 180, 255), success = Color3.fromRGB(100, 255, 100), background = Color3.fromRGB(30, 30, 35), header = Color3.fromRGB(40, 40, 50) } -- Wait for game to load if not game:IsLoaded() then game.Loaded:Wait() end -- Cleanup previous UI if playerGui:FindFirstChild("LogUI") then playerGui.LogUI:Destroy() end -- UI Setup local function createLogUI() local screenGui = Instance.new("ScreenGui") screenGui.Name = "LogUI" screenGui.ResetOnSpawn = false screenGui.IgnoreGuiInset = true screenGui.DisplayOrder = 999 screenGui.Parent = playerGui -- Main container local mainFrame = Instance.new("Frame") mainFrame.Name = "MainFrame" mainFrame.AnchorPoint = Vector2.new(0.5, 0.5) mainFrame.Position = currentConfig.position mainFrame.Size = currentConfig.size mainFrame.BackgroundColor3 = colors.background mainFrame.BackgroundTransparency = 0.3 mainFrame.Parent = screenGui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 8) corner.Parent = mainFrame -- Header local header = Instance.new("Frame") header.Name = "Header" header.Size = UDim2.new(1, 0, 0, currentConfig.headerHeight) header.BackgroundColor3 = colors.header header.BackgroundTransparency = 0.2 header.Parent = mainFrame local headerCorner = Instance.new("UICorner") headerCorner.CornerRadius = UDim.new(0, 8) headerCorner.Parent = header local title = Instance.new("TextLabel") title.Name = "Title" title.Size = UDim2.new(1, -40, 1, 0) title.Position = UDim2.new(0, 10, 0, 0) title.Text = "System Logs" title.TextColor3 = Color3.fromRGB(220, 220, 220) title.FontFace = font title.TextSize = currentConfig.fontSize title.TextXAlignment = Enum.TextXAlignment.Left title.BackgroundTransparency = 1 title.Parent = header -- Close button local closeButton = Instance.new("TextButton") closeButton.Name = "CloseButton" closeButton.Size = UDim2.new(0, currentConfig.headerHeight - 8, 0, currentConfig.headerHeight - 8) closeButton.Position = UDim2.new(1, -currentConfig.headerHeight, 0.5, 0) closeButton.AnchorPoint = Vector2.new(0, 0.5) closeButton.Text = "×" closeButton.TextColor3 = Color3.fromRGB(220, 220, 220) closeButton.TextSize = currentConfig.fontSize + 4 closeButton.FontFace = font closeButton.BackgroundTransparency = 0.7 closeButton.BackgroundColor3 = Color3.fromRGB(80, 80, 80) closeButton.Parent = header local closeCorner = Instance.new("UICorner") closeCorner.CornerRadius = UDim.new(1, 0) closeCorner.Parent = closeButton -- Log container local logContainer = Instance.new("ScrollingFrame") logContainer.Name = "LogContainer" logContainer.Size = UDim2.new(1, -8, 1, -currentConfig.headerHeight - 8) logContainer.Position = UDim2.new(0, 4, 0, currentConfig.headerHeight + 4) logContainer.BackgroundTransparency = 1 logContainer.BorderSizePixel = 0 logContainer.ScrollBarThickness = currentConfig.scrollBarThickness logContainer.ScrollBarImageColor3 = Color3.fromRGB(100, 100, 100) logContainer.CanvasSize = UDim2.new(0, 0, 0, 0) logContainer.AutomaticCanvasSize = Enum.AutomaticSize.Y logContainer.ScrollingDirection = Enum.ScrollingDirection.Y logContainer.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar logContainer.Parent = mainFrame local layout = Instance.new("UIListLayout") layout.Padding = UDim.new(0, 6) layout.SortOrder = Enum.SortOrder.LayoutOrder layout.Parent = logContainer local padding = Instance.new("UIPadding") padding.PaddingTop = UDim.new(0, 4) padding.PaddingBottom = UDim.new(0, 4) padding.PaddingLeft = UDim.new(0, 4) padding.PaddingRight = UDim.new(0, 4) padding.Parent = logContainer -- Interaction handling local dragging = false local dragStartPos, frameStartPos local touchStartPos, touchStartTime local function handleDragStart(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStartPos = input.Position frameStartPos = mainFrame.Position if isMobile then touchStartPos = input.Position touchStartTime = os.clock() end local connection connection = input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false if connection then connection:Disconnect() end end end) end end local function isTap(input) if not isMobile then return false end local duration = os.clock() - touchStartTime local distance = (input.Position - touchStartPos).Magnitude return duration < 0.3 and distance < touchThreshold end header.InputBegan:Connect(handleDragStart) userInputService.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then if isMobile and isTap(input) then return end local delta = input.Position - dragStartPos mainFrame.Position = UDim2.new( frameStartPos.X.Scale, frameStartPos.X.Offset + delta.X, frameStartPos.Y.Scale, frameStartPos.Y.Offset + delta.Y ) end end) -- Close button functionality local function toggleUI() screenGui.Enabled = not screenGui.Enabled local tween = tweenService:Create( closeButton, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {BackgroundTransparency = screenGui.Enabled and 0.7 or 0.3} ) tween:Play() end closeButton.Activated:Connect(toggleUI) -- Performance optimization local logEntries = {} local lastLogTime = 0 local logQueue = {} local function cleanupOldLogs() while #logEntries > maxLogEntries do local oldest = table.remove(logEntries, 1) if oldest then oldest:Destroy() end end end local function addLog(message, logType, timestamp) timestamp = timestamp or os.time() local logFrame = Instance.new("Frame") logFrame.BackgroundColor3 = Color3.fromRGB(40, 40, 45) logFrame.BackgroundTransparency = 0.2 logFrame.Size = UDim2.new(1, -8, 0, 0) logFrame.AutomaticSize = Enum.AutomaticSize.Y logFrame.LayoutOrder = timestamp logFrame.Parent = logContainer lofFrame.Name = "Template" local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 4) corner.Parent = logFrame local padding = Instance.new("UIPadding") padding.PaddingTop = UDim.new(0, isMobile and 8 or 6) padding.PaddingBottom = UDim.new(0, isMobile and 8 or 6) padding.PaddingLeft = UDim.new(0, isMobile and 12 or 8) padding.PaddingRight = UDim.new(0, isMobile and 12 or 8) padding.Parent = logFrame -- Type indicator local typeIndicator = Instance.new("Frame") typeIndicator.Size = UDim2.new(0, isMobile and 6 or 4, 1, 0) typeIndicator.BackgroundColor3 = colors[logType] or colors.info typeIndicator.BorderSizePixel = 0 typeIndicator.Parent = logFrame typeIndicator.Name = "VerticalBar" -- Timestamp local timeText = Instance.new("TextLabel") timeText.Size = UDim2.new(0, isMobile and 70 or 60, 0, isMobile and 20 or 16) timeText.Position = UDim2.new(0, isMobile and 16 or 12, 0, isMobile and 8 or 6) timeText.Text = os.date("%H:%M:%S", timestamp) timeText.TextColor3 = Color3.fromRGB(150, 150, 150) timeText.FontFace = font timeText.TextSize = isMobile and currentConfig.fontSize - 2 or currentConfig.fontSize - 2 timeText.TextXAlignment = Enum.TextXAlignment.Left timeText.BackgroundTransparency = 1 timeText.Parent = logFrame timeText.Name = "Timestamp" -- Message local label = Instance.new("TextLabel") label.Size = UDim2.new(1, isMobile and -90 or -80, 0, 0) label.Position = UDim2.new(0, isMobile and 90 or 80, 0, isMobile and 8 or 6) label.Text = message label.TextColor3 = colors[logType] or colors.info label.FontFace = font label.TextSize = currentConfig.fontSize label.TextXAlignment = Enum.TextXAlignment.Left label.TextYAlignment = Enum.TextYAlignment.Top label.TextWrapped = true label.AutomaticSize = Enum.AutomaticSize.Y label.BackgroundTransparency = 1 label.Parent = logFrame labal.Name = "Message" table.insert(logEntries, logFrame) cleanupOldLogs() if logContainer.CanvasPosition.Y >= logContainer.CanvasSize.Y.Offset - logContainer.AbsoluteSize.Y - 20 then runService.Heartbeat:Wait() logContainer.CanvasPosition = Vector2.new(0, logContainer.CanvasSize.Y.Offset) end end local function processLogQueue() while true do local now = os.clock() if #logQueue > 0 and now - lastLogTime >= logThrottleTime then local log = table.remove(logQueue, 1) addLog(log.message, log.logType, log.timestamp) lastLogTime = now end task.wait(logThrottleTime) end end task.spawn(processLogQueue) return { screenGui = screenGui, addLog = function(message, logType, timestamp) table.insert(logQueue, { message = message, logType = logType or "info", timestamp = timestamp or os.time() }) end } end -- Initialize the UI local logUI = createLogUI() -- Handle incoming log messages local typeMap = { [Enum.MessageType.MessageOutput] = "info", [Enum.MessageType.MessageInfo] = "info", [Enum.MessageType.MessageWarning] = "warning", [Enum.MessageType.MessageError] = "error" } logService.MessageOut:Connect(function(message, messageType) logUI.addLog(message, typeMap[messageType] or "info") end) -- Export API local logs = {} logs.log = function(message, logType) logUI.addLog(message, logType or "info") end logs.info = function(message) logUI.addLog(message, "info") end logs.warn = function(message) logUI.addLog(message, "warning") end logs.error = function(message) logUI.addLog(message, "error") end logs.success = function(message) logUI.addLog(message, "success") end logs.system = function(message) logUI.addLog("[System] " .. message, "system") end -- Mobile specific functions if isMobile then logs.show = function() logUI.screenGui.Enabled = true end logs.hide = function() logUI.screenGui.Enabled = false end logs.toggle = function() logUI.screenGui.Enabled = not logUI.screenGui.Enabled end end return logs