-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[ VeryVare Player Manager | Obsidian Minimal | v1.2 One LocalScript. Place in StarterPlayerScripts or StarterGui. No external modules, no keybinds, no remote assets required for icons. Notes: - Spectate is a client-side camera feature. - Teleport uses the local character's CFrame. A game's server rules or anti-cheat may reject or revert the move. - Stick Behind follows a target each frame and may likewise be limited by a game's server-side movement checks. - Clipboard APIs are optional. In standard Roblox, a selectable textbox is shown so the player can copy manually. ]] local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local TweenService = game:GetService("TweenService") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") local localPlayer = Players.LocalPlayer if not localPlayer then warn("[VeryVare] This script must run on the client.") return end local playerGui = localPlayer:WaitForChild("PlayerGui") local priorGui = playerGui:FindFirstChild("VeryVare_PlayerManager") if priorGui then priorGui:Destroy() end local C = { bg = Color3.fromRGB(12, 13, 16), sidebar = Color3.fromRGB(17, 18, 22), panel = Color3.fromRGB(24, 26, 30), hover = Color3.fromRGB(32, 35, 40), selected = Color3.fromRGB(43, 46, 52), border = Color3.fromRGB(50, 53, 60), text = Color3.fromRGB(242, 243, 245), muted = Color3.fromRGB(151, 155, 165), subtle = Color3.fromRGB(105, 111, 123), white = Color3.fromRGB(255, 255, 255), green = Color3.fromRGB(118, 216, 169), red = Color3.fromRGB(242, 134, 143), } local state = { selected = nil, spectating = nil, stickTarget = nil, stickDistance = 1.8, tab = "Players", minimized = false, compact = false, sortDistance = false, showCoordinates = false, reduceMotion = false, guiScale = 1, search = "", alive = true, } local connections = {} local thumbCache = {} local function bind(signal, callback) local connection = signal:Connect(callback) table.insert(connections, connection) return connection end local function make(className, properties, parent) local object = Instance.new(className) for key, value in pairs(properties or {}) do object[key] = value end if parent then object.Parent = parent end return object end local function corner(object, radius) make("UICorner", {CornerRadius = UDim.new(0, radius or 8)}, object) end local function outline(object, color, transparency) return make("UIStroke", { Color = color or C.border, Thickness = 1, Transparency = transparency or 0, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, }, object) end local function label(parent, text, position, size, font, textSize, color, align) return make("TextLabel", { BackgroundTransparency = 1, Text = text, Position = position, Size = size, Font = font or Enum.Font.Gotham, TextSize = textSize or 14, TextColor3 = color or C.text, TextXAlignment = align or Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, }, parent) end local function button(parent, text, position, size, accent) local b = make("TextButton", { AutoButtonColor = false, Text = text, Position = position, Size = size, BackgroundColor3 = accent and C.text or C.hover, BorderSizePixel = 0, TextColor3 = accent and C.bg or C.text, Font = Enum.Font.GothamMedium, TextSize = 12, }, parent) corner(b, 8) outline(b, accent and C.text or C.border, accent and 1 or 0.45) b.MouseEnter:Connect(function() if state.alive then b.BackgroundColor3 = accent and C.white or C.selected end end) b.MouseLeave:Connect(function() if state.alive then b.BackgroundColor3 = accent and C.text or C.hover end end) return b end -- Icons are drawn with GUI primitives (not emoji, no external image IDs). local function icon(parent, kind, position, color) local holder = make("Frame", { BackgroundTransparency = 1, Position = position, Size = UDim2.fromOffset(20, 20), }, parent) color = color or C.muted local function line(x, y, w, h, angle) local f = make("Frame", { BackgroundColor3 = color, BorderSizePixel = 0, Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(w, h), Rotation = angle or 0, }, holder) corner(f, 3) end local function ring(x, y, w, h) local f = make("Frame", { BackgroundTransparency = 1, Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(w, h), }, holder) corner(f, math.max(w, h)) make("UIStroke", {Color = color, Thickness = 1.6}, f) end if kind == "users" then ring(5, 2, 9, 9) line(2, 14, 16, 2) line(4, 12, 12, 2) elseif kind == "settings" then ring(4, 4, 12, 12) ring(8, 8, 4, 4) line(9, 0, 2, 4) line(9, 16, 2, 4) line(0, 9, 4, 2) line(16, 9, 4, 2) elseif kind == "info" then ring(2, 2, 16, 16) line(9, 8, 2, 7) ring(9, 5, 2, 2) elseif kind == "search" then ring(2, 2, 12, 12) line(12, 13, 8, 2, 45) elseif kind == "resize" then line(9, 16, 10, 2, -45) line(13, 17, 7, 2, -45) else ring(3, 3, 14, 14) end return holder end local gui = make("ScreenGui", { Name = "VeryVare_PlayerManager", ResetOnSpawn = false, IgnoreGuiInset = true, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 50, }, playerGui) local main = make("Frame", { Name = "Window", AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(940, 620), BackgroundColor3 = C.bg, BorderSizePixel = 0, ClipsDescendants = true, }, gui) corner(main, 14) outline(main, C.border, 0.15) local uiScale = make("UIScale", {Scale = 1}, main) local expandedWidth, expandedHeight = 940, 620 local function adaptScale() local camera = Workspace.CurrentCamera if not camera then return end local viewport = camera.ViewportSize -- Keep the same visual scale when minimized; the small bar must not grow. local fit = math.min(1, viewport.X / (expandedWidth + 70), viewport.Y / (expandedHeight + 75)) uiScale.Scale = math.clamp(fit * state.guiScale, 0.48, 1.3) end adaptScale() local top = make("Frame", { Size = UDim2.new(1, 0, 0, 58), BackgroundColor3 = C.sidebar, BorderSizePixel = 0, }, main) label(top, "VERYVARE", UDim2.fromOffset(21, 11), UDim2.fromOffset(180, 20), Enum.Font.GothamBold, 16) label(top, "PLAYER MANAGER / OBSIDIAN", UDim2.fromOffset(22, 34), UDim2.fromOffset(250, 13), Enum.Font.GothamMedium, 9, C.muted) make("Frame", {Position = UDim2.new(0, 0, 1, -1), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = C.border, BorderSizePixel = 0}, top) local minimizeButton = button(top, "−", UDim2.new(1, -86, 0, 13), UDim2.fromOffset(30, 30)) minimizeButton.TextSize = 22 local closeButton = button(top, "×", UDim2.new(1, -48, 0, 13), UDim2.fromOffset(30, 30)) closeButton.TextSize = 20 local sidebar = make("Frame", { Position = UDim2.fromOffset(0, 58), Size = UDim2.new(0, 185, 1, -58), BackgroundColor3 = C.sidebar, BorderSizePixel = 0, }, main) make("Frame", {Position = UDim2.new(1, -1, 0, 0), Size = UDim2.new(0, 1, 1, 0), BackgroundColor3 = C.border, BorderSizePixel = 0}, sidebar) label(sidebar, "NAVIGATION", UDim2.fromOffset(19, 20), UDim2.fromOffset(130, 18), Enum.Font.GothamBold, 10, C.subtle) local sidebarButtons = {} for i, tabName in ipairs({"Players", "Settings", "About"}) do local nav = make("TextButton", { Text = "", AutoButtonColor = false, Position = UDim2.fromOffset(13, 52 + (i - 1) * 49), Size = UDim2.new(1, -26, 0, 40), BackgroundColor3 = C.sidebar, BorderSizePixel = 0, }, sidebar) corner(nav, 8) icon(nav, tabName == "Players" and "users" or (tabName == "Settings" and "settings" or "info"), UDim2.fromOffset(14, 10)) label(nav, tabName, UDim2.fromOffset(46, 1), UDim2.new(1, -52, 1, -2), Enum.Font.GothamMedium, 13, C.text) sidebarButtons[tabName] = nav nav.MouseEnter:Connect(function() if state.alive and state.tab ~= tabName then nav.BackgroundColor3 = C.hover end end) nav.MouseLeave:Connect(function() if state.alive then nav.BackgroundColor3 = state.tab == tabName and C.selected or C.sidebar end end) end label(sidebar, "Made by VeryVare", UDim2.new(0, 19, 1, -53), UDim2.new(1, -30, 0, 19), Enum.Font.GothamMedium, 11, C.muted) label(sidebar, "LOCAL SCRIPT • V1.2", UDim2.new(0, 19, 1, -34), UDim2.new(1, -30, 0, 16), Enum.Font.Gotham, 9, C.subtle) local content = make("Frame", { Position = UDim2.fromOffset(185, 58), Size = UDim2.new(1, -185, 1, -58), BackgroundTransparency = 1, }, main) local pages = {} for _, tabName in ipairs({"Players", "Settings", "About"}) do pages[tabName] = make("Frame", { Name = tabName, Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = tabName == "Players", }, content) end local function showTab(name) state.tab = name for tabName, page in pairs(pages) do page.Visible = tabName == name sidebarButtons[tabName].BackgroundColor3 = tabName == name and C.selected or C.sidebar end end for tabName, nav in pairs(sidebarButtons) do nav.MouseButton1Click:Connect(function() showTab(tabName) end) end showTab("Players") local playersPage = pages.Players label(playersPage, "Players", UDim2.fromOffset(24, 18), UDim2.fromOffset(280, 31), Enum.Font.GothamBold, 23) label(playersPage, "Manage, inspect and spectate players in this server.", UDim2.fromOffset(24, 49), UDim2.new(1, -50, 0, 18), Enum.Font.Gotham, 11, C.muted) local playerCount = label(playersPage, "0 ONLINE", UDim2.new(1, -122, 0, 24), UDim2.fromOffset(105, 24), Enum.Font.GothamBold, 10, C.green, Enum.TextXAlignment.Right) local searchContainer = make("Frame", { Position = UDim2.fromOffset(24, 79), Size = UDim2.fromOffset(294, 38), BackgroundColor3 = C.panel, BorderSizePixel = 0, }, playersPage) corner(searchContainer, 8) outline(searchContainer) icon(searchContainer, "search", UDim2.fromOffset(12, 9)) local searchBox = make("TextBox", { Position = UDim2.fromOffset(42, 2), Size = UDim2.new(1, -50, 1, -4), BackgroundTransparency = 1, Text = "", PlaceholderText = "Search name or username...", PlaceholderColor3 = C.subtle, ClearTextOnFocus = false, TextColor3 = C.text, Font = Enum.Font.Gotham, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, }, searchContainer) local sortButton = button(playersPage, "SORT: NAME", UDim2.fromOffset(338, 79), UDim2.fromOffset(128, 38)) local refreshButton = button(playersPage, "REFRESH", UDim2.fromOffset(476, 79), UDim2.fromOffset(100, 38)) local listPanel = make("Frame", { Position = UDim2.fromOffset(24, 127), Size = UDim2.new(0, 294, 1, -150), BackgroundColor3 = C.panel, BorderSizePixel = 0, }, playersPage) corner(listPanel, 10) outline(listPanel) local listScroll = make("ScrollingFrame", { Position = UDim2.fromOffset(9, 9), Size = UDim2.new(1, -18, 1, -18), BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = C.subtle, CanvasSize = UDim2.fromOffset(0, 0), AutomaticCanvasSize = Enum.AutomaticSize.None, }, listPanel) local listLayout = make("UIListLayout", { Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder, }, listScroll) bind(listLayout:GetPropertyChangedSignal("AbsoluteContentSize"), function() listScroll.CanvasSize = UDim2.fromOffset(0, listLayout.AbsoluteContentSize.Y + 8) end) local detailPanel = make("Frame", { Position = UDim2.fromOffset(330, 127), Size = UDim2.new(1, -354, 1, -150), BackgroundColor3 = C.panel, BorderSizePixel = 0, }, playersPage) corner(detailPanel, 10) outline(detailPanel) local emptyTitle = label(detailPanel, "No player selected", UDim2.new(0, 10, 0.5, -26), UDim2.new(1, -20, 0, 24), Enum.Font.GothamBold, 17, C.text, Enum.TextXAlignment.Center) local emptySubtitle = label(detailPanel, "Choose someone from the player list.", UDim2.new(0, 10, 0.5, 2), UDim2.new(1, -20, 0, 20), Enum.Font.Gotham, 11, C.muted, Enum.TextXAlignment.Center) local detailContent = make("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = false}, detailPanel) local selectedAvatar = make("ImageLabel", {Position = UDim2.fromOffset(18, 20), Size = UDim2.fromOffset(64, 64), BackgroundColor3 = C.hover, BorderSizePixel = 0, Image = ""}, detailContent) corner(selectedAvatar, 10) local selectedName = label(detailContent, "", UDim2.fromOffset(96, 27), UDim2.new(1, -110, 0, 27), Enum.Font.GothamBold, 18) local selectedUsername = label(detailContent, "", UDim2.fromOffset(96, 56), UDim2.new(1, -110, 0, 20), Enum.Font.Gotham, 12, C.muted) make("Frame", {Position = UDim2.fromOffset(18, 101), Size = UDim2.new(1, -36, 0, 1), BorderSizePixel = 0, BackgroundColor3 = C.border}, detailContent) local healthText = label(detailContent, "HEALTH", UDim2.fromOffset(18, 119), UDim2.fromOffset(165, 19), Enum.Font.GothamMedium, 10, C.muted) local healthValue = label(detailContent, "—", UDim2.new(1, -110, 0, 119), UDim2.fromOffset(92, 19), Enum.Font.GothamMedium, 11, C.text, Enum.TextXAlignment.Right) local healthTrack = make("Frame", {Position = UDim2.fromOffset(18, 145), Size = UDim2.new(1, -36, 0, 7), BorderSizePixel = 0, BackgroundColor3 = C.hover}, detailContent) corner(healthTrack, 4) local healthFill = make("Frame", {Size = UDim2.fromScale(0, 1), BorderSizePixel = 0, BackgroundColor3 = C.green}, healthTrack) corner(healthFill, 4) local function metric(y, title) label(detailContent, title, UDim2.fromOffset(18, y), UDim2.new(0.5, -18, 0, 18), Enum.Font.GothamMedium, 10, C.muted) return label(detailContent, "—", UDim2.new(0.5, 0, 0, y), UDim2.new(0.5, -18, 0, 18), Enum.Font.GothamMedium, 11, C.text, Enum.TextXAlignment.Right) end local distanceValue = metric(175, "DISTANCE") local teamValue = metric(202, "TEAM") local userIdValue = metric(229, "USER ID") local positionTitle = label(detailContent, "POSITION", UDim2.fromOffset(18, 257), UDim2.fromOffset(100, 18), Enum.Font.GothamMedium, 10, C.muted) local positionValue = label(detailContent, "—", UDim2.fromOffset(101, 257), UDim2.new(1, -119, 0, 18), Enum.Font.GothamMedium, 10, C.text, Enum.TextXAlignment.Right) positionTitle.Visible = false positionValue.Visible = false local spectateButton = button(detailContent, "SPECTATE", UDim2.new(0, 18, 1, -128), UDim2.new(0.5, -23, 0, 36), true) local unspectateButton = button(detailContent, "UNSPECTATE", UDim2.new(0.5, 5, 1, -128), UDim2.new(0.5, -23, 0, 36)) local teleportButton = button(detailContent, "TELEPORT", UDim2.new(0, 18, 1, -84), UDim2.new(0.5, -23, 0, 36)) local stickButton = button(detailContent, "STICK BEHIND", UDim2.new(0.5, 5, 1, -84), UDim2.new(0.5, -23, 0, 36)) local copyNameButton = button(detailContent, "COPY NAME", UDim2.new(0, 18, 1, -40), UDim2.new(0.5, -23, 0, 32)) local copyUserButton = button(detailContent, "COPY @USER", UDim2.new(0.5, 5, 1, -40), UDim2.new(0.5, -23, 0, 32)) -- Toast messages are contained within the window and automatically expire. local toast = make("TextLabel", { AnchorPoint = Vector2.new(0.5, 1), Position = UDim2.new(0.5, 0, 1, -15), Size = UDim2.fromOffset(340, 36), BackgroundColor3 = C.selected, BorderSizePixel = 0, TextColor3 = C.text, Font = Enum.Font.GothamMedium, TextSize = 11, Text = "", Visible = false, ZIndex = 20, }, main) corner(toast, 8) outline(toast) local toastSerial = 0 local function notify(message) if not state.alive then return end if state.minimized then return end toastSerial += 1 local thisToast = toastSerial toast.Text = tostring(message) toast.Visible = true task.delay(2.7, function() if state.alive and thisToast == toastSerial then toast.Visible = false end end) end local overlay = make("Frame", { Size = UDim2.fromScale(1, 1), BackgroundColor3 = C.bg, BackgroundTransparency = 0.25, BorderSizePixel = 0, Visible = false, ZIndex = 30, }, main) local dialog = make("Frame", { AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(365, 174), BackgroundColor3 = C.panel, BorderSizePixel = 0, ZIndex = 31, }, overlay) corner(dialog, 12) outline(dialog) local dialogTitle = label(dialog, "Unload Player Manager?", UDim2.fromOffset(20, 22), UDim2.new(1, -40, 0, 26), Enum.Font.GothamBold, 17) dialogTitle.ZIndex = 32 local dialogInfo = label(dialog, "The UI closes and your camera is restored.", UDim2.fromOffset(20, 57), UDim2.new(1, -40, 0, 19), Enum.Font.Gotham, 11, C.muted) dialogInfo.ZIndex = 32 local cancelUnload = button(dialog, "CANCEL", UDim2.fromOffset(20, 116), UDim2.fromOffset(151, 38)) local confirmUnload = button(dialog, "YES, UNLOAD", UDim2.fromOffset(184, 116), UDim2.fromOffset(160, 38), true) cancelUnload.ZIndex = 32 confirmUnload.ZIndex = 32 local copyOverlay = make("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = C.bg, BackgroundTransparency = 0.22, BorderSizePixel = 0, Visible = false, ZIndex = 35}, main) local copyDialog = make("Frame", {AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(420, 176), BackgroundColor3 = C.panel, BorderSizePixel = 0, ZIndex = 36}, copyOverlay) corner(copyDialog, 12) outline(copyDialog) local copyTitle = label(copyDialog, "Manual copy", UDim2.fromOffset(18, 15), UDim2.fromOffset(340, 24), Enum.Font.GothamBold, 16) copyTitle.ZIndex = 37 local copyHint = label(copyDialog, "Select the text and press Ctrl+C.", UDim2.fromOffset(18, 43), UDim2.fromOffset(360, 20), Enum.Font.Gotham, 11, C.muted) copyHint.ZIndex = 37 local copyBox = make("TextBox", {Position = UDim2.fromOffset(18, 76), Size = UDim2.new(1, -36, 0, 36), BackgroundColor3 = C.hover, BorderSizePixel = 0, ClearTextOnFocus = false, Text = "", TextColor3 = C.text, Font = Enum.Font.Gotham, TextSize = 12, ZIndex = 37}, copyDialog) corner(copyBox, 7) local copyClose = button(copyDialog, "DONE", UDim2.new(1, -111, 1, -50), UDim2.fromOffset(92, 32), true) copyClose.ZIndex = 37 copyClose.MouseButton1Click:Connect(function() copyOverlay.Visible = false end) local function getRoot(player) local character = player and player.Character return character and character:FindFirstChild("HumanoidRootPart") or nil end local function getHumanoid(player) local character = player and player.Character return character and character:FindFirstChildOfClass("Humanoid") or nil end local function getDistance(player) local source = getRoot(localPlayer) local destination = getRoot(player) if source and destination then return (source.Position - destination.Position).Magnitude end return math.huge end local function getThumbnail(player, imageLabel) if not player or not imageLabel then return end if thumbCache[player.UserId] then imageLabel.Image = thumbCache[player.UserId] return end task.spawn(function() local ok, image = pcall(function() return Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size100x100) end) if ok and image and state.alive then thumbCache[player.UserId] = image if imageLabel.Parent then imageLabel.Image = image end end end) end local function updateStickButton() local isSticking = state.stickTarget ~= nil stickButton.Text = isSticking and "UNSTICK" or "STICK BEHIND" stickButton.TextColor3 = isSticking and C.green or C.text end local function stopSticking(message) state.stickTarget = nil updateStickButton() if message then notify(message) end end local function stopSpectating() state.spectating = nil local camera = Workspace.CurrentCamera local humanoid = getHumanoid(localPlayer) if camera and humanoid then camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = humanoid end end local function unload() if not state.alive then return end stopSticking() stopSpectating() state.alive = false for _, connection in ipairs(connections) do connection:Disconnect() end gui:Destroy() end -- Also clean up connections if a second copy of the script replaces this GUI. bind(gui.Destroying, function() if not state.alive then return end stopSticking() stopSpectating() state.alive = false for _, connection in ipairs(connections) do connection:Disconnect() end end) confirmUnload.MouseButton1Click:Connect(unload) cancelUnload.MouseButton1Click:Connect(function() overlay.Visible = false end) local resizeHandle -- Created below; referenced by the minimize handler. local minimizeTween local function setMinimized(shouldMinimize, onFinished) if state.minimized == shouldMinimize then if onFinished then onFinished() end return end if minimizeTween then minimizeTween:Cancel() end state.minimized = shouldMinimize minimizeButton.Text = shouldMinimize and "+" or "−" local targetWidth = shouldMinimize and 380 or expandedWidth local targetHeight = shouldMinimize and 58 or expandedHeight local currentWidth = main.Size.X.Offset local currentHeight = main.Size.Y.Offset local targetPosition = UDim2.new( main.Position.X.Scale, main.Position.X.Offset + (targetWidth - currentWidth) / 2, main.Position.Y.Scale, main.Position.Y.Offset + (targetHeight - currentHeight) / 2 ) -- Hide layout elements immediately so they cannot overlap the top bar. sidebar.Visible = false content.Visible = false toast.Visible = false if resizeHandle then resizeHandle.Visible = false end local function finish() if not state.alive or state.minimized ~= shouldMinimize then return end if not shouldMinimize then sidebar.Visible = true content.Visible = true if resizeHandle then resizeHandle.Visible = true end end if onFinished then onFinished() end end if state.reduceMotion then main.Size = UDim2.fromOffset(targetWidth, targetHeight) main.Position = targetPosition finish() else minimizeTween = TweenService:Create(main, TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = UDim2.fromOffset(targetWidth, targetHeight), Position = targetPosition, }) minimizeTween.Completed:Connect(function(playbackState) if playbackState == Enum.PlaybackState.Completed then finish() end end) minimizeTween:Play() end end minimizeButton.MouseButton1Click:Connect(function() setMinimized(not state.minimized) end) closeButton.MouseButton1Click:Connect(function() if state.minimized then setMinimized(false, function() overlay.Visible = true end) else overlay.Visible = true end end) -- Window drag and corner resize; intentionally no keyboard shortcuts. local dragActive = false local dragStart local startPosition local resizeActive = false local resizeStart local startSize bind(top.InputBegan, function(input) if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end dragActive = true dragStart = input.Position startPosition = main.Position end) resizeHandle = make("TextButton", {Text = "", Position = UDim2.new(1, -25, 1, -25), Size = UDim2.fromOffset(21, 21), BackgroundTransparency = 1, AutoButtonColor = false, ZIndex = 10}, main) icon(resizeHandle, "resize", UDim2.fromOffset(0, 0), C.muted) bind(resizeHandle.InputBegan, function(input) if state.minimized then return end if input.UserInputType ~= Enum.UserInputType.MouseButton1 and input.UserInputType ~= Enum.UserInputType.Touch then return end resizeActive = true resizeStart = input.Position startSize = main.Size end) bind(UserInputService.InputChanged, function(input) if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch then return end if dragActive and dragStart and startPosition then local delta = (input.Position - dragStart) / math.max(uiScale.Scale, 0.01) main.Position = UDim2.new(startPosition.X.Scale, startPosition.X.Offset + delta.X, startPosition.Y.Scale, startPosition.Y.Offset + delta.Y) elseif resizeActive and resizeStart and startSize then local delta = (input.Position - resizeStart) / math.max(uiScale.Scale, 0.01) local width = math.clamp(startSize.X.Offset + delta.X, 820, 1130) -- Keep the three action rows and player details from overlapping. local height = math.clamp(startSize.Y.Offset + delta.Y, 620, 740) expandedWidth = width expandedHeight = height main.Size = UDim2.fromOffset(width, height) adaptScale() end end) bind(UserInputService.InputEnded, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragActive = false resizeActive = false end end) local function copyText(value) local copyFunction = (type(setclipboard) == "function" and setclipboard) or (type(toclipboard) == "function" and toclipboard) if copyFunction then local ok = pcall(copyFunction, value) if ok then notify("Copied to clipboard") return end end copyBox.Text = value copyOverlay.Visible = true task.defer(function() if not state.alive then return end copyBox:CaptureFocus() copyBox.CursorPosition = #value + 1 copyBox.SelectionStart = 1 end) end local rebuildPlayerList local setSelected local function updateSelectionDetails() local player = state.selected if not player or not player.Parent then return end local humanoid = getHumanoid(player) local root = getRoot(player) if humanoid then local hp = math.max(0, humanoid.Health) local maxHp = math.max(1, humanoid.MaxHealth) healthValue.Text = ("%d / %d"):format(math.floor(hp + 0.5), math.floor(maxHp + 0.5)) healthFill.Size = UDim2.fromScale(math.clamp(hp / maxHp, 0, 1), 1) healthFill.BackgroundColor3 = hp / maxHp < 0.3 and C.red or C.green else healthValue.Text = "Unavailable" healthFill.Size = UDim2.fromScale(0, 1) end local distance = getDistance(player) distanceValue.Text = distance == math.huge and "—" or ("%d studs"):format(math.floor(distance + 0.5)) teamValue.Text = player.Team and player.Team.Name or "No team" userIdValue.Text = tostring(player.UserId) if root then positionValue.Text = ("%.0f, %.0f, %.0f"):format(root.Position.X, root.Position.Y, root.Position.Z) else positionValue.Text = "Unavailable" end end rebuildPlayerList = function() if not state.alive then return end for _, child in ipairs(listScroll:GetChildren()) do if child:IsA("GuiObject") and child ~= listLayout then child:Destroy() end end local candidates = {} local query = string.lower(state.search) for _, player in ipairs(Players:GetPlayers()) do local searchable = string.lower(player.Name .. " " .. player.DisplayName) if query == "" or string.find(searchable, query, 1, true) then table.insert(candidates, player) end end table.sort(candidates, function(a, b) if state.sortDistance then local aDistance, bDistance = getDistance(a), getDistance(b) if aDistance ~= bDistance then return aDistance < bDistance end end return string.lower(a.DisplayName) < string.lower(b.DisplayName) end) playerCount.Text = tostring(#Players:GetPlayers()) .. " ONLINE" for index, player in ipairs(candidates) do local height = state.compact and 49 or 60 local active = state.selected == player local row = make("TextButton", { Name = "Player_" .. player.UserId, LayoutOrder = index, Size = UDim2.new(1, -3, 0, height), BackgroundColor3 = active and C.selected or C.hover, BorderSizePixel = 0, AutoButtonColor = false, Text = "", }, listScroll) corner(row, 8) if active then outline(row, C.muted, 0.3) end local avatar = make("ImageLabel", { Position = UDim2.fromOffset(9, state.compact and 7 or 10), Size = UDim2.fromOffset(state.compact and 34 or 39, state.compact and 34 or 39), BackgroundColor3 = C.selected, BorderSizePixel = 0, Image = "", }, row) corner(avatar, 7) getThumbnail(player, avatar) label(row, player.DisplayName, UDim2.fromOffset(state.compact and 52 or 58, state.compact and 7 or 11), UDim2.new(1, -65, 0, 21), Enum.Font.GothamMedium, 12) label(row, "@" .. player.Name, UDim2.fromOffset(state.compact and 52 or 58, state.compact and 26 or 33), UDim2.new(1, -65, 0, 16), Enum.Font.Gotham, 10, C.muted) row.MouseEnter:Connect(function() if state.alive and row.Parent and state.selected ~= player then row.BackgroundColor3 = C.selected end end) row.MouseLeave:Connect(function() if state.alive and row.Parent and state.selected ~= player then row.BackgroundColor3 = C.hover end end) row.MouseButton1Click:Connect(function() setSelected(player) end) end end setSelected = function(player) state.selected = player local selected = player ~= nil and player.Parent ~= nil detailContent.Visible = selected emptyTitle.Visible = not selected emptySubtitle.Visible = not selected if selected then selectedName.Text = player.DisplayName selectedUsername.Text = "@" .. player.Name selectedAvatar.Image = "" getThumbnail(player, selectedAvatar) updateSelectionDetails() end updateStickButton() rebuildPlayerList() end bind(searchBox:GetPropertyChangedSignal("Text"), function() state.search = searchBox.Text rebuildPlayerList() end) sortButton.MouseButton1Click:Connect(function() state.sortDistance = not state.sortDistance sortButton.Text = state.sortDistance and "SORT: NEAREST" or "SORT: NAME" rebuildPlayerList() end) refreshButton.MouseButton1Click:Connect(function() rebuildPlayerList() updateSelectionDetails() notify("Player list refreshed") end) spectateButton.MouseButton1Click:Connect(function() local target = state.selected if not target or not target.Parent then notify("Select an available player first") return end local humanoid = getHumanoid(target) local camera = Workspace.CurrentCamera if not humanoid or not camera then notify("Target character isn't ready") return end state.spectating = target camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = humanoid notify("Spectating " .. target.DisplayName) end) unspectateButton.MouseButton1Click:Connect(function() stopSpectating() notify("Returned to your camera") end) teleportButton.MouseButton1Click:Connect(function() local target = state.selected if not target or not target.Parent then notify("Select a player first") return end local ownRoot, targetRoot = getRoot(localPlayer), getRoot(target) if not ownRoot or not targetRoot then notify("Both characters must be spawned") return end if target == localPlayer then notify("You're already at your own position") return end if state.stickTarget then stopSticking() end local ok = pcall(function() ownRoot.CFrame = targetRoot.CFrame * CFrame.new(3, 0, 3) end) notify(ok and "Teleport requested (game rules may block it)" or "Teleport failed") end) stickButton.MouseButton1Click:Connect(function() if state.stickTarget then stopSticking("Stick Behind disabled") return end local target = state.selected if not target or not target.Parent then notify("Select a player first") return end if target == localPlayer then notify("Choose another player") return end if not getRoot(localPlayer) or not getRoot(target) then notify("Both characters must be spawned") return end state.stickTarget = target updateStickButton() notify("Sticking behind " .. target.DisplayName) end) copyNameButton.MouseButton1Click:Connect(function() if state.selected then copyText(state.selected.DisplayName) end end) copyUserButton.MouseButton1Click:Connect(function() if state.selected then copyText(state.selected.Name) end end) -- Settings: every toggle starts OFF by design. local settingsPage = pages.Settings label(settingsPage, "Settings", UDim2.fromOffset(24, 18), UDim2.fromOffset(260, 31), Enum.Font.GothamBold, 23) label(settingsPage, "Customize the interface. All toggle options start off.", UDim2.fromOffset(24, 49), UDim2.new(1, -50, 0, 18), Enum.Font.Gotham, 11, C.muted) local settingsScroll = make("ScrollingFrame", { Position = UDim2.fromOffset(24, 87), Size = UDim2.new(1, -48, 1, -109), BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = C.subtle, CanvasSize = UDim2.fromOffset(0, 0), }, settingsPage) local settingsLayout = make("UIListLayout", {Padding = UDim.new(0, 10), SortOrder = Enum.SortOrder.LayoutOrder}, settingsScroll) bind(settingsLayout:GetPropertyChangedSignal("AbsoluteContentSize"), function() settingsScroll.CanvasSize = UDim2.fromOffset(0, settingsLayout.AbsoluteContentSize.Y + 10) end) local settingControls = {} local settingOrder = 0 local function addToggle(title, description, property, callback) settingOrder += 1 local container = make("Frame", {Size = UDim2.new(1, -9, 0, 76), BackgroundColor3 = C.panel, BorderSizePixel = 0, LayoutOrder = settingOrder}, settingsScroll) corner(container, 9) outline(container) label(container, title, UDim2.fromOffset(16, 15), UDim2.new(1, -115, 0, 22), Enum.Font.GothamMedium, 13) label(container, description, UDim2.fromOffset(16, 42), UDim2.new(1, -115, 0, 19), Enum.Font.Gotham, 10, C.muted) local toggle = button(container, "OFF", UDim2.new(1, -79, 0.5, -15), UDim2.fromOffset(60, 30)) local function refresh() toggle.Text = state[property] and "ON" or "OFF" toggle.BackgroundColor3 = state[property] and C.selected or C.hover end toggle.MouseButton1Click:Connect(function() state[property] = not state[property] refresh() if callback then callback() end end) settingControls[property] = refresh refresh() end addToggle("Compact player rows", "Fit more players in the list.", "compact", rebuildPlayerList) addToggle("Sort by distance", "Show nearby players first.", "sortDistance", function() sortButton.Text = state.sortDistance and "SORT: NEAREST" or "SORT: NAME" rebuildPlayerList() end) addToggle("Show coordinates", "Display selected player's XYZ position.", "showCoordinates", function() positionTitle.Visible = state.showCoordinates positionValue.Visible = state.showCoordinates end) addToggle("Reduce animations", "Use instant transitions for window controls.", "reduceMotion") local scalePanel = make("Frame", {Size = UDim2.new(1, -9, 0, 74), BackgroundColor3 = C.panel, BorderSizePixel = 0, LayoutOrder = 5}, settingsScroll) corner(scalePanel, 9) outline(scalePanel) label(scalePanel, "Interface scale", UDim2.fromOffset(16, 13), UDim2.new(1, -160, 0, 22), Enum.Font.GothamMedium, 13) label(scalePanel, "Make the entire menu bigger or smaller.", UDim2.fromOffset(16, 39), UDim2.new(1, -180, 0, 19), Enum.Font.Gotham, 10, C.muted) local scaleDown = button(scalePanel, "−", UDim2.new(1, -149, 0, 20), UDim2.fromOffset(33, 33)) local scaleValue = label(scalePanel, "100%", UDim2.new(1, -108, 0, 20), UDim2.fromOffset(58, 33), Enum.Font.GothamBold, 12, C.text, Enum.TextXAlignment.Center) local scaleUp = button(scalePanel, "+", UDim2.new(1, -44, 0, 20), UDim2.fromOffset(33, 33)) local function changeScale(change) state.guiScale = math.clamp(state.guiScale + change, 0.7, 1.2) scaleValue.Text = tostring(math.floor(state.guiScale * 100 + 0.5)) .. "%" adaptScale() end scaleDown.MouseButton1Click:Connect(function() changeScale(-0.1) end) scaleUp.MouseButton1Click:Connect(function() changeScale(0.1) end) local stickDistancePanel = make("Frame", {Size = UDim2.new(1, -9, 0, 74), BackgroundColor3 = C.panel, BorderSizePixel = 0, LayoutOrder = 6}, settingsScroll) corner(stickDistancePanel, 9) outline(stickDistancePanel) label(stickDistancePanel, "Stick Behind distance", UDim2.fromOffset(16, 13), UDim2.new(1, -185, 0, 22), Enum.Font.GothamMedium, 13) label(stickDistancePanel, "Adjust how closely you follow a player.", UDim2.fromOffset(16, 39), UDim2.new(1, -185, 0, 19), Enum.Font.Gotham, 10, C.muted) local stickDistanceDown = button(stickDistancePanel, "−", UDim2.new(1, -179, 0, 20), UDim2.fromOffset(33, 33)) local stickDistanceValue = label(stickDistancePanel, "1.8 studs", UDim2.new(1, -140, 0, 20), UDim2.fromOffset(88, 33), Enum.Font.GothamBold, 11, C.text, Enum.TextXAlignment.Center) local stickDistanceUp = button(stickDistancePanel, "+", UDim2.new(1, -44, 0, 20), UDim2.fromOffset(33, 33)) local function changeStickDistance(delta) state.stickDistance = math.clamp(math.round((state.stickDistance + delta) * 10) / 10, 1.2, 5) stickDistanceValue.Text = ("%.1f studs"):format(state.stickDistance) end stickDistanceDown.MouseButton1Click:Connect(function() changeStickDistance(-0.2) end) stickDistanceUp.MouseButton1Click:Connect(function() changeStickDistance(0.2) end) local resetButton = button(settingsScroll, "RESET SETTINGS & WINDOW POSITION", UDim2.fromOffset(0, 0), UDim2.new(1, -9, 0, 39)) resetButton.LayoutOrder = 7 resetButton.MouseButton1Click:Connect(function() stopSticking() state.compact = false state.sortDistance = false state.showCoordinates = false state.reduceMotion = false state.guiScale = 1 state.stickDistance = 1.8 positionTitle.Visible = false positionValue.Visible = false sortButton.Text = "SORT: NAME" for _, update in pairs(settingControls) do update() end scaleValue.Text = "100%" stickDistanceValue.Text = "1.8 studs" if minimizeTween then minimizeTween:Cancel() end expandedWidth, expandedHeight = 940, 620 state.minimized = false minimizeButton.Text = "−" sidebar.Visible = true content.Visible = true resizeHandle.Visible = true main.Size = UDim2.fromOffset(940, 620) main.Position = UDim2.fromScale(0.5, 0.5) adaptScale() rebuildPlayerList() notify("Settings reset to defaults") end) local aboutPage = pages.About label(aboutPage, "About", UDim2.fromOffset(24, 18), UDim2.fromOffset(260, 31), Enum.Font.GothamBold, 23) label(aboutPage, "VeryVare Player Manager / Version 1.2", UDim2.fromOffset(24, 51), UDim2.new(1, -48, 0, 18), Enum.Font.Gotham, 12, C.muted) local aboutPanel = make("Frame", {Position = UDim2.fromOffset(24, 90), Size = UDim2.new(1, -48, 0, 260), BackgroundColor3 = C.panel, BorderSizePixel = 0}, aboutPage) corner(aboutPanel, 10) outline(aboutPanel) local aboutLines = { "• Live player list with name and username search", "• Selected player health, team, distance and position", "• Spectate / unspectate and local teleport request", "• Stick Behind mode with adjustable follow distance", "• Optional clipboard support with manual-copy fallback", "• Draggable and resizable window with no keybindings", "• Close button opens an unload confirmation", } for i, text in ipairs(aboutLines) do label(aboutPanel, text, UDim2.fromOffset(20, 15 + (i - 1) * 36), UDim2.new(1, -40, 0, 22), Enum.Font.Gotham, 12, C.text) end label(aboutPage, "Built by VeryVare Studio", UDim2.fromOffset(24, 367), UDim2.new(1, -48, 0, 24), Enum.Font.GothamMedium, 12, C.muted) bind(Players.PlayerAdded, function() rebuildPlayerList() end) bind(Players.PlayerRemoving, function(player) if state.stickTarget == player then stopSticking("Target player left the server") end if state.spectating == player then stopSpectating() end if state.selected == player then setSelected(nil) end task.defer(rebuildPlayerList) end) bind(localPlayer.CharacterAdded, function() if state.stickTarget then stopSticking("Stick Behind stopped after respawn") end end) local updateClock = 0 bind(RunService.Heartbeat, function(delta) -- This must run every frame; the UI statistics below are throttled. if state.stickTarget then local target = state.stickTarget if not target.Parent then stopSticking("Target player left the server") else local ownRoot, targetRoot = getRoot(localPlayer), getRoot(target) local ownHumanoid = getHumanoid(localPlayer) if ownRoot and targetRoot and ownHumanoid and ownHumanoid.Health > 0 then local ok = pcall(function() -- A positive local Z offset stays BEHIND the target's facing direction. ownRoot.CFrame = targetRoot.CFrame * CFrame.new(0, 0, state.stickDistance) ownRoot.AssemblyLinearVelocity = targetRoot.AssemblyLinearVelocity ownRoot.AssemblyAngularVelocity = Vector3.zero end) if not ok then stopSticking("Stick Behind could not continue") end end end end updateClock += delta if updateClock < 0.35 then return end updateClock = 0 updateSelectionDetails() adaptScale() if state.spectating then if not state.spectating.Parent then stopSpectating() else local targetHumanoid = getHumanoid(state.spectating) local camera = Workspace.CurrentCamera if targetHumanoid and camera and camera.CameraSubject ~= targetHumanoid then camera.CameraType = Enum.CameraType.Custom camera.CameraSubject = targetHumanoid end end end end) rebuildPlayerList() notify("VeryVare Player Manager loaded")