M
Description
The Player Manager is a sleek Roblox GUI featuring player tracking, spectate, teleport, Stick Behind, player information, and customizable settings—all in a modern, draggable, and resizable interface.
GAMEUniversal
UPDATEDNov 2, 2026
ACCESSKeyless
PLATFORMDesktop
Script source Luau
-- [[ BloxScripts Risk Notice ]]
-- This script has not been verified by BloxScripts.fun. 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 BloxScripts 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")
Review the source before using it. Executions count successful copies, capped at 10 per user and network per script in 24 hours.
Community discussion
0Start the conversation.


Your community, in one place