Universal Script – persistence.win universal (Keyless) - Verified script for Universal Roblox
Key RequiredUniversal

Universal Script – persistence.win universal (Keyless)

Universal Scriptpersistencepersistence 3K views 9.2K executesUpdated Oct 21, 2026
Unrated
00
Lua Script•2502 lines (78745 chars)
-- persistence.win — Universal Script v2.1
-- join to suggest: discord.gg/MU4W3uPf9p
-- credits to ai

--[[
    ═══════════════════════════════════════════════════════════════
    persistence.win — Universal Hub v2.1
    Memory-leak audited & patched build
    
    Linoria UI Library
    
    Features: Fly, Aimbot, Noclip, ESP (Player + NPC), Instant Stop,
    Custom Gravity, Slope Angle, No Void, Float Platform, Waypoints,
    SpawnLocation TP, CFrame Copy, Face North, TP Tool, Latch,
    Spectate + Beam Tracer, Low HP Tracker, Death Logger,
    Potato Graphics, Instance Path Evaluator, Activity Logger,
    Script Launchers, Workspace Scanner, Performance Tracker,
    Sound Customization, Telemetry, Config/Theme Manager
    ═══════════════════════════════════════════════════════════════
    
    join to suggest: discord.gg/MU4W3uPf9p
    credits to ai
]]

-- ============================================================
-- SERVICES
-- ============================================================
local Players            = game:GetService("Players")
local RunService         = game:GetService("RunService")
local UserInputService   = game:GetService("UserInputService")
local TweenService       = game:GetService("TweenService")
local Workspace          = game:GetService("Workspace")
local StarterGui         = game:GetService("StarterGui")
local Lighting           = game:GetService("Lighting")
local Stats              = game:GetService("Stats")
local Debris             = game:GetService("Debris")
local ContentProvider    = game:GetService("ContentProvider")
local TeleportService    = game:GetService("TeleportService")
local ReplicatedStorage  = game:GetService("ReplicatedStorage")
local SoundService       = game:GetService("SoundService")

local Camera       = Workspace.CurrentCamera
local LocalPlayer  = Players.LocalPlayer
local Mouse        = LocalPlayer:GetMouse()

-- ============================================================
-- LOAD LINORIA LIBRARY
-- ============================================================
local repo = "https://raw.githubusercontent.com/violin-suzutsuki/LinoriaLib/main/"

local Library      = loadstring(game:HttpGet(repo .. "Library.lua"))()
local ThemeManager = loadstring(game:HttpGet(repo .. "addons/ThemeManager.lua"))()
local SaveManager  = loadstring(game:HttpGet(repo .. "addons/SaveManager.lua"))()

-- ============================================================
-- MASTER CONNECTION REGISTRY (for leak-free unload)
-- ============================================================
local MasterConnections = {}   -- All RBXScriptConnections stored here for cleanup
local PlayerConnections = {}   -- [Player] = {conn1, conn2, ...}

local function RegisterConnection(conn)
    table.insert(MasterConnections, conn)
    return conn
end

local function RegisterPlayerConnection(player, conn)
    if not PlayerConnections[player] then
        PlayerConnections[player] = {}
    end
    table.insert(PlayerConnections[player], conn)
    table.insert(MasterConnections, conn)
    return conn
end

local function CleanupPlayerConnections(player)
    local conns = PlayerConnections[player]
    if conns then
        for _, c in ipairs(conns) do
            if c.Connected then c:Disconnect() end
        end
        PlayerConnections[player] = nil
    end
end

local function CleanupAllConnections()
    for _, c in ipairs(MasterConnections) do
        if typeof(c) == "RBXScriptConnection" and c.Connected then
            c:Disconnect()
        end
    end
    table.clear(MasterConnections)
    table.clear(PlayerConnections)
end

-- ============================================================
-- STATE VARIABLES
-- ============================================================

-- Movement
local SpeedEnabled         = false
local SpeedValue           = 16
local JumpPowerValue       = 50
local InfiniteJumpEnabled  = false
local InstantStopEnabled   = false
local CustomGravityEnabled = false
local CustomGravityValue   = 196.2
local MaxSlopeEnabled      = false
local NoVoidEnabled        = false
local NoVoidOriginal       = nil

-- Fly
local FlyEnabled = false
local FlySpeed   = 50
local FlyBody    = nil
local FlyGyro    = nil

-- Float Platform
local FloatEnabled    = false
local FloatPlatform   = nil
local FloatOffset     = 0
local FloatMovingUp   = false
local FloatMovingDown = false

-- Noclip
local NoclipEnabled = false

-- God Mode
local GodModeEnabled = false

-- Camera
local FOVValue       = 70
local MaxZoomDistance = 128

-- Player ESP
local ESPEnabled          = false
local ESPObjects          = {}   -- [Player] = espData
local ESPFontSize         = 13
local ESPYOffset          = 3
local ESPFillTransparency = 0.5
local ESPShowDistance      = true

-- NPC ESP
local NPCESPEnabled  = false
local NPCESPObjects  = {}   -- {data, data, ...}
local NPCDestroyConns = {}  -- connections to Instance.Destroying for auto-cleanup

-- Instance Path Evaluator
local InstanceHighlights = {}

-- Aimbot
local AimbotEnabled   = false
local AimbotFOV       = 200
local AimbotSmoothing = 5
local AimbotFOVCircle = nil

-- Click TP
local ClickTPEnabled = false

-- Latch
local LatchEnabled = false
local LatchTarget  = nil
local LatchOrigin  = nil

-- Spectate
local SpectateEnabled  = false
local SpectateTarget   = nil
local SpectateBeam     = nil
local SpectateBeamAtt0 = nil
local SpectateBeamAtt1 = nil

-- Low HP Tracker
local LowHPEnabled       = false
local LowHPThreshold     = 35
local LowHPConnections   = {}   -- [Player] = {conn, ...}
local LowHPCooldowns     = {}   -- [Player] = tick()

-- Death Logger
local DeathLogEnabled    = false
local DeathLogs          = {}    -- capped at 100
local DeathConnections   = {}    -- [Player] = {conn, ...}

-- Player Activity Logger
local ActivityLogEnabled   = false
local ActivityConnections  = {}  -- named connections
local PlayerJoinTimes      = {} -- [UserId] = os.time()

-- Fullbright
local FullbrightEnabled = false
local OriginalLighting  = {}

-- Potato Graphics (weak keys so destroyed parts can be GC'd)
local PotatoEnabled = false
local OriginalMaterials = setmetatable({}, {__mode = "k"})

-- Chat Spam
local ChatSpamEnabled    = false
local ChatSpamMessage    = "Hello!"
local ChatSpamDelay      = 2
local ChatSpamGeneration = 0   -- prevents orphaned coroutines

-- Sound Customization
local SoundLowHP   = "rbxassetid://6042053626"
local SoundLeft    = "rbxassetid://6042053626"
local SoundGeneral = "rbxassetid://6042053626"
local SoundVolume  = 0.5

-- Performance Tracker
local PerfTrackerEnabled = false
local LastFPS            = 0
local FPSAccumulator     = 0
local FPSFrameCount      = 0

-- Telemetry
local TelemetryEnabled = false
local TelemetryData = {
    SessionStart   = os.time(),
    TogglesUsed    = 0,
    ButtonsPressed = 0,
    TPsPerformed   = 0,
}

-- Waypoints (up to 50)
local Waypoints     = {}
local MAX_WAYPOINTS = 50

-- Teleport Tool
local TPTool = nil

-- ============================================================
-- UTILITY FUNCTIONS
-- ============================================================

local function Notify(title, text, duration)
    Library:Notify(title .. ": " .. text, duration or 3)
end

local function PlaySound(assetId, volume)
    pcall(function()
        local s = Instance.new("Sound")
        s.SoundId = assetId
        s.Volume = volume or SoundVolume
        s.Parent = SoundService
        s:Play()
        -- PATCH #20: Debris fallback so sound is always cleaned up
        Debris:AddItem(s, 10)
        s.Ended:Once(function()
            s:Destroy()
        end)
    end)
end

local function GetCharacter()
    return LocalPlayer.Character
end

local function GetHumanoid()
    local char = GetCharacter()
    return char and char:FindFirstChildOfClass("Humanoid")
end

local function GetRootPart()
    local char = GetCharacter()
    return char and (char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso"))
end

local function GetHead()
    local char = GetCharacter()
    return char and char:FindFirstChild("Head")
end

local function IsAlive(player)
    local char = player and player.Character
    if not char then return false end
    local hum = char:FindFirstChildOfClass("Humanoid")
    if not hum or hum.Health <= 0 then return false end
    local root = char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso")
    return root ~= nil
end

local function IsTeammate(player)
    if not LocalPlayer.Team then return false end
    return player.Team == LocalPlayer.Team
end

local function GetPlayerNames(excludeSelf)
    local names = {}
    for _, p in ipairs(Players:GetPlayers()) do
        if not (excludeSelf and p == LocalPlayer) then
            table.insert(names, p.Name)
        end
    end
    return names
end

local function BumpTelemetry(field)
    if TelemetryEnabled and TelemetryData[field] then
        TelemetryData[field] += 1
    end
end

local function IsValidInstance(inst)
    return typeof(inst) == "Instance" and inst.Parent ~= nil
end

local function SafeDestroy(inst)
    if IsValidInstance(inst) then
        inst:Destroy()
    end
end

-- ============================================================
-- ESP MODULE (Players) — PATCHED
-- ============================================================

local ESPModule = {}

function ESPModule:CreateESP(player)
    if player == LocalPlayer then return end
    if ESPObjects[player] then self:RemoveESP(player) end

    local espData = {}

    local billboard = Instance.new("BillboardGui")
    billboard.Name = "ESP_Billboard"
    billboard.AlwaysOnTop = true
    billboard.Size = UDim2.new(0, 200, 0, 60)
    billboard.StudsOffset = Vector3.new(0, ESPYOffset, 0)
    billboard.LightInfluence = 0
    billboard.MaxDistance = 2000

    local nameLabel = Instance.new("TextLabel")
    nameLabel.Name = "NameLabel"
    nameLabel.BackgroundTransparency = 1
    nameLabel.Size = UDim2.new(1, 0, 0.35, 0)
    nameLabel.Font = Enum.Font.GothamBold
    nameLabel.TextSize = ESPFontSize
    nameLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
    nameLabel.TextStrokeTransparency = 0.3
    nameLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    nameLabel.Text = player.Name
    nameLabel.Parent = billboard

    local healthLabel = Instance.new("TextLabel")
    healthLabel.Name = "HealthLabel"
    healthLabel.BackgroundTransparency = 1
    healthLabel.Size = UDim2.new(1, 0, 0.35, 0)
    healthLabel.Position = UDim2.new(0, 0, 0.35, 0)
    healthLabel.Font = Enum.Font.GothamBold
    healthLabel.TextSize = ESPFontSize - 1
    healthLabel.TextColor3 = Color3.fromRGB(0, 255, 0)
    healthLabel.TextStrokeTransparency = 0.3
    healthLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    healthLabel.Text = "100 HP"
    healthLabel.Parent = billboard

    local distLabel = Instance.new("TextLabel")
    distLabel.Name = "DistLabel"
    distLabel.BackgroundTransparency = 1
    distLabel.Size = UDim2.new(1, 0, 0.3, 0)
    distLabel.Position = UDim2.new(0, 0, 0.7, 0)
    distLabel.Font = Enum.Font.Gotham
    distLabel.TextSize = ESPFontSize - 2
    distLabel.TextColor3 = Color3.fromRGB(200, 200, 200)
    distLabel.TextStrokeTransparency = 0.3
    distLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    distLabel.Text = "0m"
    distLabel.Parent = billboard

    local highlight = Instance.new("Highlight")
    highlight.Name = "ESP_Highlight"
    highlight.FillColor = Color3.fromRGB(255, 0, 0)
    highlight.OutlineColor = Color3.fromRGB(255, 255, 255)
    highlight.FillTransparency = ESPFillTransparency
    highlight.OutlineTransparency = 0
    highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop

    espData.Billboard = billboard
    espData.Highlight = highlight
    espData.NameLabel = nameLabel
    espData.HealthLabel = healthLabel
    espData.DistLabel = distLabel

    ESPObjects[player] = espData
    self:AttachESP(player)

    -- PATCH #1: Clean up when character is removed (respawn/death)
    -- so we don't hold refs to destroyed instances
    if player.Character then
        local charRemovingConn
        charRemovingConn = player.Character.AncestryChanged:Connect(function(_, parent)
            if parent == nil then
                -- Character was destroyed, detach GUI refs
                if espData.Billboard then
                    espData.Billboard.Adornee = nil
                    espData.Billboard.Parent = nil
                end
                if espData.Highlight and espData.Highlight.Parent then
                    espData.Highlight.Parent = nil
                end
                if charRemovingConn then
                    charRemovingConn:Disconnect()
                    charRemovingConn = nil
                end
            end
        end)
        RegisterPlayerConnection(player, charRemovingConn)
    end
end

function ESPModule:AttachESP(player)
    local espData = ESPObjects[player]
    if not espData then return end
    local char = player.Character
    if not char then return end

    local head = char:FindFirstChild("Head")
    if head then
        espData.Billboard.Adornee = head
        espData.Billboard.Parent = head
    end

    -- PATCH: Verify highlight parent is valid before setting
    if char.Parent then
        espData.Highlight.Parent = char
    end
end

function ESPModule:RemoveESP(player)
    local espData = ESPObjects[player]
    if not espData then return end
    SafeDestroy(espData.Billboard)
    SafeDestroy(espData.Highlight)
    espData.Billboard = nil
    espData.Highlight = nil
    ESPObjects[player] = nil
end

function ESPModule:UpdateESP()
    for player, espData in pairs(ESPObjects) do
        -- PATCH #1: Validate player still exists
        if not player or not player.Parent then
            self:RemoveESP(player)
            continue
        end

        local char = player.Character
        if not char or not char.Parent then continue end

        local hum = char:FindFirstChildOfClass("Humanoid")
        local root = char:FindFirstChild("HumanoidRootPart")
        local myRoot = GetRootPart()

        if hum then
            local maxHP = math.max(hum.MaxHealth, 1)
            local health = math.floor(hum.Health)
            local ratio = math.clamp(hum.Health / maxHP, 0, 1)
            espData.HealthLabel.Text = health .. "/" .. math.floor(maxHP) .. " HP"
            espData.HealthLabel.TextColor3 = Color3.fromRGB(255 * (1 - ratio), 255 * ratio, 0)
        end

        if root and myRoot and ESPShowDistance then
            espData.DistLabel.Text = math.floor((root.Position - myRoot.Position).Magnitude) .. "m"
            espData.DistLabel.Visible = true
        else
            espData.DistLabel.Visible = false
        end

        espData.Billboard.StudsOffset = Vector3.new(0, ESPYOffset, 0)
        espData.NameLabel.TextSize = ESPFontSize
        espData.HealthLabel.TextSize = ESPFontSize - 1
        espData.DistLabel.TextSize = ESPFontSize - 2

        -- Re-attach if adornee was lost
        if espData.Billboard.Adornee == nil or not IsValidInstance(espData.Billboard.Adornee) then
            self:AttachESP(player)
        end
    end
end

function ESPModule:EnableAll()
    for _, player in ipairs(Players:GetPlayers()) do
        if player ~= LocalPlayer then self:CreateESP(player) end
    end
end

function ESPModule:DisableAll()
    for player in pairs(ESPObjects) do
        self:RemoveESP(player)
    end
end

-- ============================================================
-- NPC ESP MODULE — PATCHED #2
-- ============================================================

local NPCESPModule = {}

function NPCESPModule:Scan()
    self:Clear()
    if not NPCESPEnabled then return end

    for _, obj in ipairs(Workspace:GetDescendants()) do
        if obj:IsA("Model") and obj:FindFirstChildOfClass("Humanoid") then
            local isPlayer = false
            for _, p in ipairs(Players:GetPlayers()) do
                if p.Character == obj then isPlayer = true; break end
            end
            if isPlayer then continue end

            local head = obj:FindFirstChild("Head")
            local hum = obj:FindFirstChildOfClass("Humanoid")
            if not head or not hum then continue end

            local highlight = Instance.new("Highlight")
            highlight.Name = "NPC_ESP_Highlight"
            highlight.FillColor = Color3.fromRGB(0, 170, 255)
            highlight.OutlineColor = Color3.fromRGB(255, 255, 255)
            highlight.FillTransparency = 0.5
            highlight.OutlineTransparency = 0
            highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
            highlight.Parent = obj

            local bb = Instance.new("BillboardGui")
            bb.Name = "NPC_ESP_Billboard"
            bb.AlwaysOnTop = true
            bb.Size = UDim2.new(0, 200, 0, 40)
            bb.StudsOffset = Vector3.new(0, 3, 0)
            bb.LightInfluence = 0
            bb.MaxDistance = 1500
            bb.Adornee = head
            bb.Parent = head

            local lbl = Instance.new("TextLabel")
            lbl.BackgroundTransparency = 1
            lbl.Size = UDim2.new(1, 0, 0.5, 0)
            lbl.Font = Enum.Font.GothamBold
            lbl.TextSize = 12
            lbl.TextColor3 = Color3.fromRGB(0, 200, 255)
            lbl.TextStrokeTransparency = 0.3
            lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
            lbl.Text = "[NPC] " .. obj.Name
            lbl.Parent = bb

            local hlbl = Instance.new("TextLabel")
            hlbl.BackgroundTransparency = 1
            hlbl.Size = UDim2.new(1, 0, 0.5, 0)
            hlbl.Position = UDim2.new(0, 0, 0.5, 0)
            hlbl.Font = Enum.Font.Gotham
            hlbl.TextSize = 11
            hlbl.TextColor3 = Color3.fromRGB(0, 255, 0)
            hlbl.TextStrokeTransparency = 0.3
            hlbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
            hlbl.Text = math.floor(hum.Health) .. " HP"
            hlbl.Parent = bb

            local data = {
                Model = obj,
                Highlight = highlight,
                Billboard = bb,
                HealthLabel = hlbl,
                Humanoid = hum,
                DestroyConn = nil,
            }

            -- PATCH #2: Auto-cleanup when NPC model is destroyed
            data.DestroyConn = obj.AncestryChanged:Connect(function(_, parent)
                if parent == nil then
                    SafeDestroy(data.Highlight)
                    SafeDestroy(data.Billboard)
                    if data.DestroyConn then
                        data.DestroyConn:Disconnect()
                        data.DestroyConn = nil
                    end
                    -- Remove from table
                    for i, d in ipairs(NPCESPObjects) do
                        if d == data then
                            table.remove(NPCESPObjects, i)
                            break
                        end
                    end
                end
            end)

            table.insert(NPCESPObjects, data)
        end
    end
end

function NPCESPModule:Update()
    for i = #NPCESPObjects, 1, -1 do
        local data = NPCESPObjects[i]
        if not data.Model or not data.Model.Parent or not data.Humanoid or not data.Humanoid.Parent then
            SafeDestroy(data.Highlight)
            SafeDestroy(data.Billboard)
            if data.DestroyConn then data.DestroyConn:Disconnect(); data.DestroyConn = nil end
            table.remove(NPCESPObjects, i)
        else
            data.HealthLabel.Text = math.floor(data.Humanoid.Health) .. " HP"
        end
    end
end

function NPCESPModule:Clear()
    for _, data in ipairs(NPCESPObjects) do
        SafeDestroy(data.Highlight)
        SafeDestroy(data.Billboard)
        if data.DestroyConn then data.DestroyConn:Disconnect(); data.DestroyConn = nil end
    end
    NPCESPObjects = {}
end

-- ============================================================
-- FLY MODULE — PATCHED #11
-- ============================================================

local FlyModule = {}

function FlyModule:Enable()
    local root = GetRootPart()
    local hum = GetHumanoid()
    if not root or not hum then return end

    -- PATCH #11: Clean old instances first
    self:Disable()

    FlyBody = Instance.new("BodyVelocity")
    FlyBody.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
    FlyBody.Velocity = Vector3.zero
    FlyBody.Parent = root

    FlyGyro = Instance.new("BodyGyro")
    FlyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
    FlyGyro.P = 9e4
    FlyGyro.Parent = root

    hum.PlatformStand = true
end

function FlyModule:Disable()
    local hum = GetHumanoid()
    if hum then hum.PlatformStand = false end
    if FlyBody then SafeDestroy(FlyBody); FlyBody = nil end
    if FlyGyro then SafeDestroy(FlyGyro); FlyGyro = nil end
end

function FlyModule:Update()
    if not FlyEnabled then return end
    -- PATCH #11: Validate instances still exist and have parents
    if not FlyBody or not FlyBody.Parent or not FlyGyro or not FlyGyro.Parent then
        -- Re-enable if character is valid
        local root = GetRootPart()
        if root and root.Parent then
            self:Enable()
        end
        return
    end

    local root = GetRootPart()
    if not root or not root.Parent then return end

    local dir = Vector3.zero
    local cf = Camera.CFrame

    if UserInputService:IsKeyDown(Enum.KeyCode.W) then dir += cf.LookVector end
    if UserInputService:IsKeyDown(Enum.KeyCode.S) then dir -= cf.LookVector end
    if UserInputService:IsKeyDown(Enum.KeyCode.A) then dir -= cf.RightVector end
    if UserInputService:IsKeyDown(Enum.KeyCode.D) then dir += cf.RightVector end
    if UserInputService:IsKeyDown(Enum.KeyCode.Space) then dir += Vector3.yAxis end
    if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then dir -= Vector3.yAxis end

    if dir.Magnitude > 0 then dir = dir.Unit end
    FlyBody.Velocity = dir * FlySpeed
    FlyGyro.CFrame = cf
end

-- ============================================================
-- AIMBOT MODULE — PATCHED #12
-- ============================================================

local AimbotModule = {}

function AimbotModule:CreateFOVCircle()
    self:DestroyFOVCircle()
    AimbotFOVCircle = Drawing.new("Circle")
    AimbotFOVCircle.Visible = false
    AimbotFOVCircle.Radius = AimbotFOV
    AimbotFOVCircle.Color = Color3.fromRGB(255, 255, 255)
    AimbotFOVCircle.Thickness = 1
    AimbotFOVCircle.Transparency = 0.7
    AimbotFOVCircle.Filled = false
    AimbotFOVCircle.NumSides = 64
end

-- PATCH #12: Centralized cleanup
function AimbotModule:DestroyFOVCircle()
    if AimbotFOVCircle then
        pcall(function() AimbotFOVCircle:Remove() end)
        AimbotFOVCircle = nil
    end
end

function AimbotModule:UpdateFOVCircle()
    if not AimbotFOVCircle then return end
    local mp = UserInputService:GetMouseLocation()
    AimbotFOVCircle.Position = Vector2.new(mp.X, mp.Y)
    AimbotFOVCircle.Radius = AimbotFOV
    AimbotFOVCircle.Visible = AimbotEnabled
end

function AimbotModule:GetClosestPlayer()
    local closest, closestDist = nil, AimbotFOV
    local mp = UserInputService:GetMouseLocation()

    for _, player in ipairs(Players:GetPlayers()) do
        if player == LocalPlayer or not IsAlive(player) or IsTeammate(player) then continue end
        local head = player.Character and player.Character:FindFirstChild("Head")
        if not head then continue end
        local sp, onScreen = Camera:WorldToViewportPoint(head.Position)
        if not onScreen then continue end
        local dist = (Vector2.new(sp.X, sp.Y) - mp).Magnitude
        if dist < closestDist then closestDist = dist; closest = player end
    end
    return closest
end

function AimbotModule:AimAt(player)
    if not player then return end
    local head = player.Character and player.Character:FindFirstChild("Head")
    if not head then return end
    local camPos = Camera.CFrame.Position
    local targetCF = CFrame.lookAt(camPos, head.Position)
    Camera.CFrame = Camera.CFrame:Lerp(targetCF, 1 / AimbotSmoothing)
end

-- ============================================================
-- FLOAT PLATFORM MODULE — PATCHED #8
-- ============================================================

local FloatModule = {}

function FloatModule:Enable()
    self:Disable()
    local root = GetRootPart()
    if not root then return end

    FloatPlatform = Instance.new("Part")
    FloatPlatform.Name = "FloatPlatform"
    FloatPlatform.Size = Vector3.new(6, 0.5, 6)
    FloatPlatform.Anchored = true
    FloatPlatform.CanCollide = true
    FloatPlatform.Transparency = 0.6
    FloatPlatform.BrickColor = BrickColor.new("Institutional white")
    FloatPlatform.Material = Enum.Material.ForceField
    FloatPlatform.CFrame = root.CFrame * CFrame.new(0, -3.5 + FloatOffset, 0)
    FloatPlatform.Parent = Workspace
end

function FloatModule:Disable()
    if FloatPlatform then
        SafeDestroy(FloatPlatform)
        FloatPlatform = nil
    end
end

function FloatModule:Update()
    if not FloatEnabled then return end
    -- PATCH #8: Validate platform still exists
    if not FloatPlatform or not FloatPlatform.Parent then
        if FloatEnabled then self:Enable() end
        return
    end
    local root = GetRootPart()
    if not root or not root.Parent then return end

    if FloatMovingUp then FloatOffset += 0.5 end
    if FloatMovingDown then FloatOffset -= 0.5 end

    FloatPlatform.CFrame = CFrame.new(root.Position.X, root.Position.Y - 3.5 + FloatOffset, root.Position.Z)
end

-- ============================================================
-- SPECTATE MODULE — PATCHED #7
-- ============================================================

local SpectateModule = {}

function SpectateModule:Enable(player)
    if not player or not player.Character then return end
    SpectateTarget = player
    local hum = player.Character:FindFirstChildOfClass("Humanoid")
    if hum then Camera.CameraSubject = hum end
    self:CreateBeam()
end

function SpectateModule:Disable()
    SpectateTarget = nil
    local hum = GetHumanoid()
    if hum then Camera.CameraSubject = hum end
    self:DestroyBeam()
end

function SpectateModule:CreateBeam()
    self:DestroyBeam()
    local myRoot = GetRootPart()
    if not myRoot or not myRoot.Parent then return end
    if not SpectateTarget or not SpectateTarget.Character then return end

    local tRoot = SpectateTarget.Character:FindFirstChild("HumanoidRootPart")
    if not tRoot or not tRoot.Parent then return end

    SpectateBeamAtt0 = Instance.new("Attachment")
    SpectateBeamAtt0.Parent = myRoot

    SpectateBeamAtt1 = Instance.new("Attachment")
    SpectateBeamAtt1.Parent = tRoot

    SpectateBeam = Instance.new("Beam")
    SpectateBeam.Attachment0 = SpectateBeamAtt0
    SpectateBeam.Attachment1 = SpectateBeamAtt1
    SpectateBeam.Color = ColorSequence.new(Color3.fromRGB(0, 255, 255))
    SpectateBeam.Width0 = 0.3
    SpectateBeam.Width1 = 0.3
    SpectateBeam.FaceCamera = true
    SpectateBeam.LightEmission = 1
    SpectateBeam.Transparency = NumberSequence.new(0.3)
    SpectateBeam.Parent = myRoot
end

function SpectateModule:DestroyBeam()
    SafeDestroy(SpectateBeam); SpectateBeam = nil
    SafeDestroy(SpectateBeamAtt0); SpectateBeamAtt0 = nil
    SafeDestroy(SpectateBeamAtt1); SpectateBeamAtt1 = nil
end

-- PATCH #7: Validate spectate target each frame
function SpectateModule:Validate()
    if not SpectateEnabled then return end
    if not SpectateTarget or not SpectateTarget.Parent then
        self:Disable()
        SpectateEnabled = false
        if Toggles and Toggles.SpectateToggle then
            Toggles.SpectateToggle:SetValue(false)
        end
        Notify("Spectate", "Target left, spectate disabled")
        return
    end
    if not SpectateTarget.Character or not SpectateTarget.Character.Parent then
        -- Character gone (respawning), just wait
        return
    end
    -- Validate beam attachments
    if SpectateBeamAtt1 and not IsValidInstance(SpectateBeamAtt1) then
        self:CreateBeam()
    end
end

-- ============================================================
-- LOW HP TRACKER MODULE — PATCHED #3
-- ============================================================

local LowHPModule = {}

function LowHPModule:Enable()
    self:Disable()
    for _, player in ipairs(Players:GetPlayers()) do
        if player ~= LocalPlayer then self:Watch(player) end
    end
end

function LowHPModule:Watch(player)
    if LowHPConnections[player] then return end -- already watching
    LowHPConnections[player] = {}
    LowHPCooldowns[player] = 0

    -- PATCH #3: Use CharacterAdded + HealthChanged instead of Heartbeat polling
    local function hookCharacter(char)
        if not char then return end
        local hum = char:WaitForChild("Humanoid", 10)
        if not hum then return end

        local healthConn
        healthConn = hum.HealthChanged:Connect(function(newHealth)
            if not LowHPEnabled then return end
            if newHealth > 0 and newHealth < LowHPThreshold then
                local now = tick()
                if now - (LowHPCooldowns[player] or 0) > 5 then
                    LowHPCooldowns[player] = now
                    PlaySound(SoundLowHP, SoundVolume)
                    Notify("Low HP", player.Name .. " is at " .. math.floor(newHealth) .. " HP!", 2)
                end
            end
        end)

        if not LowHPConnections[player] then
            LowHPConnections[player] = {}
        end
        table.insert(LowHPConnections[player], healthConn)
    end

    -- Hook current character
    if player.Character then hookCharacter(player.Character) end

    -- Hook future characters
    local charAddedConn = player.CharacterAdded:Connect(function(char)
        task.wait(1)
        hookCharacter(char)
    end)
    table.insert(LowHPConnections[player], charAddedConn)
end

function LowHPModule:Unwatch(player)
    local conns = LowHPConnections[player]
    if conns then
        for _, c in ipairs(conns) do
            if c.Connected then c:Disconnect() end
        end
    end
    LowHPConnections[player] = nil
    LowHPCooldowns[player] = nil
end

function LowHPModule:Disable()
    for player in pairs(LowHPConnections) do
        self:Unwatch(player)
    end
    LowHPConnections = {}
    LowHPCooldowns = {}
end

-- ============================================================
-- DEATH LOGGER MODULE — PATCHED #4
-- ============================================================

local DeathLogModule = {}

function DeathLogModule:Enable()
    self:Disable()
    for _, player in ipairs(Players:GetPlayers()) do
        self:Watch(player)
    end
end

function DeathLogModule:Watch(player)
    -- PATCH #4: Prevent stacking connections
    if DeathConnections[player] then return end
    DeathConnections[player] = {}

    local function hookCharacter(char)
        if not char then return end
        local hum = char:WaitForChild("Humanoid", 10)
        if not hum then return end

        local diedConn
        diedConn = hum.Died:Connect(function()
            local root = char:FindFirstChild("HumanoidRootPart")
            local pos = root and root.Position or Vector3.zero
            local isVoid = pos.Y < (Workspace.FallenPartsDestroyHeight + 50)
            local entry = {
                Player = player.Name,
                Position = pos,
                CFrame = root and root.CFrame or CFrame.new(),
                Time = os.date("%H:%M:%S"),
                IsVoid = isVoid,
            }
            table.insert(DeathLogs, 1, entry)
            -- PATCH #15: Cap death logs
            while #DeathLogs > 100 do
                table.remove(DeathLogs)
            end
            Notify("Death Log", player.Name .. " died at " .. entry.Time .. (isVoid and " (Void)" or ""), 4)
        end)

        if DeathConnections[player] then
            table.insert(DeathConnections[player], diedConn)
        end
    end

    if player.Character then hookCharacter(player.Character) end

    local charConn = player.CharacterAdded:Connect(function(char)
        task.wait(0.5)
        hookCharacter(char)
    end)
    table.insert(DeathConnections[player], charConn)
end

function DeathLogModule:Unwatch(player)
    local conns = DeathConnections[player]
    if conns then
        for _, c in ipairs(conns) do
            if c.Connected then c:Disconnect() end
        end
    end
    DeathConnections[player] = nil
end

function DeathLogModule:Disable()
    for player in pairs(DeathConnections) do
        self:Unwatch(player)
    end
    DeathConnections = {}
end

-- ============================================================
-- PLAYER ACTIVITY LOGGER — PATCHED #5, #14
-- ============================================================

local ActivityModule = {}

function ActivityModule:Enable()
    self:Disable()

    -- PATCH #14: Clear stale join times
    table.clear(PlayerJoinTimes)

    for _, p in ipairs(Players:GetPlayers()) do
        PlayerJoinTimes[p.UserId] = os.time()
    end

    local joinConn = Players.PlayerAdded:Connect(function(p)
        PlayerJoinTimes[p.UserId] = os.time()
    end)

    local leaveConn = Players.PlayerRemoving:Connect(function(p)
        local joinTime = PlayerJoinTimes[p.UserId]
        local duration = joinTime and (os.time() - joinTime) or 0
        local mins = math.floor(duration / 60)
        local secs = duration % 60
        PlaySound(SoundLeft, SoundVolume)
        Notify("Player Left", string.format("%s left (Session: %dm %ds)", p.Name, mins, secs), 5)
        PlayerJoinTimes[p.UserId] = nil
    end)

    -- PATCH #5: Store named for proper cleanup
    ActivityConnections = {joinConn, leaveConn}
end

function ActivityModule:Disable()
    for _, c in ipairs(ActivityConnections) do
        if typeof(c) == "RBXScriptConnection" and c.Connected then c:Disconnect() end
    end
    ActivityConnections = {}
    -- PATCH #14: Clear join times
    table.clear(PlayerJoinTimes)
end

-- ============================================================
-- INSTANCE PATH EVALUATOR — PATCHED #9
-- ============================================================

local function ClearInstanceHighlights()
    for i = #InstanceHighlights, 1, -1 do
        SafeDestroy(InstanceHighlights[i])
        InstanceHighlights[i] = nil
    end
    InstanceHighlights = {}
end

local function EvaluateInstancePath(pathStr)
    -- PATCH #9: Always clear before new evaluation
    ClearInstanceHighlights()

    local success, result = pcall(function()
        return loadstring("return " .. pathStr)()
    end)

    if not success then
        Notify("Evaluator", "Error: " .. tostring(result), 4)
        return
    end

    local parts = {}
    if typeof(result) == "Instance" then
        parts = {result}
    elseif type(result) == "table" then
        parts = result
    end

    local count = 0
    for _, part in ipairs(parts) do
        if typeof(part) == "Instance" and (part:IsA("BasePart") or part:IsA("Model")) then
            local h = Instance.new("Highlight")
            h.FillColor = Color3.fromRGB(255, 255, 0)
            h.OutlineColor = Color3.fromRGB(255, 255, 0)
            h.FillTransparency = 0.4
            h.OutlineTransparency = 0
            h.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
            h.Parent = part
            table.insert(InstanceHighlights, h)
            count += 1
        end
    end
    Notify("Evaluator", "Highlighted " .. count .. " instances", 3)
end

-- ============================================================
-- WORKSPACE SCANNER
-- ============================================================

local function ScanWorkspace()
    local anchored, unanchored, tools, npcs, playerCount = 0, 0, 0, 0, #Players:GetPlayers()

    for _, obj in ipairs(Workspace:GetDescendants()) do
        if obj:IsA("BasePart") then
            if obj.Anchored then anchored += 1 else unanchored += 1 end
        elseif obj:IsA("Tool") then
            tools += 1
        elseif obj:IsA("Humanoid") then
            local model = obj.Parent
            local isPlayer = false
            for _, p in ipairs(Players:GetPlayers()) do
                if p.Character == model then isPlayer = true; break end
            end
            if not isPlayer then npcs += 1 end
        end
    end

    return string.format(
        "Anchored: %d\nUnanchored: %d\nTools: %d\nPlayers: %d\nNPCs: %d",
        anchored, unanchored, tools, playerCount, npcs
    )
end

-- ============================================================
-- FULLBRIGHT / POTATO GRAPHICS — PATCHED #18
-- ============================================================

local function EnableFullbright()
    OriginalLighting.Ambient = Lighting.Ambient
    OriginalLighting.Brightness = Lighting.Brightness
    OriginalLighting.ClockTime = Lighting.ClockTime
    OriginalLighting.FogEnd = Lighting.FogEnd
    OriginalLighting.GlobalShadows = Lighting.GlobalShadows
    OriginalLighting.OutdoorAmbient = Lighting.OutdoorAmbient

    Lighting.Ambient = Color3.fromRGB(178, 178, 178)
    Lighting.Brightness = 2
    Lighting.ClockTime = 14
    Lighting.FogEnd = 100000
    Lighting.GlobalShadows = false
    Lighting.OutdoorAmbient = Color3.fromRGB(178, 178, 178)
end

local function DisableFullbright()
    for prop, val in pairs(OriginalLighting) do
        pcall(function() Lighting[prop] = val end)
    end
end

-- PATCH #18: Weak-key table so destroyed parts get GC'd
local function EnablePotato()
    for _, obj in ipairs(Workspace:GetDescendants()) do
        if obj:IsA("BasePart") then
            OriginalMaterials[obj] = obj.Material
            obj.Material = Enum.Material.SmoothPlastic
        end
    end
end

local function DisablePotato()
    for obj, mat in pairs(OriginalMaterials) do
        if typeof(obj) == "Instance" and obj.Parent then
            pcall(function() obj.Material = mat end)
        end
    end
    -- Reset weak table
    OriginalMaterials = setmetatable({}, {__mode = "k"})
end

-- ============================================================
-- TELEPORT TOOL
-- ============================================================

local function CreateTPTool()
    if TPTool then SafeDestroy(TPTool); TPTool = nil end
    TPTool = Instance.new("Tool")
    TPTool.Name = "TP Tool"
    TPTool.RequiresHandle = false
    TPTool.CanBeDropped = false

    TPTool.Activated:Connect(function()
        local root = GetRootPart()
        if root and Mouse.Hit then
            root.CFrame = CFrame.new(Mouse.Hit.Position + Vector3.new(0, 3, 0))
            BumpTelemetry("TPsPerformed")
        end
    end)

    local backpack = LocalPlayer:FindFirstChild("Backpack")
    if backpack then
        TPTool.Parent = backpack
        Notify("Tool", "TP Tool added to inventory!", 3)
    end
end

-- ============================================================
-- NOCLIP
-- ============================================================

local function NoclipUpdate()
    if not NoclipEnabled then return end
    local char = GetCharacter()
    if not char then return end
    for _, part in ipairs(char:GetDescendants()) do
        if part:IsA("BasePart") then part.CanCollide = false end
    end
end

-- ============================================================
-- INSTANT STOP (Anti-Sliding)
-- ============================================================

local function InstantStopUpdate()
    if not InstantStopEnabled then return end
    local hum = GetHumanoid()
    local root = GetRootPart()
    if not hum or not root then return end
    if hum.MoveDirection.Magnitude == 0 then
        root.AssemblyLinearVelocity = Vector3.new(0, root.AssemblyLinearVelocity.Y, 0)
    end
end

-- ============================================================
-- CREATE LINORIA UI
-- ============================================================

local Window = Library:CreateWindow({
    Title = "persistence.win",
    Center = true,
    AutoShow = true,
    TabPadding = 8,
    MenuFadeTime = 0.2,
})

-- ─────────────────────────────────────────────
-- TAB: MOVEMENT
-- ─────────────────────────────────────────────
local MovementTab = Window:AddTab("Movement")

local SpeedGroup = MovementTab:AddLeftGroupbox("Speed & Jump")

SpeedGroup:AddToggle("SpeedToggle", {
    Text = "Custom WalkSpeed",
    Default = false,
    Callback = function(v)
        SpeedEnabled = v
        BumpTelemetry("TogglesUsed")
        if not v then
            local hum = GetHumanoid()
            if hum then hum.WalkSpeed = 16 end
        end
    end
})

SpeedGroup:AddSlider("WalkSpeedSlider", {
    Text = "Walk Speed",
    Default = 16, Min = 0, Max = 250, Rounding = 0,
    Callback = function(v) SpeedValue = v end
})

SpeedGroup:AddSlider("JumpPowerSlider", {
    Text = "Jump Power",
    Default = 50, Min = 0, Max = 300, Rounding = 0,
    Callback = function(v)
        JumpPowerValue = v
        local hum = GetHumanoid()
        if hum then hum.UseJumpPower = true; hum.JumpPower = v end
    end
})

SpeedGroup:AddToggle("InfiniteJumpToggle", {
    Text = "Infinite Jump",
    Default = false,
    Callback = function(v) InfiniteJumpEnabled = v; BumpTelemetry("TogglesUsed") end
})

SpeedGroup:AddToggle("InstantStopToggle", {
    Text = "Instant Stop (No Sliding)",
    Default = false,
    Tooltip = "Removes deceleration when you release movement keys",
    Callback = function(v) InstantStopEnabled = v; BumpTelemetry("TogglesUsed") end
})

local PhysicsGroup = MovementTab:AddLeftGroupbox("Physics")

PhysicsGroup:AddToggle("CustomGravityToggle", {
    Text = "Custom Gravity",
    Default = false,
    Callback = function(v)
        CustomGravityEnabled = v
        BumpTelemetry("TogglesUsed")
        if not v then Workspace.Gravity = 196.2 end
    end
})

PhysicsGroup:AddSlider("GravitySlider", {
    Text = "Gravity",
    Default = 196.2, Min = 0, Max = 1000, Rounding = 1,
    Callback = function(v) CustomGravityValue = v end
})

PhysicsGroup:AddToggle("MaxSlopeToggle", {
    Text = "360° MaxSlopeAngle",
    Default = false,
    Tooltip = "Walk up vertical surfaces",
    Callback = function(v)
        MaxSlopeEnabled = v
        BumpTelemetry("TogglesUsed")
        local hum = GetHumanoid()
        if hum then hum.MaxSlopeAngle = v and 360 or 89 end
    end
})

PhysicsGroup:AddToggle("NoVoidToggle", {
    Text = "No Void Protection",
    Default = false,
    Tooltip = "Prevents dying from falling off the map",
    Callback = function(v)
        NoVoidEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then
            NoVoidOriginal = Workspace.FallenPartsDestroyHeight
            Workspace.FallenPartsDestroyHeight = -1e9
        else
            if NoVoidOriginal then Workspace.FallenPartsDestroyHeight = NoVoidOriginal end
        end
    end
})

local FlyGroup = MovementTab:AddRightGroupbox("Fly")

FlyGroup:AddToggle("FlyToggle", {
    Text = "Fly Enabled",
    Default = false,
    Tooltip = "WASD + Space/Shift to move",
    Callback = function(v)
        FlyEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then FlyModule:Enable() else FlyModule:Disable() end
    end
})

FlyGroup:AddSlider("FlySpeedSlider", {
    Text = "Fly Speed",
    Default = 50, Min = 10, Max = 500, Rounding = 0,
    Callback = function(v) FlySpeed = v end
})

local CharGroup = MovementTab:AddRightGroupbox("Character")

CharGroup:AddToggle("NoclipToggle", {
    Text = "Noclip",
    Default = false,
    Callback = function(v) NoclipEnabled = v; BumpTelemetry("TogglesUsed") end
})

CharGroup:AddToggle("GodModeToggle", {
    Text = "God Mode (Client)",
    Default = false,
    Callback = function(v)
        GodModeEnabled = v
        BumpTelemetry("TogglesUsed")
        local hum = GetHumanoid()
        if hum then
            if v then hum.MaxHealth = math.huge; hum.Health = math.huge
            else hum.MaxHealth = 100; hum.Health = 100 end
        end
    end
})

CharGroup:AddButton({
    Text = "Reset Character",
    DoubleClick = true,
    Func = function()
        local hum = GetHumanoid()
        if hum then hum.Health = 0 end
        BumpTelemetry("ButtonsPressed")
    end
})

local FloatGroup = MovementTab:AddRightGroupbox("Float Platform")

FloatGroup:AddToggle("FloatToggle", {
    Text = "Float Platform",
    Default = false,
    Tooltip = "Q = Up, E = Down",
    Callback = function(v)
        FloatEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then FloatModule:Enable() else FloatModule:Disable(); FloatOffset = 0 end
    end
})

FloatGroup:AddSlider("FloatOffsetSlider", {
    Text = "Vertical Offset",
    Default = 0, Min = -50, Max = 200, Rounding = 0,
    Callback = function(v) FloatOffset = v end
})

-- ─────────────────────────────────────────────
-- TAB: COMBAT
-- ─────────────────────────────────────────────
local CombatTab = Window:AddTab("Combat")

local AimbotGroup = CombatTab:AddLeftGroupbox("Aimbot")

AimbotGroup:AddToggle("AimbotToggle", {
    Text = "Aimbot (Hold RMB)",
    Default = false,
    Callback = function(v) AimbotEnabled = v; BumpTelemetry("TogglesUsed") end
})

AimbotGroup:AddSlider("AimbotFOVSlider", {
    Text = "FOV Radius",
    Default = 200, Min = 50, Max = 800, Rounding = 0,
    Callback = function(v) AimbotFOV = v end
})

AimbotGroup:AddSlider("AimbotSmoothSlider", {
    Text = "Smoothing",
    Default = 5, Min = 1, Max = 20, Rounding = 1,
    Callback = function(v) AimbotSmoothing = v end
})

AimbotGroup:AddToggle("ShowFOVToggle", {
    Text = "Show FOV Circle",
    Default = false,
    Callback = function(v)
        if AimbotFOVCircle then AimbotFOVCircle.Visible = v and AimbotEnabled end
    end
})

local CombatMiscGroup = CombatTab:AddRightGroupbox("Misc Combat")

CombatMiscGroup:AddToggle("ClickTPToggle", {
    Text = "Click Teleport (Ctrl+Click)",
    Default = false,
    Callback = function(v) ClickTPEnabled = v; BumpTelemetry("TogglesUsed") end
})

CombatMiscGroup:AddButton({
    Text = "TP to Closest Player",
    Func = function()
        local myRoot = GetRootPart()
        if not myRoot then return end
        local closest, closestDist = nil, math.huge
        for _, p in ipairs(Players:GetPlayers()) do
            if p == LocalPlayer or not IsAlive(p) then continue end
            local r = p.Character:FindFirstChild("HumanoidRootPart")
            if r then
                local d = (r.Position - myRoot.Position).Magnitude
                if d < closestDist then closestDist = d; closest = r end
            end
        end
        if closest then
            myRoot.CFrame = closest.CFrame * CFrame.new(0, 0, 5)
            BumpTelemetry("TPsPerformed")
            Notify("Teleport", "TP'd to closest player!")
        end
    end
})

CombatMiscGroup:AddButton({
    Text = "Equip TP Tool",
    Func = function() CreateTPTool(); BumpTelemetry("ButtonsPressed") end,
    Tooltip = "Adds a click-to-teleport tool to your inventory"
})

-- ─────────────────────────────────────────────
-- TAB: PLAYERS & TRACKING
-- ─────────────────────────────────────────────
local TrackingTab = Window:AddTab("Players")

local PlayerTPGroup = TrackingTab:AddLeftGroupbox("Player Teleport")

PlayerTPGroup:AddDropdown("TPPlayerDropdown", {
    Values = GetPlayerNames(true),
    Default = 1,
    Multi = false,
    Text = "Select Player",
})

PlayerTPGroup:AddButton({
    Text = "Teleport to Player",
    Func = function()
        local sel = Options.TPPlayerDropdown.Value
        if not sel then Notify("TP", "No player selected!"); return end
        local t = Players:FindFirstChild(sel)
        if t and t.Character then
            local tr = t.Character:FindFirstChild("HumanoidRootPart")
            local mr = GetRootPart()
            if tr and mr then
                mr.CFrame = tr.CFrame * CFrame.new(0, 0, 5)
                BumpTelemetry("TPsPerformed")
                Notify("TP", "Teleported to " .. sel)
            end
        end
    end
})

PlayerTPGroup:AddButton({
    Text = "Refresh Player List",
    Func = function()
        Options.TPPlayerDropdown:SetValues(GetPlayerNames(true))
        Notify("TP", "Player list refreshed!")
    end
})

local LatchGroup = TrackingTab:AddLeftGroupbox("Latch Onto Player")

LatchGroup:AddDropdown("LatchDropdown", {
    Values = GetPlayerNames(true),
    Default = 1,
    Multi = false,
    Text = "Latch Target",
})

LatchGroup:AddToggle("LatchToggle", {
    Text = "Latch Enabled",
    Default = false,
    Tooltip = "TP to player, returns you when disabled",
    Callback = function(v)
        LatchEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then
            local sel = Options.LatchDropdown.Value
            local t = sel and Players:FindFirstChild(sel)
            local mr = GetRootPart()
            if mr then LatchOrigin = mr.CFrame end
            if t and t.Character then
                local tr = t.Character:FindFirstChild("HumanoidRootPart")
                if tr and mr then
                    LatchTarget = t
                    mr.CFrame = tr.CFrame * CFrame.new(0, 0, 3)
                    Notify("Latch", "Latched onto " .. sel)
                end
            else
                Notify("Latch", "Target not found!")
                LatchEnabled = false
                if Toggles and Toggles.LatchToggle then Toggles.LatchToggle:SetValue(false) end
            end
        else
            LatchTarget = nil
            local mr = GetRootPart()
            if mr and LatchOrigin then
                mr.CFrame = LatchOrigin
                Notify("Latch", "Returned to origin")
            end
            LatchOrigin = nil
        end
    end
})

local SpectateGroup = TrackingTab:AddRightGroupbox("Spectate")

SpectateGroup:AddDropdown("SpectateDropdown", {
    Values = GetPlayerNames(true),
    Default = 1,
    Multi = false,
    Text = "Spectate Target",
})

SpectateGroup:AddToggle("SpectateToggle", {
    Text = "Spectate Player",
    Default = false,
    Callback = function(v)
        SpectateEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then
            local sel = Options.SpectateDropdown.Value
            local t = sel and Players:FindFirstChild(sel)
            if t then SpectateModule:Enable(t) else Notify("Spectate", "Player not found!") end
        else
            SpectateModule:Disable()
        end
    end
})

local LowHPGroup = TrackingTab:AddRightGroupbox("Low HP Tracker")

LowHPGroup:AddToggle("LowHPToggle", {
    Text = "Low HP Alerts",
    Default = false,
    Callback = function(v)
        LowHPEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then LowHPModule:Enable() else LowHPModule:Disable() end
    end
})

LowHPGroup:AddSlider("LowHPThreshold", {
    Text = "HP Threshold",
    Default = 35, Min = 5, Max = 100, Rounding = 0,
    Callback = function(v) LowHPThreshold = v end
})

local DeathLogGroup = TrackingTab:AddRightGroupbox("Death Logger")

DeathLogGroup:AddToggle("DeathLogToggle", {
    Text = "Death Logger",
    Default = false,
    Callback = function(v)
        DeathLogEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then DeathLogModule:Enable() else DeathLogModule:Disable() end
    end
})

DeathLogGroup:AddButton({
    Text = "TP to Last Death Location",
    Func = function()
        if #DeathLogs == 0 then Notify("Death Log", "No deaths logged!"); return end
        local root = GetRootPart()
        if root then
            root.CFrame = DeathLogs[1].CFrame
            BumpTelemetry("TPsPerformed")
            Notify("Death Log", "TP'd to " .. DeathLogs[1].Player .. "'s death location")
        end
    end
})

DeathLogGroup:AddButton({
    Text = "Print Death Log (F9)",
    Func = function()
        print("═══ DEATH LOG ═══")
        for i, entry in ipairs(DeathLogs) do
            print(string.format("#%d | %s | %s | %s | Pos: %s",
                i, entry.Time, entry.Player,
                entry.IsVoid and "VOID" or "NORMAL",
                tostring(entry.Position)))
        end
        print("═════════════════")
        Notify("Death Log", #DeathLogs .. " entries printed to console (F9)")
    end
})

DeathLogGroup:AddButton({
    Text = "Clear Death Logs",
    Func = function()
        table.clear(DeathLogs)
        DeathLogs = {}
        Notify("Death Log", "All logs cleared")
    end
})

-- ─────────────────────────────────────────────
-- TAB: VISUALS
-- ─────────────────────────────────────────────
local VisualsTab = Window:AddTab("Visuals")

local ESPGroup = VisualsTab:AddLeftGroupbox("Player ESP")

ESPGroup:AddToggle("ESPToggle", {
    Text = "Player ESP",
    Default = false,
    Callback = function(v)
        ESPEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then ESPModule:EnableAll() else ESPModule:DisableAll() end
    end
})

ESPGroup:AddToggle("ESPDistToggle", {
    Text = "Show Distance",
    Default = true,
    Callback = function(v) ESPShowDistance = v end
})

ESPGroup:AddSlider("ESPFontSlider", {
    Text = "Font Size",
    Default = 13, Min = 8, Max = 24, Rounding = 0,
    Callback = function(v) ESPFontSize = v end
})

ESPGroup:AddSlider("ESPYOffsetSlider", {
    Text = "Y Offset",
    Default = 3, Min = 0, Max = 10, Rounding = 1,
    Callback = function(v) ESPYOffset = v end
})

ESPGroup:AddSlider("ESPFillSlider", {
    Text = "Fill Transparency",
    Default = 0.5, Min = 0, Max = 1, Rounding = 2,
    Callback = function(v)
        ESPFillTransparency = v
        for _, data in pairs(ESPObjects) do
            if data.Highlight and data.Highlight.Parent then data.Highlight.FillTransparency = v end
        end
    end
})

local NPCGroup = VisualsTab:AddLeftGroupbox("NPC ESP")

NPCGroup:AddToggle("NPCESPToggle", {
    Text = "NPC ESP",
    Default = false,
    Callback = function(v)
        NPCESPEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then NPCESPModule:Scan() else NPCESPModule:Clear() end
    end
})

NPCGroup:AddButton({
    Text = "Rescan NPCs",
    Func = function()
        NPCESPModule:Scan()
        Notify("NPC ESP", #NPCESPObjects .. " NPCs found")
    end
})

local WorldGroup = VisualsTab:AddRightGroupbox("World & Lighting")

WorldGroup:AddToggle("FullbrightToggle", {
    Text = "Fullbright",
    Default = false,
    Callback = function(v)
        FullbrightEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then EnableFullbright() else DisableFullbright() end
    end
})

WorldGroup:AddToggle("GlobalShadowToggle", {
    Text = "Disable Global Shadows",
    Default = false,
    Callback = function(v) Lighting.GlobalShadows = not v end
})

WorldGroup:AddToggle("PotatoToggle", {
    Text = "Potato Graphics",
    Default = false,
    Tooltip = "SmoothPlastic all parts for FPS boost",
    Callback = function(v)
        PotatoEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then EnablePotato() else DisablePotato() end
    end
})

WorldGroup:AddButton({
    Text = "Remove Fog",
    Func = function()
        Lighting.FogEnd = 1e9; Lighting.FogStart = 1e9
        for _, v in ipairs(Lighting:GetDescendants()) do
            if v:IsA("Atmosphere") then v:Destroy() end
        end
        Notify("Visuals", "Fog removed!")
        BumpTelemetry("ButtonsPressed")
    end
})

WorldGroup:AddButton({
    Text = "Remove Post Effects",
    Func = function()
        for _, v in ipairs(Lighting:GetDescendants()) do
            if v:IsA("PostEffect") then v:Destroy() end
        end
        Notify("Visuals", "Post effects removed!")
        BumpTelemetry("ButtonsPressed")
    end
})

local CameraGroup = VisualsTab:AddRightGroupbox("Camera")

CameraGroup:AddSlider("FOVSlider", {
    Text = "Field of View",
    Default = 70, Min = 60, Max = 120, Rounding = 0,
    Callback = function(v) FOVValue = v; Camera.FieldOfView = v end
})

CameraGroup:AddSlider("MaxZoomSlider", {
    Text = "Max Zoom Distance",
    Default = 128, Min = 10, Max = 12800, Rounding = 0,
    Callback = function(v)
        MaxZoomDistance = v
        LocalPlayer.CameraMaxZoomDistance = v
    end
})

local EvalGroup = VisualsTab:AddRightGroupbox("Instance Path Evaluator")

EvalGroup:AddInput("EvalInput", {
    Default = "",
    Numeric = false,
    Finished = true,
    Text = "Instance Path / Expression",
    Placeholder = "e.g. workspace.Baseplate",
    Callback = function(v)
        if v and v ~= "" then EvaluateInstancePath(v) end
    end
})

EvalGroup:AddButton({
    Text = "Clear Highlights",
    Func = function()
        ClearInstanceHighlights()
        Notify("Evaluator", "Highlights cleared")
    end
})

-- ─────────────────────────────────────────────
-- TAB: TELEPORT & WAYPOINTS
-- ─────────────────────────────────────────────
local TeleportTab = Window:AddTab("Teleport")

local WPGroup = TeleportTab:AddLeftGroupbox("Waypoints (Max " .. MAX_WAYPOINTS .. ")")

WPGroup:AddInput("WPNameInput", {
    Default = "",
    Numeric = false,
    Finished = false,
    Text = "Waypoint Name",
    Placeholder = "Enter name..."
})

WPGroup:AddButton({
    Text = "Save Current Position",
    Func = function()
        local name = Options.WPNameInput.Value
        if not name or name == "" then Notify("WP", "Enter a name!"); return end
        -- PATCH #13: Count existing waypoints properly
        local count = 0
        for _ in pairs(Waypoints) do count += 1 end
        if not Waypoints[name] and count >= MAX_WAYPOINTS then
            Notify("WP", "Max " .. MAX_WAYPOINTS .. " waypoints reached!"); return
        end
        local root = GetRootPart()
        if root then
            Waypoints[name] = root.CFrame
            local wpNames = {}
            for n in pairs(Waypoints) do wpNames[#wpNames + 1] = n end
            Options.WPDropdown:SetValues(wpNames)
            Notify("WP", "Saved: " .. name)
            BumpTelemetry("ButtonsPressed")
        end
    end
})

WPGroup:AddDropdown("WPDropdown", {
    Values = {},
    Default = 1,
    Multi = false,
    Text = "Select Waypoint"
})

WPGroup:AddButton({
    Text = "TP to Waypoint",
    Func = function()
        local sel = Options.WPDropdown.Value
        if not sel or not Waypoints[sel] then Notify("WP", "No waypoint selected!"); return end
        local root = GetRootPart()
        if root then
            root.CFrame = Waypoints[sel]
            BumpTelemetry("TPsPerformed")
            Notify("WP", "TP'd to: " .. sel)
        end
    end
})

WPGroup:AddButton({
    Text = "Delete Waypoint",
    Func = function()
        local sel = Options.WPDropdown.Value
        if sel and Waypoints[sel] then
            Waypoints[sel] = nil
            local wpNames = {}
            for n in pairs(Waypoints) do wpNames[#wpNames + 1] = n end
            Options.WPDropdown:SetValues(wpNames)
            Notify("WP", "Deleted: " .. sel)
        end
    end
})

local SpawnGroup = TeleportTab:AddRightGroupbox("Spawn Locations")

SpawnGroup:AddButton({
    Text = "Refresh Spawn List",
    Func = function()
        local spawns = {}
        for _, obj in ipairs(Workspace:GetDescendants()) do
            if obj:IsA("SpawnLocation") then
                table.insert(spawns, obj:GetFullName())
            end
        end
        if #spawns == 0 then
            Notify("Spawns", "No SpawnLocations found!")
        else
            Options.SpawnDropdown:SetValues(spawns)
            Notify("Spawns", #spawns .. " spawns found!")
        end
        BumpTelemetry("ButtonsPressed")
    end
})

SpawnGroup:AddDropdown("SpawnDropdown", {
    Values = {},
    Default = 1,
    Multi = false,
    Text = "Select Spawn"
})

SpawnGroup:AddButton({
    Text = "TP to Spawn",
    Func = function()
        local sel = Options.SpawnDropdown.Value
        if not sel then Notify("Spawn", "No spawn selected!"); return end
        local success, spawn = pcall(function()
            return loadstring("return " .. sel)()
        end)
        if success and typeof(spawn) == "Instance" and spawn:IsA("SpawnLocation") then
            local root = GetRootPart()
            if root then
                root.CFrame = spawn.CFrame + Vector3.new(0, 5, 0)
                BumpTelemetry("TPsPerformed")
                Notify("Spawn", "TP'd to spawn!")
            end
        else
            Notify("Spawn", "Could not resolve spawn!")
        end
    end
})

local PosGroup = TeleportTab:AddRightGroupbox("Position & Axis Tools")

PosGroup:AddButton({
    Text = "Copy CFrame to Clipboard",
    Func = function()
        local root = GetRootPart()
        if root then
            local cf = root.CFrame
            local str = string.format("CFrame.new(%.2f, %.2f, %.2f)", cf.X, cf.Y, cf.Z)
            if setclipboard then
                setclipboard(str)
                Notify("Position", "CFrame copied: " .. str)
            else
                Notify("Position", "Clipboard not supported!")
            end
        end
        BumpTelemetry("ButtonsPressed")
    end
})

PosGroup:AddButton({
    Text = "Face North",
    Func = function()
        local root = GetRootPart()
        if root then
            root.CFrame = CFrame.new(root.Position) * CFrame.Angles(0, 0, 0)
            Notify("Position", "Now facing North!")
        end
        BumpTelemetry("ButtonsPressed")
    end
})

-- ─────────────────────────────────────────────
-- TAB: UTILITIES
-- ─────────────────────────────────────────────
local UtilTab = Window:AddTab("Utilities")

local MiscGroup = UtilTab:AddLeftGroupbox("Miscellaneous")

MiscGroup:AddButton({
    Text = "Anti AFK",
    Func = function()
        local vu = game:GetService("VirtualUser")
        RegisterConnection(LocalPlayer.Idled:Connect(function()
            vu:Button2Down(Vector2.zero, Camera.CFrame)
            task.wait(1)
            vu:Button2Up(Vector2.zero, Camera.CFrame)
        end))
        Notify("Misc", "Anti-AFK enabled!")
        BumpTelemetry("ButtonsPressed")
    end
})

MiscGroup:AddButton({
    Text = "Unlock FPS",
    Func = function()
        if setfpscap then setfpscap(0); Notify("Misc", "FPS unlocked!")
        else Notify("Misc", "Not supported!") end
        BumpTelemetry("ButtonsPressed")
    end
})

MiscGroup:AddButton({
    Text = "Copy Server Link",
    Func = function()
        if setclipboard then
            setclipboard("roblox://experiences/start?placeId=" .. game.PlaceId .. "&gameInstanceId=" .. game.JobId)
            Notify("Misc", "Server link copied!")
        end
        BumpTelemetry("ButtonsPressed")
    end
})

MiscGroup:AddButton({
    Text = "Rejoin Server",
    DoubleClick = true,
    Func = function()
        TeleportService:TeleportToPlaceInstance(game.PlaceId, game.JobId, LocalPlayer)
        BumpTelemetry("ButtonsPressed")
    end
})

local ScriptGroup = UtilTab:AddLeftGroupbox("Script Launchers")

ScriptGroup:AddButton({
    Text = "Run Infinite Yield",
    Func = function()
        BumpTelemetry("ButtonsPressed")
        loadstring(game:HttpGet("https://raw.githubusercontent.com/EdgeIY/infiniteyield/master/source"))()
    end,
    Tooltip = "Loads Infinite Yield admin script"
})

ScriptGroup:AddButton({
    Text = "Run UniversalSynSaveInstance",
    Func = function()
        BumpTelemetry("ButtonsPressed")
        loadstring(game:HttpGet("https://raw.githubusercontent.com/luau/SynSaveInstance/main/saveinstance.luau", true))()
    end,
    Tooltip = "Save game files"
})

local ActivityGroup = UtilTab:AddLeftGroupbox("Player Activity Logger")

ActivityGroup:AddToggle("ActivityLogToggle", {
    Text = "Log Player Join/Leave",
    Default = false,
    Callback = function(v)
        ActivityLogEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then ActivityModule:Enable() else ActivityModule:Disable() end
    end
})

local ScanGroup = UtilTab:AddRightGroupbox("Workspace Scanner")

ScanGroup:AddButton({
    Text = "Scan Workspace",
    Func = function()
        local result = ScanWorkspace()
        Notify("Scanner", result, 8)
        print("═══ WORKSPACE SCAN ═══\n" .. result .. "\n══════════════════════")
        BumpTelemetry("ButtonsPressed")
    end
})

local PerfGroup = UtilTab:AddRightGroupbox("Live Performance")

PerfGroup:AddToggle("PerfToggle", {
    Text = "Live Performance Tracker",
    Default = false,
    Tooltip = "Prints FPS/Ping/Memory to console every 5s",
    Callback = function(v) PerfTrackerEnabled = v; BumpTelemetry("TogglesUsed") end
})

local ChatGroup = UtilTab:AddRightGroupbox("Chat Spam")

ChatGroup:AddInput("ChatMsgInput", {
    Default = "Hello!",
    Numeric = false,
    Finished = false,
    Text = "Spam Message",
    Placeholder = "Enter message...",
    Callback = function(v) ChatSpamMessage = v end
})

ChatGroup:AddSlider("ChatDelaySlider", {
    Text = "Delay (seconds)",
    Default = 2, Min = 0.5, Max = 30, Rounding = 1,
    Callback = function(v) ChatSpamDelay = v end
})

-- PATCH #10: Generation counter to kill stale coroutines
ChatGroup:AddToggle("ChatSpamToggle", {
    Text = "Chat Spam",
    Default = false,
    Callback = function(v)
        ChatSpamEnabled = v
        BumpTelemetry("TogglesUsed")
        if v then
            ChatSpamGeneration += 1
            local myGen = ChatSpamGeneration
            task.spawn(function()
                while ChatSpamEnabled and ChatSpamGeneration == myGen do
                    pcall(function()
                        local events = ReplicatedStorage:FindFirstChild("DefaultChatSystemChatEvents")
                        if events then
                            local say = events:FindFirstChild("SayMessageRequest")
                            if say then say:FireServer(ChatSpamMessage, "All") end
                        end
                    end)
                    task.wait(ChatSpamDelay)
                end
            end)
        else
            -- Bump generation to kill any running coroutine
            ChatSpamGeneration += 1
        end
    end
})

-- ─────────────────────────────────────────────
-- TAB: SETTINGS
-- ─────────────────────────────────────────────
local SettingsTab = Window:AddTab("Settings")

local MenuGroup = SettingsTab:AddLeftGroupbox("Menu")

MenuGroup:AddToggle("ShowKeybinds", {
    Text = "Show Keybind List",
    Default = false,
    Callback = function(v) Library:SetKeybindVisibility(v) end
})

MenuGroup:AddLabel("Menu Toggle Key"):AddKeyPicker("MenuKeybind", {
    Default = "RightControl",
    SyncToggleState = false,
    Mode = "Toggle",
    Text = "Menu Toggle",
})

MenuGroup:AddButton({
    Text = "Unload Script",
    DoubleClick = true,
    Func = function()
        -- ═══ FULL CLEANUP ═══

        -- Disable all modules
        ESPModule:DisableAll()
        NPCESPModule:Clear()
        FlyModule:Disable()
        FloatModule:Disable()
        SpectateModule:Disable()
        LowHPModule:Disable()
        DeathLogModule:Disable()
        ActivityModule:Disable()

        -- Drawing objects
        AimbotModule:DestroyFOVCircle()

        -- Visuals
        if FullbrightEnabled then DisableFullbright() end
        if PotatoEnabled then DisablePotato() end

        -- World state
        if NoVoidEnabled and NoVoidOriginal then
            Workspace.FallenPartsDestroyHeight = NoVoidOriginal
        end
        if CustomGravityEnabled then Workspace.Gravity = 196.2 end

        -- Tools
        if TPTool then SafeDestroy(TPTool); TPTool = nil end

        -- Instance highlights
        ClearInstanceHighlights()

        -- Character state
        local hum = GetHumanoid()
        if hum then
            hum.WalkSpeed = 16
            hum.JumpPower = 50
            hum.MaxSlopeAngle = 89
            if GodModeEnabled then
                hum.MaxHealth = 100
                hum.Health = 100
            end
        end

        -- Kill chat spam coroutine
        ChatSpamEnabled = false
        ChatSpamGeneration += 1

        -- Disconnect ALL registered connections
        CleanupAllConnections()

        -- Clear data tables
        table.clear(DeathLogs)
        table.clear(Waypoints)
        table.clear(LowHPCooldowns)

        Library:Unload()
        print("[persistence.win] Fully unloaded — all connections and instances cleaned up.")
    end
})

local SoundGroup = SettingsTab:AddLeftGroupbox("Sound Customization")

SoundGroup:AddInput("SoundLowHPInput", {
    Default = SoundLowHP,
    Numeric = false,
    Finished = true,
    Text = "Low HP Sound ID",
    Callback = function(v) SoundLowHP = v end
})

SoundGroup:AddInput("SoundLeftInput", {
    Default = SoundLeft,
    Numeric = false,
    Finished = true,
    Text = "Player Left Sound ID",
    Callback = function(v) SoundLeft = v end
})

SoundGroup:AddInput("SoundGeneralInput", {
    Default = SoundGeneral,
    Numeric = false,
    Finished = true,
    Text = "General Sound ID",
    Callback = function(v) SoundGeneral = v end
})

SoundGroup:AddSlider("SoundVolumeSlider", {
    Text = "Sound Volume",
    Default = 0.5, Min = 0, Max = 2, Rounding = 2,
    Callback = function(v) SoundVolume = v end
})

SoundGroup:AddButton({
    Text = "Test Sound",
    Func = function() PlaySound(SoundGeneral, SoundVolume) end
})

local TelemetryGroup = SettingsTab:AddRightGroupbox("Telemetry & Stats")

TelemetryGroup:AddToggle("TelemetryToggle", {
    Text = "Enable Telemetry Logging",
    Default = false,
    Callback = function(v) TelemetryEnabled = v end
})

TelemetryGroup:AddButton({
    Text = "Print Telemetry to Console (F9)",
    Func = function()
        local elapsed = os.time() - TelemetryData.SessionStart
        local mins = math.floor(elapsed / 60)
        print("═══ persistence.win TELEMETRY ═══")
        print("Session Duration: " .. mins .. " minutes")
        print("Toggles Used: " .. TelemetryData.TogglesUsed)
        print("Buttons Pressed: " .. TelemetryData.ButtonsPressed)
        print("TPs Performed: " .. TelemetryData.TPsPerformed)
        print("Active Connections: " .. #MasterConnections)
        print("ESP Objects: " .. (function() local c=0; for _ in pairs(ESPObjects) do c+=1 end; return c end)())
        print("NPC ESP Objects: " .. #NPCESPObjects)
        print("Death Logs: " .. #DeathLogs)
        print("Waypoints: " .. (function() local c=0; for _ in pairs(Waypoints) do c+=1 end; return c end)())
        print("═════════════════════════════════")
        Notify("Telemetry", "Stats printed to console (F9)")
    end
})

local ThemeGroup = SettingsTab:AddRightGroupbox("Theme & Config")

ThemeManager:SetLibrary(Library)
SaveManager:SetLibrary(Library)
SaveManager:IgnoreThemeSettings()
SaveManager:SetIgnoreIndexes({"MenuKeybind"})
ThemeManager:SetFolder("PersistenceWin")
SaveManager:SetFolder("PersistenceWin/configs")

SaveManager:BuildConfigSection(SettingsTab)
ThemeManager:ApplyToTab(SettingsTab)

-- ============================================================
-- INPUT CONNECTIONS (all registered)
-- ============================================================

RegisterConnection(UserInputService.JumpRequest:Connect(function()
    if InfiniteJumpEnabled then
        local hum = GetHumanoid()
        if hum then hum:ChangeState(Enum.HumanoidStateType.Jumping) end
    end
end))

RegisterConnection(UserInputService.InputBegan:Connect(function(input, gpe)
    if gpe then return end
    if ClickTPEnabled and input.UserInputType == Enum.UserInputType.MouseButton1 then
        if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
            local root = GetRootPart()
            if root and Mouse.Hit then
                root.CFrame = CFrame.new(Mouse.Hit.Position + Vector3.new(0, 3, 0))
                BumpTelemetry("TPsPerformed")
            end
        end
    end
    if input.KeyCode == Enum.KeyCode.Q then FloatMovingUp = true end
    if input.KeyCode == Enum.KeyCode.E then FloatMovingDown = true end
end))

RegisterConnection(UserInputService.InputEnded:Connect(function(input)
    if input.KeyCode == Enum.KeyCode.Q then FloatMovingUp = false end
    if input.KeyCode == Enum.KeyCode.E then FloatMovingDown = false end
end))

-- ============================================================
-- PLAYER CONNECTIONS (all registered, keyed per player) — PATCH #16, #17
-- ============================================================

local function SetupPlayerConnections(player)
    if player == LocalPlayer then return end

    -- PATCH #17: Clean old connections if player somehow re-triggers
    CleanupPlayerConnections(player)

    RegisterPlayerConnection(player, player.CharacterAdded:Connect(function(char)
        task.wait(1)
        if ESPEnabled then ESPModule:AttachESP(player) end
        -- Re-hook death logger if enabled
        if DeathLogEnabled and not DeathConnections[player] then
            DeathLogModule:Watch(player)
        end
        -- Re-hook low HP if enabled
        if LowHPEnabled and not LowHPConnections[player] then
            LowHPModule:Watch(player)
        end
    end))
end

for _, player in ipairs(Players:GetPlayers()) do
    SetupPlayerConnections(player)
end

RegisterConnection(Players.PlayerAdded:Connect(function(player)
    SetupPlayerConnections(player)
    if ESPEnabled then
        task.wait(1)
        ESPModule:CreateESP(player)
    end
    if DeathLogEnabled then DeathLogModule:Watch(player) end
    if LowHPEnabled then LowHPModule:Watch(player) end
end))

RegisterConnection(Players.PlayerRemoving:Connect(function(player)
    ESPModule:RemoveESP(player)
    CleanupPlayerConnections(player)
    DeathLogModule:Unwatch(player)
    LowHPModule:Unwatch(player)

    -- PATCH #6: Auto-disable latch if target leaves
    if LatchEnabled and LatchTarget == player then
        LatchEnabled = false
        LatchTarget = nil
        local mr = GetRootPart()
        if mr and LatchOrigin then mr.CFrame = LatchOrigin end
        LatchOrigin = nil
        if Toggles and Toggles.LatchToggle then Toggles.LatchToggle:SetValue(false) end
        Notify("Latch", "Target left, latch disabled — returned to origin")
    end

    -- PATCH #7: Auto-disable spectate if target leaves
    if SpectateEnabled and SpectateTarget == player then
        SpectateModule:Disable()
        SpectateEnabled = false
        if Toggles and Toggles.SpectateToggle then Toggles.SpectateToggle:SetValue(false) end
        Notify("Spectate", "Target left, spectate disabled")
    end
end))

-- Local player respawn
RegisterConnection(LocalPlayer.CharacterAdded:Connect(function()
    task.wait(1)
    if FlyEnabled then FlyModule:Enable() end
    if FloatEnabled then FloatModule:Enable() end
    if SpeedEnabled then
        local hum = GetHumanoid()
        if hum then hum.WalkSpeed = SpeedValue end
    end
    if GodModeEnabled then
        local hum = GetHumanoid()
        if hum then hum.MaxHealth = math.huge; hum.Health = math.huge end
    end
    if MaxSlopeEnabled then
        local hum = GetHumanoid()
        if hum then hum.MaxSlopeAngle = 360 end
    end
    if SpectateEnabled and SpectateTarget then
        SpectateModule:CreateBeam()
    end
end))

-- ============================================================
-- INITIALIZE AIMBOT
-- ============================================================
AimbotModule:CreateFOVCircle()

-- ============================================================
-- MAIN RENDER LOOP (single connection, registered)
-- ============================================================

local perfPrintTimer = 0

RegisterConnection(RunService.RenderStepped:Connect(function(dt)
    -- Speed
    if SpeedEnabled then
        local hum = GetHumanoid()
        if hum then hum.WalkSpeed = SpeedValue end
    end

    -- Custom Gravity
    if CustomGravityEnabled then
        Workspace.Gravity = CustomGravityValue
    end

    -- Instant Stop
    InstantStopUpdate()

    -- Noclip
    NoclipUpdate()

    -- Fly
    FlyModule:Update()

    -- Float Platform
    FloatModule:Update()

    -- ESP
    if ESPEnabled then ESPModule:UpdateESP() end

    -- NPC ESP
    if NPCESPEnabled then NPCESPModule:Update() end

    -- Aimbot
    AimbotModule:UpdateFOVCircle()
    if AimbotEnabled and UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) then
        local target = AimbotModule:GetClosestPlayer()
        if target then AimbotModule:AimAt(target) end
    end

    -- Fullbright maintenance
    if FullbrightEnabled then
        Lighting.Ambient = Color3.fromRGB(178, 178, 178)
        Lighting.Brightness = 2
        Lighting.FogEnd = 100000
        Lighting.GlobalShadows = false
    end

    -- PATCH #6: Latch follow with validity check
    if LatchEnabled and LatchTarget then
        if not LatchTarget.Parent then
            -- Player left
            LatchEnabled = false
            local mr = GetRootPart()
            if mr and LatchOrigin then mr.CFrame = LatchOrigin end
            LatchTarget = nil; LatchOrigin = nil
            if Toggles and Toggles.LatchToggle then Toggles.LatchToggle:SetValue(false) end
        else
            local myRoot = GetRootPart()
            local tChar = LatchTarget.Character
            if tChar and myRoot then
                local tRoot = tChar:FindFirstChild("HumanoidRootPart")
                if tRoot then
                    myRoot.CFrame = tRoot.CFrame * CFrame.new(0, 0, 3)
                end
            end
        end
    end

    -- PATCH #7: Spectate validation
    SpectateModule:Validate()

    -- PATCH #19: Performance tracker using dt instead of RenderStepped:Wait()
    if PerfTrackerEnabled then
        FPSAccumulator += dt
        FPSFrameCount += 1

        perfPrintTimer += dt
        if perfPrintTimer >= 5 then
            perfPrintTimer = 0
            local avgFPS = FPSFrameCount > 0 and math.floor(FPSFrameCount / FPSAccumulator) or 0
            FPSAccumulator = 0
            FPSFrameCount = 0

            local ping = 0
            pcall(function()
                ping = math.floor(Stats.Network.ServerStatsItem["Data Ping"]:GetValue())
            end)
            local mem = 0
            pcall(function()
                mem = math.floor(Stats:GetTotalMemoryUsageMb())
            end)
            warn(string.format("[persistence.win Perf] FPS: %d | Ping: %dms | Memory: %dMB", avgFPS, ping, mem))
        end
    end
end))

-- ============================================================
-- SET MENU TOGGLE KEYBIND
-- ============================================================
Library.ToggleKeybind = Options.MenuKeybind

-- ============================================================
-- STARTUP
-- ============================================================
Notify("persistence.win", "Loaded! RightControl to toggle menu.", 5)
PlaySound(SoundGeneral, SoundVolume)

print("[persistence.win] All modules loaded successfully!")
print("[persistence.win] join to suggest: discord.gg/MU4W3uPf9p")
print("[persistence.win] credits to ai")
print("Tabs: Movement | Combat | Players | Visuals | Teleport | Utilities | Settings")

How to Execute Universal Script – persistence.win universal (Keyless)

Step 1: Copy Code: Click the Copy Code button in the viewer above to grab the clean Lua loadstring.

Step 2: Launch Executor: Open a compatible, unpatched executor. If you need one, check our Roblox Executors Directory.

Step 3: Join Experience: Launch Roblox and join Universal Script.

Step 4: Attach & Run: Attach/inject your executor into the Roblox process, paste the code into the script tab, and press Execute.

Created By

persistence
persistence
Script Creator
View Author Profile

Features & Information

Execute Universal Script – persistence.win universal (Keyless). Key system required, created by persistence, updated Oct 21, 2026. Tested and working on supported executors.
#open source#universal#aimbot#esp#keyless

Script Changelog (1)

@persistenceOct 21, 2026

Create script

Community Comments (3)

persistencepersistenceOct 24, 2026

Any issues with the script? I guarantee you some of the features don't work as intended so inform me so I can fix it.

Replying to @persistence

@persistence is there god mode?

Replying to @HEEHSHVJHGXVHJGXVNG
persistencepersistenceOct 25, 2026

@HEEHSHVJHGXVHJGXVNG I think so, but I'm pretty sure it doesn't work.

Frequently Asked Questions

How do I execute Universal Script – persistence.win universal (Keyless) in Roblox?

To run Universal Script – persistence.win universal (Keyless), copy the Lua loadstring from the code viewer above, launch Roblox and join Universal Script, attach a working executor (such as Potassium, Solara, or Delta from our Executors directory), paste the code into your executor console, and click Execute.

Is Universal Script – persistence.win universal (Keyless) keyless or does it require an access key?

Universal Script – persistence.win universal (Keyless) requires an access key. You can retrieve the official key directly using the Get Script Key link provided above.

Is Universal Script – persistence.win universal (Keyless) currently safe and working?

This script is active and operational. Always test scripts using a secondary (alt) Roblox account to safeguard your main profile against anti-cheat bans.