if game.PlaceId ~= 205224386 then warn('[luna.dev] this script is for hide and seek extreme (205224386).') return end local players = game:GetService('Players') local replicatedstorage = game:GetService('ReplicatedStorage') local runservice = game:GetService('RunService') local userinputservice = game:GetService('UserInputService') local lighting = game:GetService('Lighting') local collectionservice = game:GetService('CollectionService') local httpservice = game:GetService('HttpService') local tweenservice = game:GetService('TweenService') local marketplace = game:GetService('MarketplaceService') local statsservice = game:GetService('Stats') local virtualuser = game:GetService('VirtualUser') local teleportservice = game:GetService('TeleportService') local localplayer = players.LocalPlayer local playergui = localplayer:WaitForChild('PlayerGui') local gamedata = replicatedstorage:WaitForChild('GameData', 12) if not gamedata then warn('[luna.dev] game data is unavailable.') return end for _, name in ipairs({ 'luna_hide_and_seek_extreme', 'luna_early_it_display' }) do local old = playergui:FindFirstChild(name) if old then old:Destroy() end end local palette = { background = Color3.fromRGB(13, 11, 21), side = Color3.fromRGB(17, 14, 28), surface = Color3.fromRGB(20, 17, 32), card = Color3.fromRGB(26, 22, 41), raised = Color3.fromRGB(36, 29, 55), accent = Color3.fromRGB(180, 142, 255), accentmid = Color3.fromRGB(112, 82, 190), accentdark = Color3.fromRGB(62, 42, 100), border = Color3.fromRGB(50, 42, 70), text = Color3.fromRGB(238, 233, 248), muted = Color3.fromRGB(172, 162, 192), dim = Color3.fromRGB(125, 112, 150), lilac = Color3.fromRGB(214, 188, 255), success = Color3.fromRGB(130, 209, 177), danger = Color3.fromRGB(243, 159, 173), gold = Color3.fromRGB(255, 211, 102), portal = Color3.fromRGB(87, 218, 245), jump = Color3.fromRGB(107, 233, 169), glue = Color3.fromRGB(247, 163, 88), camera = Color3.fromRGB(239, 148, 237) } local alive = true local connections, cleanups = {}, {} local started_at = os.clock() local S = { selected = nil, spectating = nil, return_cframe = nil, minimized = false, afk_pulses = 0, last_pulse = os.clock(), fling_active = false } local settings = { esp = true, labels = true, distance = true, credit_esp = true, teleporter_esp = true, fullbright = false, speed = true, jump = true, noclip = false, infinite_jump = false, auto_seek = false, auto_credits = false, auto_evade = false, pull_credits = false, pull_lobby = false, it_no_cooldown = false, it_keep_active = false, early_it = true, jump_pad_esp = true, seeker_radius_esp = true, closest_credit_esp = true, camera_esp = true, glue_esp = true, seeker_warning_distance = 45, auto_buy = false, auto_farm = false, anti_afk = true, auto_server_hop = true } local initial_humanoid = localplayer.Character and localplayer.Character:FindFirstChildOfClass('Humanoid') local move = { speed = math.floor(((initial_humanoid and initial_humanoid.WalkSpeed or 16) * 1.06) * 10 + 0.5) / 10, jump = math.floor(((initial_humanoid and initial_humanoid.JumpPower or 50) * 1.06) * 10 + 0.5) / 10, subtle_speed = true, subtle_jump = true } local V = { overlays = {}, credits = {}, tele = {}, hz = { jump = {}, glue = {}, camera = {} } } local M = { collisions = {}, baselines = setmetatable({}, { __mode = 'k' }) } local F = { pulled_credits = {}, loop_origin = nil, credit_attempts = 0, pull_credit_attempts = 0, lobby_targets = 0, pull_ticks = 0, lobby_cursor = 0, lobby_target = nil, lobby_started = 0, last_touch = 0, credit_inflight = false, verified_gains = 0, credit_last = nil, safe_positions = {}, last_safe = 0, last_escape = 0, last_notice = 0 } local A = { handler = nil, set_original = nil, mark_original = nil, set_hook = nil, mark_hook = nil, active = false, active_known = false, last_clear = 0, intercepts = 0, clears = 0, err = nil, attempts = 0, name = 'Unknown', last_result = 'Not tested', last_attempt = 0, sprint_first = nil, last_character = nil, practice_end = 0, practice_camera = nil, objects = {} } local recent_credits = setmetatable({}, { __mode = 'k' }) local storage = { path = 'luna.dev/scripts/hide_and_seek_extreme.json', revision = 0, loaded = false } storage.state = 'Settings will be saved in ' .. storage.path do local defaults = {} for key, value in pairs(settings) do defaults[key] = value end storage.defaults = defaults local function available() return type(readfile) == 'function' and type(writefile) == 'function' and type(makefolder) == 'function' end local function ensure_directories() if not available() then return false end for _, directory in ipairs({ 'luna.dev', 'luna.dev/scripts' }) do if type(isfolder) ~= 'function' or not isfolder(directory) then local ok = pcall(makefolder, directory) if not ok and type(isfolder) == 'function' and not isfolder(directory) then return false end end end return true end local function apply(saved) if type(saved) ~= 'table' or saved.schema ~= 1 or type(saved.options) ~= 'table' then return false end for key, original in pairs(defaults) do local value = saved.options[key] if type(value) == type(original) then settings[key] = key == 'seeker_warning_distance' and math.clamp(value, 10, 150) or value end end if type(saved.speed_value) == 'number' then move.speed = math.clamp(saved.speed_value, 0, 150) end if type(saved.jump_value) == 'number' then move.jump = math.clamp(saved.jump_value, 0, 200) end if type(saved.subtle_speed) == 'boolean' then move.subtle_speed = saved.subtle_speed end if type(saved.subtle_jump) == 'boolean' then move.subtle_jump = saved.subtle_jump end return true end local function load() if not available() then storage.state = 'File APIs unavailable in this executor; settings only last for this session.' return false end local ok, content = pcall(readfile, storage.path) if not ok then storage.state = 'No saved settings found; preferences will be saved automatically.' return false end local decoded, data = pcall(httpservice.JSONDecode, httpservice, content) if decoded and apply(data) then storage.loaded = true storage.state = 'Restored saved preferences from ' .. storage.path return true end storage.state = 'Settings file is invalid; defaults were used.' return false end function storage.save() if not ensure_directories() then storage.state = 'Could not create settings folder; check executor file access.' if storage.label and storage.label.Parent then storage.label.Text = storage.state end return false end local options = {} for key in pairs(defaults) do options[key] = settings[key] end local encoded, result = pcall(httpservice.JSONEncode, httpservice, { schema = 1, options = options, speed_value = move.speed, jump_value = move.jump, subtle_speed = move.subtle_speed, subtle_jump = move.subtle_jump }) if not encoded then storage.state = 'Unable to encode settings.' return false end local ok = pcall(writefile, storage.path, result) storage.state = ok and ('Saved preferences to ' .. storage.path) or 'Could not write settings file.' if storage.label and storage.label.Parent then storage.label.Text = storage.state end return ok end function storage.schedule() storage.revision += 1 local revision = storage.revision task.delay(0.65, function() if alive and revision == storage.revision then storage.save() end end) end load() settings.auto_buy = false end local original_lighting = { Brightness = lighting.Brightness, ClockTime = lighting.ClockTime, FogEnd = lighting.FogEnd, GlobalShadows = lighting.GlobalShadows, Ambient = lighting.Ambient, OutdoorAmbient = lighting.OutdoorAmbient } local function bind(signal, callback) local connection = signal:Connect(callback) table.insert(connections, connection) return connection end local function every(interval, callback) local acc = 0 bind(runservice.Heartbeat, function(dt) if not alive then return end acc += dt if acc >= interval then local elapsed = acc acc = 0 callback(elapsed) end end) end local function new(class, props, parent) local obj = Instance.new(class) for property, value in pairs(props or {}) do obj[property] = value end obj.Parent = parent return obj end local function round(parent, radius) return new('UICorner', { CornerRadius = UDim.new(0, radius or 6) }, parent) end local function stroke(parent, color, transparency) return new('UIStroke', { Color = color or palette.border, Thickness = 1, Transparency = transparency or 0.2, ApplyStrokeMode = Enum.ApplyStrokeMode.Border }, parent) end local function text(parent, content, size, color, props) local options = { BackgroundTransparency = 1, Text = content, Font = Enum.Font.Gotham, TextSize = size or 12, TextColor3 = color or palette.text, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Center } for key, value in pairs(props or {}) do options[key] = value end return new('TextLabel', options, parent) end local function button(parent, content, pos, size, callback, accent) local control = new('TextButton', { Position = pos, Size = size, BackgroundColor3 = accent and palette.accentdark or palette.raised, BorderSizePixel = 0, Text = content, TextSize = 11, Font = Enum.Font.GothamMedium, TextColor3 = palette.text, AutoButtonColor = true }, parent) round(control, 5) stroke(control, accent and palette.accent or palette.border) bind(control.MouseButton1Click, callback) return control end local function nextorder(parent) local n = (parent:GetAttribute('order') or 0) + 1 parent:SetAttribute('order', n) return n end local renderers = {} local function register_render(key, fn) renderers[key] = renderers[key] or {} table.insert(renderers[key], fn) end local function update_toggle(key) for _, fn in ipairs(renderers[key] or {}) do fn() end end local ui = {} local logs = {} local function notify(message) if not alive then return end table.insert(logs, os.date('%H:%M:%S') .. ' ' .. message) if #logs > 80 then table.remove(logs, 1) end if ui.message then ui.message.Text = message end if ui.refresh_log then ui.refresh_log() end end local function getdata(player, field) local data = player and player:FindFirstChild('PlayerData') local entry = data and data:FindFirstChild(field) return entry and entry.Value end local function ingame(player) return getdata(player, 'InGame') == true end local function isit(player) if getdata(player, 'It') == true then return true end local it = gamedata:FindFirstChild('It') local obj = it and it:FindFirstChild('PlayerObject') return obj and obj.Value == player or false end local function getit() local it = gamedata:FindFirstChild('It') local obj = it and it:FindFirstChild('PlayerObject') if obj and obj.Value and obj.Value:IsA('Player') then return obj.Value end for _, player in ipairs(players:GetPlayers()) do if getdata(player, 'It') == true then return player end end end local function getroot(player) local character = player and player.Character if not character then return nil end local root = character:FindFirstChild('HumanoidRootPart') local humanoid = character:FindFirstChildOfClass('Humanoid') if root and humanoid and humanoid.Health > 0 then return root, humanoid end end local function role_of(player) return isit(player) and 'IT' or (ingame(player) and 'HIDER' or 'LOBBY') end local function color_of(player) return isit(player) and palette.danger or (ingame(player) and palette.accent or palette.muted) end local function nearest_hider() local mine = getroot(localplayer) if not mine then return nil end local closest, distance for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and ingame(player) and not isit(player) then local root = getroot(player) if root then local d = (root.Position - mine.Position).Magnitude if not distance or d < distance then closest, distance = player, d end end end end return closest end local function find_nearest_credit(skip_recent) local container = workspace:FindFirstChild('GameObjects') local mine = getroot(localplayer) if not container or not mine then return nil end local chosen, best local now = os.clock() for _, part in ipairs(container:GetChildren()) do if part.Name == 'Credit' and part:IsA('BasePart') and part.Parent then local collected = part:FindFirstChild('Collected') if (not collected or not collected.Value) and (not skip_recent or now - (recent_credits[part] or -100) > 2.5) then local distance = (mine.Position - part.Position).Magnitude if not best or distance < best then chosen, best = part, distance end end end end return chosen end local function next_lobby_target() local options = {} for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and not isit(player) and not ingame(player) and getroot(player) then table.insert(options, player) end end if #options == 0 then return nil end table.sort(options, function(a, b) return a.UserId < b.UserId end) F.lobby_cursor = F.lobby_cursor % #options + 1 return options[F.lobby_cursor] end local function part_of(object) if object:IsA('BasePart') then return object end if object:IsA('Model') then return object:FindFirstChildWhichIsA('BasePart', true) end end local function restore_camera() S.spectating = nil local _, humanoid = getroot(localplayer) if workspace.CurrentCamera and humanoid then workspace.CurrentCamera.CameraSubject = humanoid end end local function teleport(player) if not player then notify('No target selected.'); return false end local myroot = getroot(localplayer) local targetroot = getroot(player) if not myroot or not targetroot then notify('One of the characters is not available.'); return false end if isit(player) and not isit(localplayer) then notify('Teleport blocked: target is It.'); return false end S.return_cframe = myroot.CFrame myroot.AssemblyLinearVelocity = Vector3.zero myroot.CFrame = targetroot.CFrame * CFrame.new(0, 1.5, 3.5) notify('Teleported to ' .. player.Name .. '.') return true end local gui = new('ScreenGui', { Name = 'luna_hide_and_seek_extreme', ResetOnSpawn = false, IgnoreGuiInset = true, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 500 }, playergui) ui.seeker_warning = text(gui, '', 12, palette.text, { Name = 'SeekerWarning', AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -15, 0, 65), Size = UDim2.fromOffset(250, 30), TextXAlignment = Enum.TextXAlignment.Right, TextStrokeTransparency = 0.15, TextStrokeColor3 = Color3.new(0, 0, 0), Font = Enum.Font.GothamBold, ZIndex = 200, Visible = false }) ui.closest_line = new('Frame', { Name = 'ClosestCreditLine', BackgroundColor3 = palette.gold, BorderSizePixel = 0, Size = UDim2.fromOffset(0, 2), AnchorPoint = Vector2.new(0.5, 0.5), Visible = false, ZIndex = 190 }, gui) ui.closest_label = text(gui, '', 11, palette.gold, { Name = 'ClosestCreditLabel', Size = UDim2.fromOffset(225, 25), TextStrokeTransparency = 0.2, TextStrokeColor3 = Color3.new(0, 0, 0), Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 191, Visible = false }) local early_gui = new('ScreenGui', { Name = 'luna_early_it_display', ResetOnSpawn = false, IgnoreGuiInset = true, DisplayOrder = 10000, ZIndexBehavior = Enum.ZIndexBehavior.Global }, playergui) local early_banner = new('Frame', { AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0.07, 0), Size = UDim2.fromOffset(320, 36), BackgroundColor3 = palette.background, BackgroundTransparency = 0.06, Visible = false, BorderSizePixel = 0, ZIndex = 100 }, early_gui) round(early_banner, 8) stroke(early_banner, palette.accent) local early_text = text(early_banner, 'SELECTING IT...', 12, palette.gold, { Size = UDim2.fromScale(1, 1), Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 101 }) local function clear_entry(entry) for _, key in ipairs({ 'highlight', 'box', 'billboard' }) do if entry[key] then entry[key]:Destroy() end end end local function clear_store(store) for key, entry in pairs(store) do clear_entry(entry) store[key] = nil end end local function mark(store, key, part, o) local entry = store[key] if entry and (entry.part ~= part or not entry.box or not entry.box.Parent or not entry.billboard or not entry.billboard.Parent) then clear_entry(entry) entry = nil end if not entry then entry = { part = part } if o.highlight then entry.highlight = new('Highlight', { Name = 'luna_mark_highlight', Adornee = part, FillColor = o.color, OutlineColor = o.color, FillTransparency = o.fill or 0.45, OutlineTransparency = 0, DepthMode = Enum.HighlightDepthMode.AlwaysOnTop }, part) end local pad = o.pad or 0.35 entry.box = new('BoxHandleAdornment', { Name = 'luna_mark_box', Adornee = part, AlwaysOnTop = true, Size = part.Size + Vector3.new(pad, pad, pad), Color3 = o.color, Transparency = o.box_t or 0.58, ZIndex = 6 }, part) entry.billboard = new('BillboardGui', { Name = 'luna_mark_label', Adornee = part, AlwaysOnTop = true, Size = UDim2.fromOffset(o.width or 190, o.height or 43), StudsOffsetWorldSpace = Vector3.new(0, math.max(2, part.Size.Y * 0.5 + 1.3), 0), MaxDistance = 25000, LightInfluence = 0 }, gui) entry.label = text(entry.billboard, '', o.text_size or 11, o.color, { Size = UDim2.fromScale(1, 1), Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Center, TextWrapped = true, TextStrokeTransparency = 0.15, TextStrokeColor3 = Color3.new(0, 0, 0) }) store[key] = entry end entry.label.Text = o.caption end local function sweep(store, visible) for key, entry in pairs(store) do if not visible[key] or not entry.part or not entry.part:IsDescendantOf(workspace) then clear_entry(entry) store[key] = nil end end end local function studs(from_root, part) return from_root and (math.floor((from_root.Position - part.Position).Magnitude + 0.5) .. ' studs') or nil end function V.clear_overlay(player) local entry = V.overlays[player] if entry then clear_entry(entry) V.overlays[player] = nil end end function V.clear_players() for player in pairs(V.overlays) do V.clear_overlay(player) end end function V.clear_seeker_radius() if V.sphere then V.sphere:Destroy(); V.sphere = nil end ui.seeker_warning.Visible = false end function V.clear_closest_line() ui.closest_line.Visible = false ui.closest_label.Visible = false end function V.restore_lighting() for property, value in pairs(original_lighting) do lighting[property] = value end end function V.sync_players() local valid = {} local mine = getroot(localplayer) for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer then valid[player] = true local character = player.Character local root = getroot(player) if settings.esp and character and root then local entry = V.overlays[player] if not entry or entry.character ~= character or not entry.highlight or not entry.highlight.Parent then V.clear_overlay(player) entry = { character = character } entry.highlight = new('Highlight', { Name = 'luna_player_esp', Adornee = character, FillTransparency = 0.7, OutlineTransparency = 0, DepthMode = Enum.HighlightDepthMode.AlwaysOnTop }, character) V.overlays[player] = entry end local color = color_of(player) entry.highlight.FillColor = color entry.highlight.OutlineColor = color if not entry.box or not entry.box.Parent or entry.box.Adornee ~= root then if entry.box then entry.box:Destroy() end entry.box = new('BoxHandleAdornment', { Name = 'luna_player_box', Adornee = root, AlwaysOnTop = true, Size = Vector3.new(3.5, 6, 3.5), Transparency = 0.92, ZIndex = 5 }, root) end entry.box.Color3 = color local head = character:FindFirstChild('Head') or root if settings.labels then if not entry.billboard or entry.billboard.Adornee ~= head then if entry.billboard then entry.billboard:Destroy() end entry.billboard = new('BillboardGui', { Name = 'luna_player_label', Adornee = head, AlwaysOnTop = true, Size = UDim2.fromOffset(215, 44), StudsOffsetWorldSpace = Vector3.new(0, 3, 0), MaxDistance = 25000 }, head) text(entry.billboard, '', 12, color, { Size = UDim2.fromScale(1, 1), Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Center, TextWrapped = true, TextStrokeTransparency = 0.2, TextStrokeColor3 = Color3.new(0, 0, 0) }) end local display = entry.billboard:FindFirstChildOfClass('TextLabel') if display then local suffix = '' if settings.distance and mine then suffix = ' | ' .. math.floor((mine.Position - root.Position).Magnitude) .. ' studs' end display.Text = player.DisplayName .. '\n' .. role_of(player) .. suffix display.TextColor3 = color end elseif entry.billboard then entry.billboard:Destroy() entry.billboard = nil end else V.clear_overlay(player) end end end for player in pairs(V.overlays) do if not valid[player] then V.clear_overlay(player) end end end function V.sync_credits() if not settings.credit_esp then return end local container = workspace:FindFirstChild('GameObjects') local visible = {} local mine = getroot(localplayer) if container then for _, part in ipairs(container:GetChildren()) do if part.Name == 'Credit' and part:IsA('BasePart') and part.Parent then local collected = part:FindFirstChild('Collected') if not collected or not collected.Value then visible[part] = true local d = studs(mine, part) mark(V.credits, part, part, { color = palette.gold, caption = 'CREDIT' .. (d and ('\n' .. d) or ''), highlight = true, fill = 0.3, box_t = 0.63, pad = 0.5, text_size = 12, width = 145, height = 38 }) end end end end sweep(V.credits, visible) end function V.sync_teleporters() if not settings.teleporter_esp then return end local registry = gamedata:FindFirstChild('Teleporters') local visible = {} local mine = getroot(localplayer) if registry then for _, object in ipairs(registry:GetChildren()) do local pad = object:IsA('ObjectValue') and object.Value if pad and pad:IsA('BasePart') and pad:IsDescendantOf(workspace) then local linked = pad:FindFirstChild('LinkedTeleporter') local destination = linked and linked:IsA('ObjectValue') and linked.Value local name = destination and destination:IsA('BasePart') and destination:IsDescendantOf(workspace) and destination.Name or '?' local d = studs(mine, pad) visible[pad] = true mark(V.tele, pad, pad, { color = palette.portal, caption = 'TELEPORTER -> ' .. name .. (d and ('\n' .. d) or ''), highlight = true, box_t = 0.55 }) end end end sweep(V.tele, visible) end function V.sync_hazards() local root = getroot(localplayer) if settings.jump_pad_esp then local visible = {} for _, object in ipairs(collectionservice:GetTagged('JumpPad')) do local part = part_of(object) if part and part:IsDescendantOf(workspace) then visible[object] = true local d = studs(root, part) mark(V.hz.jump, object, part, { color = palette.jump, caption = 'JUMP PAD' .. (d and ('\n' .. d) or '') }) end end sweep(V.hz.jump, visible) end local objects = workspace:FindFirstChild('GameObjects') local glue_visible, camera_visible = {}, {} if objects and (settings.glue_esp or settings.camera_esp) then for _, object in ipairs(objects:GetChildren()) do local name = string.lower(object.Name) local part = part_of(object) if part and part:IsDescendantOf(workspace) then local d = studs(root, part) if settings.glue_esp and (name == 'glue' or name == 'glueclient' or name == 'glueplaced' or name == 'glueserver' or name == 'gluepuddle') then glue_visible[object] = true mark(V.hz.glue, object, part, { color = palette.glue, caption = 'GLUE HAZARD' .. (d and ('\n' .. d) or '') }) end if settings.camera_esp and name:find('camera', 1, true) and name ~= 'cameraparticle' then camera_visible[object] = true mark(V.hz.camera, object, part, { color = palette.camera, caption = 'SEEKER CAMERA?' .. (d and ('\n' .. d) or '') }) end end end end if settings.glue_esp then sweep(V.hz.glue, glue_visible) end if settings.camera_esp then sweep(V.hz.camera, camera_visible) end end function V.update_seeker_radius() if not settings.seeker_radius_esp or isit(localplayer) then V.clear_seeker_radius() return end local seeker = getit() local seeker_root = seeker and getroot(seeker) local root = getroot(localplayer) if not root or not seeker_root then V.clear_seeker_radius() return end if not V.sphere or not V.sphere.Parent or V.sphere.Adornee ~= seeker_root then if V.sphere then V.sphere:Destroy() end V.sphere = new('SphereHandleAdornment', { Name = 'luna_seeker_range', Adornee = seeker_root, AlwaysOnTop = false, Color3 = palette.danger, Transparency = 0.93, Radius = settings.seeker_warning_distance, ZIndex = 0 }, seeker_root) end V.sphere.Radius = settings.seeker_warning_distance local dist = math.floor((seeker_root.Position - root.Position).Magnitude + 0.5) local danger = dist <= settings.seeker_warning_distance ui.seeker_warning.Visible = true ui.seeker_warning.Text = (danger and 'WARNING ' or 'IT DISTANCE ') .. dist .. ' studs' ui.seeker_warning.TextColor3 = danger and palette.danger or palette.jump end function V.update_credit_direction() if not settings.closest_credit_esp then V.clear_closest_line(); return end local camera = workspace.CurrentCamera local root = getroot(localplayer) local credit = find_nearest_credit(false) if not camera or not root or not credit then V.clear_closest_line(); return end local point, onscreen = camera:WorldToViewportPoint(credit.Position) if not onscreen or point.Z <= 0 then V.clear_closest_line(); return end local target = Vector2.new(point.X, point.Y) local origin = Vector2.new(camera.ViewportSize.X * 0.5, camera.ViewportSize.Y * 0.67) local delta = target - origin local length = delta.Magnitude if length < 12 then V.clear_closest_line(); return end ui.closest_line.Size = UDim2.fromOffset(length, 2) ui.closest_line.Position = UDim2.fromOffset((origin.X + target.X) / 2, (origin.Y + target.Y) / 2) ui.closest_line.Rotation = math.deg(math.atan2(delta.Y, delta.X)) ui.closest_line.Visible = true ui.closest_label.Position = UDim2.fromOffset( math.clamp(target.X - 112, 0, math.max(0, camera.ViewportSize.X - 225)), math.clamp(target.Y - 32, 0, math.max(0, camera.ViewportSize.Y - 25)) ) ui.closest_label.Text = 'NEAREST CREDIT: ' .. math.floor((root.Position - credit.Position).Magnitude + 0.5) .. ' studs' ui.closest_label.Visible = true end table.insert(cleanups, function() V.clear_players() clear_store(V.credits) clear_store(V.tele) for _, store in pairs(V.hz) do clear_store(store) end V.clear_seeker_radius() V.clear_closest_line() if settings.fullbright then V.restore_lighting() end end) function M.reset_collisions() for part, value in pairs(M.collisions) do if part and part.Parent then part.CanCollide = value end M.collisions[part] = nil end end function M.restore(kind) for humanoid, baseline in pairs(M.baselines) do if humanoid.Parent then if kind == 'speed' and baseline.speed then humanoid.WalkSpeed = baseline.speed baseline.speed = nil elseif kind == 'jump' and baseline.jump then humanoid.JumpPower = baseline.jump.power humanoid.JumpHeight = baseline.jump.height baseline.jump = nil end end end end function M.step() local sprinting = os.clock() < A.practice_end if not (settings.speed or settings.jump or sprinting or A.sprint_applied) then return end local _, humanoid = getroot(localplayer) if not humanoid then return end local baseline = M.baselines[humanoid] if not baseline then baseline = {} M.baselines[humanoid] = baseline end if (settings.speed or sprinting) and not baseline.speed then baseline.speed = humanoid.WalkSpeed end if settings.jump and not baseline.jump then baseline.jump = { power = humanoid.JumpPower, height = humanoid.JumpHeight } end if settings.speed or sprinting then local target = baseline.speed if settings.speed then target = move.subtle_speed and math.floor(baseline.speed * 1.06 * 10 + 0.5) / 10 or move.speed end if sprinting then target = math.max(target, 29) end if humanoid.WalkSpeed ~= target then humanoid.WalkSpeed = target end end if sprinting then A.sprint_applied = true elseif A.sprint_applied then A.sprint_applied = false if not settings.speed then M.restore('speed') end end if settings.jump then local target_jump = move.subtle_jump and math.floor(baseline.jump.power * 1.06 * 10 + 0.5) / 10 or move.jump if humanoid.UseJumpPower then if humanoid.JumpPower ~= target_jump then humanoid.JumpPower = target_jump end else local original = math.max(baseline.jump.power, 1) local target_height = baseline.jump.height * (target_jump / original) ^ 2 if math.abs(humanoid.JumpHeight - target_height) > 0.001 then humanoid.JumpHeight = target_height end end end end bind(runservice.Heartbeat, function() if alive then M.step() end end) bind(userinputservice.JumpRequest, function() if settings.infinite_jump then local _, humanoid = getroot(localplayer) if humanoid then humanoid:ChangeState(Enum.HumanoidStateType.Jumping) end end end) bind(runservice.Stepped, function() if not alive or not settings.noclip then return end local character = localplayer.Character if not character then return end for _, part in ipairs(character:GetDescendants()) do if part:IsA('BasePart') and part.CanCollide then if M.collisions[part] == nil then M.collisions[part] = true end part.CanCollide = false end end end) table.insert(cleanups, function() M.reset_collisions() M.restore('speed') M.restore('jump') restore_camera() end) function F.teleport_credit(part, automated) local root = getroot(localplayer) if not root or not part or not part.Parent then return false end if not automated then S.return_cframe = root.CFrame elseif not F.loop_origin then F.loop_origin = root.CFrame S.return_cframe = F.loop_origin end recent_credits[part] = os.clock() root.AssemblyLinearVelocity = Vector3.zero root.CFrame = part.CFrame + Vector3.new(0, 2.5, 0) return true end function F.restore_pulled() for part, original in pairs(F.pulled_credits) do if part.Parent then pcall(function() part.CFrame = original end) end F.pulled_credits[part] = nil end end function F.pull_player(target) local mine = getroot(localplayer) local theirs = getroot(target) if not mine or not theirs or target == localplayer then return false end local destination = mine.CFrame * CFrame.new(0, 0.05, 0) local ok = pcall(function() target.Character:PivotTo(destination) theirs.CFrame = destination end) local now = os.clock() if ok and type(firetouchinterest) == 'function' and now - F.last_touch >= 0.2 then F.last_touch = now pcall(function() firetouchinterest(mine, theirs, 0) firetouchinterest(mine, theirs, 1) end) end if ok then F.pull_ticks += 1 end return ok end function F.try_pull_credit() if F.credit_inflight then return false end local part = find_nearest_credit(true) local root = getroot(localplayer) if not part or not root or F.pulled_credits[part] then return false end local original = part.CFrame F.pulled_credits[part] = original recent_credits[part] = os.clock() + 6 F.credit_inflight = true local data = localplayer:FindFirstChild('PlayerData') local balance = data and data:FindFirstChild('Credits') local start_balance = balance and balance.Value task.spawn(function() local started = os.clock() while alive and settings.pull_credits and part.Parent and F.pulled_credits[part] == original and os.clock() - started < 1.15 do local current = getroot(localplayer) local collected = part:FindFirstChild('Collected') if not current or (collected and collected.Value) then break end pcall(function() part.CFrame = CFrame.new(current.Position) * original.Rotation end) task.wait(0.06) end if F.pulled_credits[part] == original then if part.Parent then pcall(function() part.CFrame = original end) end F.pulled_credits[part] = nil end task.wait(0.7) F.credit_inflight = false end) return true end function F.try_pull_lobby() local root = getroot(localplayer) if not root then return false end local now = os.clock() local target = F.lobby_target local target_root = getroot(target) if not target or target.Parent ~= players or isit(target) or ingame(target) or not target_root or now - F.lobby_started >= 1.25 then target = next_lobby_target() F.lobby_target = target F.lobby_started = now if getroot(target) then F.lobby_targets += 1 end end if not target then return false end return F.pull_player(target) end function F.try_evade() local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') if not settings.auto_evade or isit(localplayer) or not ingame(localplayer) or not running or not running.Value then table.clear(F.safe_positions) return end local mine = getroot(localplayer) local seeker = getit() local seeker_root = getroot(seeker) if not mine or not seeker_root or seeker == localplayer then return end local now = os.clock() local distance = (mine.Position - seeker_root.Position).Magnitude if distance > 90 and now - F.last_safe > 1.2 then local last = F.safe_positions[#F.safe_positions] if not last or (last.cf.Position - mine.Position).Magnitude > 13 then table.insert(F.safe_positions, { cf = mine.CFrame, t = now }) if #F.safe_positions > 16 then table.remove(F.safe_positions, 1) end F.last_safe = now end end if not seeking or not seeking.Value or distance > 38 or now - F.last_escape < 2 then return end local destination local best = 80 for _, spot in ipairs(F.safe_positions) do local d = (spot.cf.Position - seeker_root.Position).Magnitude if now - spot.t < 50 and d > best and (spot.cf.Position - mine.Position).Magnitude > 30 then best, destination = d, spot.cf end end for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and player ~= seeker and ingame(player) and not isit(player) then local other = getroot(player) if other then local d = (other.Position - seeker_root.Position).Magnitude if d > best and (other.Position - mine.Position).Magnitude > 30 then best, destination = d, other.CFrame * CFrame.new(4, 0, 4) end end end end if destination then F.last_escape = now mine.AssemblyLinearVelocity = Vector3.zero mine.CFrame = destination notify('Auto evade: escaped from It (not guaranteed against server tags).') elseif now - F.last_notice > 8 then F.last_notice = now notify('Auto evade: no known safe destination yet.') end end table.insert(cleanups, F.restore_pulled) function A.clear_hooks() local handler = A.handler if handler then if handler.SetCooldown == A.set_hook then handler.SetCooldown = A.set_original end if handler.MarkAbilityAsActive == A.mark_hook then handler.MarkAbilityAsActive = A.mark_original end end A.handler, A.set_original, A.mark_original, A.set_hook, A.mark_hook = nil, nil, nil, nil, nil A.active, A.active_known = false, false end function A.bridge() if A.handler and A.handler.SetCooldown == A.set_hook then return true end local scripts = localplayer:FindFirstChild('PlayerScripts') local modules = scripts and scripts:FindFirstChild('Modules') local module_script = modules and modules:FindFirstChild('AbilityHandler') if not module_script then A.last_result = 'AbilityHandler missing'; return false end local ok, module = pcall(require, module_script) if not ok or type(module) ~= 'table' or type(module.SetCooldown) ~= 'function' then A.last_result = 'AbilityHandler unavailable' return false end if A.handler and A.handler ~= module then A.clear_hooks() end if A.handler == module then if module.SetCooldown == A.set_hook then return true end A.clear_hooks() end A.handler = module A.set_original = module.SetCooldown A.mark_original = module.MarkAbilityAsActive A.set_hook = function(self, duration, ...) if alive and settings.it_no_cooldown and isit(localplayer) and type(duration) == 'number' then if duration > 0 then A.intercepts += 1 end duration = 0 end return A.set_original(self, duration, ...) end module.SetCooldown = A.set_hook if type(A.mark_original) == 'function' then A.mark_hook = function(self, active, ...) local result = A.mark_original(self, active, ...) if alive then A.active_known = true A.active = active == true end return result end module.MarkAbilityAsActive = A.mark_hook end return true end function A.can_use() local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') local character = localplayer.Character local root, humanoid = getroot(localplayer) return running and running.Value and seeking and seeking.Value and isit(localplayer) and root ~= nil and humanoid ~= nil and character and character:GetAttribute('IsSeekerCharacter') == true end function A.equipped_name() local data = localplayer:FindFirstChild('PlayerData') local equipped = data and data:FindFirstChild('EquippedCharacter') local wanted = equipped and tostring(equipped.Value) if not wanted or wanted == '' then return 'Unknown' end local main = playergui:FindFirstChild('MainGui') local shop = main and main:FindFirstChild('ShopFrame') if shop then for _, child in ipairs(shop:GetDescendants()) do if child.Name == 'Data' then local character = child:FindFirstChild('CharacterName') if character and tostring(character.Value) == wanted then local ability = child:FindFirstChild('Ability') if ability and ability:IsA('StringValue') then return ability.Value end end end end end return 'Unknown' end function A.press() if not A.can_use() then A.last_result = 'Not seeking as It'; return false end local main = playergui:FindFirstChild('MainGui') local frame = main and main:FindFirstChild('AbilityFrame') local control = frame and frame:FindFirstChild('AbilityButton') if not control then A.last_result = 'Ability button unavailable'; return false end if type(firesignal) == 'function' then local ok = pcall(firesignal, control.MouseButton1Click) if ok then A.last_result = 'Button signal sent' A.attempts += 1 return true end end local ok = pcall(function() local virtual_input = game:GetService('VirtualInputManager') virtual_input:SendKeyEvent(true, Enum.KeyCode.One, false, game) virtual_input:SendKeyEvent(false, Enum.KeyCode.One, false, game) end) if ok then A.last_result = 'Key 1 sent' A.attempts += 1 return true end A.last_result = 'No supported activation method' return false end function A.clear_cooldown() if not A.bridge() or not A.handler or not A.can_use() then return false end local now = os.clock() if now - A.last_clear < 0.2 then return true end local ok, err = pcall(A.set_original, A.handler, 0) if ok then A.last_clear = now A.clears += 1 A.err = nil else A.err = tostring(err) end return ok end local function practice_effect(obj) table.insert(A.objects, obj) return obj end function A.practice_sprint() if not getroot(localplayer) then notify('Practice Sprint: character unavailable.'); return end A.practice_end = os.clock() + 6 A.last_result = 'Practice Sprint: local boost for 6s' notify('Practice Sprint active (local movement only).') end function A.practice_glue() local root = getroot(localplayer) if not root then return end local ground = workspace:Raycast(root.Position, Vector3.new(0, -18, 0)) local point = ground and ground.Position or root.Position - Vector3.new(0, 3, 0) local glue = practice_effect(new('Part', { Name = 'luna_practice_glue', Anchored = true, CanCollide = false, CanTouch = false, Material = Enum.Material.Neon, Color = Color3.fromRGB(121, 224, 121), Transparency = 0.4, Shape = Enum.PartType.Ball, Size = Vector3.new(0.22, 10, 10), CFrame = CFrame.new(point + Vector3.new(0, 0.13, 0)) }, workspace)) task.delay(7, function() if glue.Parent then glue:Destroy() end end) A.last_result = 'Practice Glue: visual patch only' notify('Practice Glue spawned locally; it cannot trap anyone.') end function A.practice_camera_toggle() local camera = workspace.CurrentCamera local root = getroot(localplayer) if not camera or not root then return end if A.practice_camera then camera.CameraType = A.practice_camera.kind camera.CameraSubject = A.practice_camera.subject camera.CFrame = A.practice_camera.cf A.practice_camera = nil A.last_result = 'Practice Camera: exited' notify('Practice Camera closed.') return end A.practice_camera = { kind = camera.CameraType, subject = camera.CameraSubject, cf = camera.CFrame } camera.CameraType = Enum.CameraType.Scriptable camera.CFrame = CFrame.lookAt(root.Position + root.CFrame.LookVector * 10 + Vector3.new(0, 6, 0), root.Position) A.last_result = 'Practice Camera: local POV active' notify('Practice Camera active. Press again to exit.') end function A.practice_smash() local root = getroot(localplayer) if not root then return end local ring = practice_effect(new('Part', { Name = 'luna_practice_smash', Anchored = true, CanCollide = false, CanTouch = false, Shape = Enum.PartType.Ball, Size = Vector3.new(0.12, 2, 2), CFrame = CFrame.new(root.Position - Vector3.new(0, 2.6, 0)), Material = Enum.Material.Neon, Color = palette.accent, Transparency = 0.15 }, workspace)) tweenservice:Create(ring, TweenInfo.new(0.65), { Size = Vector3.new(0.12, 23, 23), Transparency = 1 }):Play() task.delay(0.8, function() if ring.Parent then ring:Destroy() end end) A.last_result = 'Practice Smash: local ring only' notify('Practice Smash visual (no players stunned).') end table.insert(cleanups, function() A.clear_hooks() if A.practice_camera and workspace.CurrentCamera then local camera = workspace.CurrentCamera camera.CameraType = A.practice_camera.kind camera.CameraSubject = A.practice_camera.subject camera.CFrame = A.practice_camera.cf A.practice_camera = nil end for _, item in ipairs(A.objects) do if item.Parent then item:Destroy() end end end) local function afk_pulse() if not alive or not settings.anti_afk then return false end local ok = pcall(function() virtualuser:CaptureController() virtualuser:ClickButton2(Vector2.new(0, 0)) end) if ok then S.afk_pulses += 1 S.last_pulse = os.clock() end return ok end bind(localplayer.Idled, function() afk_pulse() end) every(45, function() if settings.anti_afk and os.clock() - S.last_pulse >= 240 then afk_pulse() end end) local viewport = workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize or Vector2.new(1280, 720) local win_w = math.clamp(viewport.X - 120, 520, 600) local win_h = math.clamp(viewport.Y - 180, 320, 372) local HEADER, SIDEBAR = 40, 124 local window = new('Frame', { Name = 'Window', AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(win_w, win_h), BackgroundColor3 = palette.background, BorderSizePixel = 0, Active = true, ClipsDescendants = true }, gui) round(window, 8) stroke(window, palette.border) new('UISizeConstraint', { MinSize = Vector2.new(480, HEADER), MaxSize = Vector2.new(980, 780) }, window) local header = new('Frame', { Name = 'Header', Size = UDim2.new(1, 0, 0, HEADER), BackgroundColor3 = palette.side, BorderSizePixel = 0, Active = true }, window) new('Frame', { Position = UDim2.new(0, 0, 1, -1), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = palette.border, BorderSizePixel = 0 }, header) local moon = new('Frame', { Position = UDim2.fromOffset(12, 10), Size = UDim2.fromOffset(20, 20), BackgroundColor3 = palette.lilac, BorderSizePixel = 0 }, header) round(moon, 10) local moon_cut = new('Frame', { Position = UDim2.fromOffset(7, -3), Size = UDim2.fromOffset(18, 18), BackgroundColor3 = palette.side, BorderSizePixel = 0 }, moon) round(moon_cut, 9) text(header, 'luna.dev', 14, palette.text, { Position = UDim2.fromOffset(40, 0), Size = UDim2.fromOffset(62, HEADER), Font = Enum.Font.GothamBold }) text(header, '/ hide and seek', 10, palette.dim, { Position = UDim2.fromOffset(104, 0), Size = UDim2.fromOffset(110, HEADER) }) local controls = new('Frame', { AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -10, 0.5, 0), Size = UDim2.fromOffset(0, 24), AutomaticSize = Enum.AutomaticSize.X, BackgroundTransparency = 1 }, header) new('UIListLayout', { FillDirection = Enum.FillDirection.Horizontal, HorizontalAlignment = Enum.HorizontalAlignment.Right, VerticalAlignment = Enum.VerticalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 6) }, controls) ui.stats = text(controls, 'FPS -- / --ms', 10, palette.muted, { Size = UDim2.fromOffset(92, 24), TextXAlignment = Enum.TextXAlignment.Right, Font = Enum.Font.GothamMedium, LayoutOrder = 1 }) ui.afk = new('TextButton', { Size = UDim2.fromOffset(92, 22), LayoutOrder = 2, BorderSizePixel = 0, Font = Enum.Font.GothamBold, TextSize = 10, Text = '', AutoButtonColor = true, BackgroundColor3 = palette.raised }, controls) round(ui.afk, 5) local afk_stroke = stroke(ui.afk, palette.success, 0.35) local function render_afk_badge() local on = settings.anti_afk ui.afk.Text = on and 'ANTI-AFK ON' or 'ANTI-AFK OFF' ui.afk.TextColor3 = on and palette.success or palette.muted ui.afk.BackgroundColor3 = on and Color3.fromRGB(22, 44, 38) or palette.raised afk_stroke.Color = on and palette.success or palette.border end register_render('anti_afk', render_afk_badge) render_afk_badge() bind(ui.afk.MouseButton1Click, function() settings.anti_afk = not settings.anti_afk update_toggle('anti_afk') storage.schedule() notify('Anti-AFK: ' .. (settings.anti_afk and 'enabled' or 'disabled')) end) local log_button = button(controls, 'LOG', UDim2.new(), UDim2.fromOffset(38, 22), function() ui.log_panel.Visible = not ui.log_panel.Visible if ui.log_panel.Visible then ui.results.Visible = false; ui.refresh_log() end end) log_button.LayoutOrder = 3 local min_button = button(controls, '-', UDim2.new(), UDim2.fromOffset(24, 22), function() end) min_button.LayoutOrder = 4 min_button.TextSize = 14 local close_button = button(controls, 'x', UDim2.new(), UDim2.fromOffset(24, 22), function() end) close_button.LayoutOrder = 5 close_button.TextColor3 = palette.danger local sidebar = new('Frame', { Name = 'Sidebar', Position = UDim2.fromOffset(0, HEADER), Size = UDim2.new(0, SIDEBAR, 1, -HEADER), BackgroundColor3 = palette.side, BorderSizePixel = 0 }, window) new('Frame', { Position = UDim2.new(1, -1, 0, 0), Size = UDim2.new(0, 1, 1, 0), BackgroundColor3 = palette.border, BorderSizePixel = 0 }, sidebar) ui.search = new('TextBox', { Position = UDim2.fromOffset(8, 8), Size = UDim2.new(1, -46, 0, 26), BackgroundColor3 = palette.background, BorderSizePixel = 0, PlaceholderText = 'Search...', PlaceholderColor3 = palette.dim, ClearTextOnFocus = false, Text = '', Font = Enum.Font.Gotham, TextSize = 11, TextColor3 = palette.text, TextXAlignment = Enum.TextXAlignment.Left }, sidebar) round(ui.search, 5) stroke(ui.search) new('UIPadding', { PaddingLeft = UDim.new(0, 8), PaddingRight = UDim.new(0, 4) }, ui.search) local search_icon = new('TextButton', { Position = UDim2.new(1, -34, 0, 8), Size = UDim2.fromOffset(26, 26), BackgroundColor3 = palette.accentdark, BorderSizePixel = 0, Text = '', AutoButtonColor = true }, sidebar) round(search_icon, 5) local lens = new('Frame', { Position = UDim2.fromOffset(7, 6), Size = UDim2.fromOffset(10, 10), BackgroundTransparency = 1 }, search_icon) round(lens, 5) new('UIStroke', { Color = palette.lilac, Thickness = 1.5, ApplyStrokeMode = Enum.ApplyStrokeMode.Border }, lens) new('Frame', { Position = UDim2.fromOffset(15, 17), Size = UDim2.fromOffset(6, 2), Rotation = 45, BackgroundColor3 = palette.lilac, BorderSizePixel = 0 }, search_icon) bind(search_icon.MouseButton1Click, function() ui.search:CaptureFocus() end) local nav = new('ScrollingFrame', { Name = 'Navigation', Position = UDim2.fromOffset(6, 44), Size = UDim2.new(1, -12, 1, -68), CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 2, ScrollBarImageColor3 = palette.accent }, sidebar) new('UIListLayout', { Padding = UDim.new(0, 2), SortOrder = Enum.SortOrder.LayoutOrder }, nav) text(sidebar, 'V14 / VIOLET', 9, palette.dim, { Position = UDim2.new(0, 14, 1, -22), Size = UDim2.new(1, -28, 0, 16), Font = Enum.Font.GothamMedium }) local content = new('Frame', { Name = 'Content', Position = UDim2.fromOffset(SIDEBAR, HEADER), Size = UDim2.new(1, -SIDEBAR, 1, -HEADER), BackgroundColor3 = palette.surface, BorderSizePixel = 0 }, window) ui.title = text(content, 'Home', 15, palette.text, { Position = UDim2.fromOffset(14, 7), Size = UDim2.new(0.55, -14, 0, 20), Font = Enum.Font.GothamBold }) ui.subtitle = text(content, '', 10, palette.muted, { Position = UDim2.fromOffset(14, 28), Size = UDim2.new(0.55, -14, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd }) ui.tag = text(content, 'MAIN', 10, palette.accent, { AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -14, 0, 8), Size = UDim2.new(0.45, -14, 0, 16), TextXAlignment = Enum.TextXAlignment.Right, Font = Enum.Font.GothamBold }) ui.status = text(content, 'Reading round status...', 10, palette.muted, { AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -14, 0, 26), Size = UDim2.new(0.45, -14, 0, 16), TextXAlignment = Enum.TextXAlignment.Right, TextTruncate = Enum.TextTruncate.AtEnd }) new('Frame', { Position = UDim2.fromOffset(10, 50), Size = UDim2.new(1, -20, 0, 1), BackgroundColor3 = palette.border, BorderSizePixel = 0 }, content) new('Frame', { Position = UDim2.new(0, 10, 1, -26), Size = UDim2.new(1, -20, 0, 1), BackgroundColor3 = palette.border, BorderSizePixel = 0 }, content) ui.message = text(content, 'Ready.', 10, palette.muted, { Position = UDim2.new(0, 10, 1, -24), Size = UDim2.new(1, -150, 0, 22), TextTruncate = Enum.TextTruncate.AtEnd }) text(content, 'LUNA.DEV / V14 VIOLET', 9, palette.dim, { AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -10, 1, -24), Size = UDim2.fromOffset(130, 22), TextXAlignment = Enum.TextXAlignment.Right }) local tab_defs = { { 'MAIN', { { 'home', 'Home' }, { 'players', 'Players' }, { 'autofarm', 'Auto Farm' } } }, { 'FEATURES', { { 'visuals', 'Visuals' }, { 'movement', 'Movement' }, { 'farming', 'Farming' }, { 'abilities', 'Abilities' }, { 'shop', 'Shop' } } }, { 'SYSTEM', { { 'tests', 'Tests' }, { 'config', 'Config' } } } } local page_titles = { home = { 'Home', 'Overview, shortcuts and quick toggles.' }, players = { 'Players', 'Seeker first, then hiders and lobby.' }, autofarm = { 'Auto Farm', 'Automatic phase selection and farming.' }, visuals = { 'Visuals', 'ESP, highlights and awareness tools.' }, movement = { 'Movement', 'Speed, jump, noclip and teleports.' }, farming = { 'Farming', 'Manual and repeating farming controls.' }, abilities = { 'Abilities', 'Seeker abilities and practice effects.' }, shop = { 'Shop', 'Credit purchase tools.' }, tests = { 'Tests', 'Experiments and gamepass diagnostics.' }, config = { 'Config', 'Save, reset and system options.' } } local pages, tabs = {}, {} local current_page = 'home' local function show_page(name) current_page = name local info_ = page_titles[name] ui.title.Text = info_[1] ui.subtitle.Text = info_[2] ui.tag.Text = string.upper(info_[1]) ui.results.Visible = false ui.log_panel.Visible = false for page_name, frame in pairs(pages) do frame.Visible = not S.minimized and page_name == name end for tab_name, control in pairs(tabs) do local selected_tab = tab_name == name control.BackgroundTransparency = selected_tab and 0 or 1 control.TextColor3 = selected_tab and palette.lilac or palette.muted control.Diamond.BackgroundColor3 = selected_tab and palette.accent or palette.dim end end local page_order = {} for _, group in ipairs(tab_defs) do local label = text(nav, group[1], 9, palette.dim, { Size = UDim2.new(1, 0, 0, 20), Font = Enum.Font.GothamBold, LayoutOrder = nextorder(nav) }) new('UIPadding', { PaddingLeft = UDim.new(0, 6), PaddingTop = UDim.new(0, 4) }, label) for _, def in ipairs(group[2]) do table.insert(page_order, def[1]) local tab = new('TextButton', { Size = UDim2.new(1, -4, 0, 25), BackgroundColor3 = palette.accentdark, BackgroundTransparency = 1, BorderSizePixel = 0, Text = def[2], TextSize = 11, Font = Enum.Font.GothamMedium, TextColor3 = palette.muted, TextXAlignment = Enum.TextXAlignment.Left, AutoButtonColor = false, LayoutOrder = nextorder(nav) }, nav) round(tab, 5) new('UIPadding', { PaddingLeft = UDim.new(0, 26) }, tab) new('Frame', { Name = 'Diamond', Position = UDim2.fromOffset(-14, 10), Size = UDim2.fromOffset(5, 5), Rotation = 45, BackgroundColor3 = palette.dim, BorderSizePixel = 0 }, tab) tabs[def[1]] = tab bind(tab.MouseButton1Click, function() show_page(def[1]) end) end end for _, name in ipairs(page_order) do local page = new('ScrollingFrame', { Name = name, Position = UDim2.fromOffset(10, 56), Size = UDim2.new(1, -20, 1, -86), CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = palette.accent, Visible = false }, content) new('UIListLayout', { Padding = UDim.new(0, 5), SortOrder = Enum.SortOrder.LayoutOrder }, page) new('UIPadding', { PaddingRight = UDim.new(0, 7), PaddingBottom = UDim.new(0, 4) }, page) pages[name] = page end ui.results = new('ScrollingFrame', { Position = UDim2.fromOffset(10, 56), Size = UDim2.new(1, -20, 1, -86), CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y, BackgroundColor3 = palette.background, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = palette.accent, Visible = false, ZIndex = 40 }, content) round(ui.results, 6) stroke(ui.results) new('UIListLayout', { Padding = UDim.new(0, 4), SortOrder = Enum.SortOrder.LayoutOrder }, ui.results) new('UIPadding', { PaddingTop = UDim.new(0, 6), PaddingBottom = UDim.new(0, 6), PaddingLeft = UDim.new(0, 6), PaddingRight = UDim.new(0, 8) }, ui.results) ui.log_panel = new('ScrollingFrame', { Position = UDim2.fromOffset(10, 56), Size = UDim2.new(1, -20, 1, -86), CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y, BackgroundColor3 = palette.background, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = palette.accent, Visible = false, ZIndex = 45 }, content) round(ui.log_panel, 6) stroke(ui.log_panel) new('UIPadding', { PaddingTop = UDim.new(0, 8), PaddingBottom = UDim.new(0, 8), PaddingLeft = UDim.new(0, 10), PaddingRight = UDim.new(0, 10) }, ui.log_panel) local log_label = text(ui.log_panel, '', 10, palette.muted, { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top }) function ui.refresh_log() if not ui.log_panel.Visible then return end local lines = {} for i = #logs, 1, -1 do table.insert(lines, logs[i]) end log_label.Text = #lines > 0 and table.concat(lines, '\n') or 'No activity yet.' end local search_index = {} local function heading(pagename, content_text) local page = pages[pagename] return text(page, content_text, 10, palette.accent, { Size = UDim2.new(1, 0, 0, 18), Font = Enum.Font.GothamBold, TextYAlignment = Enum.TextYAlignment.Bottom, LayoutOrder = nextorder(page) }) end local function info(pagename, content_text, color, size) local page = pages[pagename] return text(page, content_text, size or 10, color or palette.muted, { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = nextorder(page) }) end local function make_card(pagename, border_color) local page = pages[pagename] local card = new('Frame', { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = palette.card, BorderSizePixel = 0, LayoutOrder = nextorder(page) }, page) round(card, 6) stroke(card, border_color) new('UIPadding', { PaddingTop = UDim.new(0, 8), PaddingBottom = UDim.new(0, 8), PaddingLeft = UDim.new(0, 10), PaddingRight = UDim.new(0, 10) }, card) new('UIListLayout', { Padding = UDim.new(0, 3), SortOrder = Enum.SortOrder.LayoutOrder }, card) return card end local function status_card(pagename, color) local card = make_card(pagename) return text(card, '', 11, color or palette.text, { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top }) end local function warn_card(pagename, title, body) local card = make_card(pagename, palette.danger) text(card, title, 10, palette.danger, { Size = UDim2.new(1, 0, 0, 14), Font = Enum.Font.GothamBold, LayoutOrder = 1 }) return text(card, body, 10, palette.muted, { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 2 }) end local function make_row(pagename, title, desc, reserve) local page = pages[pagename] local row = new('Frame', { Size = UDim2.new(1, 0, 0, 38), BackgroundColor3 = palette.card, BorderSizePixel = 0, LayoutOrder = nextorder(page) }, page) round(row, 6) stroke(row) text(row, title, 12, palette.text, { Position = UDim2.fromOffset(10, 3), Size = UDim2.new(1, -(reserve + 14), 0, 17), Font = Enum.Font.GothamMedium, TextTruncate = Enum.TextTruncate.AtEnd }) text(row, desc, 10, palette.muted, { Position = UDim2.fromOffset(10, 20), Size = UDim2.new(1, -(reserve + 14), 0, 14), TextTruncate = Enum.TextTruncate.AtEnd }) table.insert(search_index, { page = pagename, title = title, desc = desc, row = row }) return row end local function add_switch(row, key, callback, title) local track = new('TextButton', { AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -10, 0.5, 0), Size = UDim2.fromOffset(34, 18), Text = '', AutoButtonColor = false, BorderSizePixel = 0, BackgroundColor3 = palette.raised }, row) round(track, 9) local knob = new('Frame', { Size = UDim2.fromOffset(12, 12), Position = UDim2.fromOffset(3, 3), BorderSizePixel = 0, BackgroundColor3 = palette.muted }, track) round(knob, 6) local function render() local on = settings[key] == true track.BackgroundColor3 = on and palette.accentmid or palette.raised tweenservice:Create(knob, TweenInfo.new(0.12), { Position = on and UDim2.fromOffset(19, 3) or UDim2.fromOffset(3, 3), BackgroundColor3 = on and palette.text or palette.muted }):Play() end register_render(key, render) render() bind(track.MouseButton1Click, function() settings[key] = not settings[key] if callback then callback(settings[key]) end update_toggle(key) storage.schedule() notify(title .. ': ' .. (settings[key] and 'enabled' or 'disabled')) end) end local function add_input(row, right, value, min_value, max_value, apply) local box = new('TextBox', { AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -right, 0.5, 0), Size = UDim2.fromOffset(52, 22), BackgroundColor3 = palette.background, BorderSizePixel = 0, Font = Enum.Font.Gotham, TextSize = 11, TextColor3 = palette.text, Text = tostring(value), ClearTextOnFocus = false }, row) round(box, 5) stroke(box) box:SetAttribute('last', value) bind(box.FocusLost, function() local number = tonumber(box.Text) if not number then box.Text = tostring(box:GetAttribute('last')) return end number = math.floor(math.clamp(number, min_value, max_value) * 10 + 0.5) / 10 box.Text = tostring(number) box:SetAttribute('last', number) apply(number) end) return box end local function toggle(pagename, title, desc, key, callback, input) local row = make_row(pagename, title, desc, input and 120 or 56) if input then add_input(row, 54, input.value, input.min, input.max, input.apply) end add_switch(row, key, callback, title) return row end local function input_row(pagename, title, desc, value, min_value, max_value, apply) local row = make_row(pagename, title, desc, 70) return add_input(row, 10, value, min_value, max_value, apply) end local function buttons(pagename, defs) local page = pages[pagename] local holder = new('Frame', { Size = UDim2.new(1, 0, 0, 28), BackgroundTransparency = 1, LayoutOrder = nextorder(page) }, page) new('UIListLayout', { FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder }, holder) local n = #defs local made = {} for i, def in ipairs(defs) do local control = button(holder, def[1], UDim2.new(), UDim2.new(1 / n, -6 * (n - 1) / n, 1, 0), def[2], def[3]) control.LayoutOrder = i table.insert(search_index, { page = pagename, title = def[1], desc = 'Action', row = holder }) made[i] = control end return made end local on = {} function on.esp(enabled) if not enabled then V.clear_players() end end function on.credit_esp(enabled) if not enabled then clear_store(V.credits) end end function on.teleporter_esp(enabled) if not enabled then clear_store(V.tele) end end function on.jump_pad_esp(enabled) if not enabled then clear_store(V.hz.jump) end end function on.glue_esp(enabled) if not enabled then clear_store(V.hz.glue) end end function on.camera_esp(enabled) if not enabled then clear_store(V.hz.camera) end end function on.seeker_radius_esp(enabled) if not enabled then V.clear_seeker_radius() end end function on.closest_credit_esp(enabled) if not enabled then V.clear_closest_line() end end function on.fullbright(enabled) if not enabled then V.restore_lighting() end end function on.speed(enabled) if not enabled then M.restore('speed') end end function on.jump(enabled) if not enabled then M.restore('jump') end end function on.noclip(enabled) if not enabled then M.reset_collisions() end end function on.auto_credits(enabled) F.loop_origin = nil if enabled then settings.pull_credits = false update_toggle('pull_credits') F.restore_pulled() F.credit_attempts = 0 end end function on.pull_credits(enabled) if enabled then settings.auto_credits = false update_toggle('auto_credits') else F.restore_pulled() end end function on.pull_lobby(enabled) F.lobby_target = nil F.lobby_started = 0 if enabled then settings.auto_seek = false update_toggle('auto_seek') notify('Pulling lobby players. Client-only: tags and rewards are not confirmed.') end end function on.auto_seek(enabled) if enabled then settings.pull_lobby = false update_toggle('pull_lobby') end end function on.it_no_cooldown(enabled) if enabled then A.bridge() A.clear_cooldown() elseif not settings.it_keep_active then A.clear_hooks() end end function on.it_keep_active(enabled) if enabled then A.bridge() A.sprint_first = nil A.last_attempt = 0 elseif not settings.it_no_cooldown then A.clear_hooks() end end do heading('home', 'QUICK ACCESS') local grid = new('Frame', { Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = nextorder(pages.home) }, pages.home) new('UIGridLayout', { CellSize = UDim2.new(1 / 3, -4, 0, 28), CellPadding = UDim2.fromOffset(6, 6), SortOrder = Enum.SortOrder.LayoutOrder }, grid) local cards = { { 'ESP', 'visuals' }, { 'Players', 'players' }, { 'Movement', 'movement' }, { 'Auto Farm', 'autofarm' }, { 'Abilities', 'abilities' }, { 'Shop', 'shop' }, { 'Farming', 'farming' }, { 'Config', 'config' }, { 'Search Everything', 'search' } } for i, def in ipairs(cards) do local card = new('TextButton', { BackgroundColor3 = palette.card, BorderSizePixel = 0, Text = '', AutoButtonColor = true, LayoutOrder = i }, grid) round(card, 5) stroke(card) new('Frame', { Position = UDim2.fromOffset(10, 12), Size = UDim2.fromOffset(5, 5), Rotation = 45, BackgroundColor3 = palette.accent, BorderSizePixel = 0 }, card) text(card, def[1], 11, palette.text, { Position = UDim2.fromOffset(24, 0), Size = UDim2.new(1, -24, 1, 0), Font = Enum.Font.GothamMedium }) if def[2] ~= 'search' then text(card, 'OPEN >', 9, palette.lilac, { AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -8, 0, 0), Size = UDim2.fromOffset(40, 28), TextXAlignment = Enum.TextXAlignment.Right }) end bind(card.MouseButton1Click, function() if def[2] == 'search' then ui.search:CaptureFocus() else show_page(def[2]) end end) end heading('home', 'STATUS') ui.home_status = status_card('home') heading('home', 'SEEKER CHANCE') ui.home_chance = status_card('home') heading('home', 'QUICK TOGGLES') toggle('home', 'Player ESP', 'Highlight players through walls', 'esp', on.esp) toggle('home', 'Credit ESP', 'Highlight uncollected credits', 'credit_esp', on.credit_esp) toggle('home', 'Anti-AFK', 'Keeps you from being idle-kicked', 'anti_afk') end do local page = pages.players ui.roster = text(page, 'PLAYERS', 10, palette.accent, { Size = UDim2.new(1, 0, 0, 18), Font = Enum.Font.GothamBold, TextYAlignment = Enum.TextYAlignment.Bottom, LayoutOrder = nextorder(page) }) local filter = new('TextBox', { Size = UDim2.new(1, 0, 0, 26), BackgroundColor3 = palette.background, BorderSizePixel = 0, PlaceholderText = 'Filter player or display name...', PlaceholderColor3 = palette.dim, ClearTextOnFocus = false, Text = '', Font = Enum.Font.Gotham, TextSize = 11, TextColor3 = palette.text, TextXAlignment = Enum.TextXAlignment.Left, LayoutOrder = nextorder(page) }, page) round(filter, 5) stroke(filter) new('UIPadding', { PaddingLeft = UDim.new(0, 9), PaddingRight = UDim.new(0, 6) }, filter) local list = new('ScrollingFrame', { Size = UDim2.new(1, 0, 0, 124), BackgroundColor3 = palette.background, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = palette.accent, CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.Y, LayoutOrder = nextorder(page) }, page) round(list, 6) stroke(list) new('UIListLayout', { Padding = UDim.new(0, 3), SortOrder = Enum.SortOrder.LayoutOrder }, list) new('UIPadding', { PaddingTop = UDim.new(0, 4), PaddingBottom = UDim.new(0, 4), PaddingLeft = UDim.new(0, 4), PaddingRight = UDim.new(0, 6) }, list) ui.selected_label = text(page, 'Selected: nobody', 11, palette.text, { Size = UDim2.new(1, 0, 0, 18), TextTruncate = Enum.TextTruncate.AtEnd, LayoutOrder = nextorder(page) }) local rows = {} local function priority(player) if isit(player) then return 0 end if ingame(player) then return 1 end return 2 end local function sorted_roster() local roster = players:GetPlayers() table.sort(roster, function(a, b) local ap, bp = priority(a), priority(b) if ap ~= bp then return ap < bp end return string.lower(a.Name) < string.lower(b.Name) end) return roster end function ui.refresh_players() for _, child in ipairs(list:GetChildren()) do if child:IsA('TextButton') then child:Destroy() end end table.clear(rows) local query = string.lower(filter.Text) for index, player in ipairs(sorted_roster()) do if query == '' or string.find(string.lower(player.Name), query, 1, true) or string.find(string.lower(player.DisplayName), query, 1, true) then local control = new('TextButton', { Size = UDim2.new(1, 0, 0, 24), BackgroundColor3 = palette.raised, BorderSizePixel = 0, Text = player.DisplayName, TextSize = 10, TextColor3 = palette.text, TextTruncate = Enum.TextTruncate.AtEnd, TextXAlignment = Enum.TextXAlignment.Left, Font = Enum.Font.GothamMedium, LayoutOrder = index }, list) round(control, 5) new('UIPadding', { PaddingLeft = UDim.new(0, 8), PaddingRight = UDim.new(0, 6) }, control) rows[player] = control bind(control.MouseButton1Click, function() S.selected = player notify('Target set to ' .. player.Name .. '.') end) end end if S.selected and S.selected.Parent ~= players then S.selected = nil end end function ui.update_rows() local myroot = getroot(localplayer) local ordered = sorted_roster() local counts = { 0, 0, 0 } for index, player in ipairs(ordered) do local p = priority(player) counts[p + 1] += 1 local row = rows[player] if row and row.LayoutOrder ~= index then row.LayoutOrder = index end end ui.roster.Text = string.format('PLAYERS / IT %d - HIDERS %d - LOBBY %d', counts[1], counts[2], counts[3]) for player, control in pairs(rows) do if control.Parent and player.Parent == players then local root = getroot(player) local distance = myroot and root and math.floor((myroot.Position - root.Position).Magnitude + 0.5) control.Text = player.DisplayName .. (player == localplayer and ' (YOU)' or '') .. ' | ' .. role_of(player) .. (distance and (' | ' .. distance .. ' studs') or '') control.TextColor3 = isit(player) and palette.danger or (ingame(player) and palette.text or palette.dim) control.BackgroundColor3 = player == S.selected and palette.accentdark or palette.raised end end if S.selected and S.selected.Parent == players then ui.selected_label.Text = 'Selected: ' .. S.selected.DisplayName .. ' (@' .. S.selected.Name .. ')' else ui.selected_label.Text = 'Selected: nobody' end end bind(filter:GetPropertyChangedSignal('Text'), ui.refresh_players) bind(players.PlayerAdded, ui.refresh_players) bind(players.PlayerRemoving, function(player) if S.selected == player then S.selected = nil end task.defer(function() if alive then ui.refresh_players() end end) end) buttons('players', { { 'TELEPORT TO PLAYER', function() teleport(S.selected) end, true }, { 'NEAREST HIDER', function() if not isit(localplayer) then notify('Nearest hider teleport requires being It.'); return end teleport(nearest_hider()) end } }) buttons('players', { { 'SPECTATE / STOP', function() if S.spectating then restore_camera(); notify('Spectating stopped.'); return end local _, humanoid = getroot(S.selected) if not humanoid then notify('Choose a living player to spectate.'); return end S.spectating = S.selected if workspace.CurrentCamera then workspace.CurrentCamera.CameraSubject = humanoid end notify('Spectating ' .. S.selected.Name .. '.') end } }) toggle('players', 'Auto evade It', 'Escape to a known safe spot before It reaches you', 'auto_evade', function(enabled) if not enabled then table.clear(F.safe_positions) end end) heading('players', 'PLAYER FLING') info('players', 'Spin into one player or all except It. Auto Farm movement pauses during fling and resumes afterward; server-side results are not guaranteed.', palette.muted, 10) local fling = { active = false, token = 0, power = 1300, attempts = 0, skipped = 0, last = 'none', mode = 'idle', original = nil, spinner = nil, attachment = nil, last_root = nil, last_humanoid = nil } input_row('players', 'Spin strength', 'Classic fling rotation (300-3000)', fling.power, 300, 3000, function(value) fling.power = math.floor(value) end) local fling_status = status_card('players') local function restore_fling() if fling.spinner then pcall(function() fling.spinner:Destroy() end) end if fling.attachment then pcall(function() fling.attachment:Destroy() end) end fling.spinner, fling.attachment = nil, nil local original, root, humanoid = fling.original, fling.last_root, fling.last_humanoid fling.original, fling.last_root, fling.last_humanoid = nil, nil, nil if root and root.Parent then pcall(function() root.AssemblyLinearVelocity = Vector3.zero root.AssemblyAngularVelocity = Vector3.zero if original and root == getroot(localplayer) then root.CFrame = original.cf end end) end if humanoid and humanoid.Parent and original then pcall(function() humanoid.PlatformStand = original.stand humanoid.AutoRotate = original.rotate if not original.stand then humanoid:ChangeState(Enum.HumanoidStateType.GettingUp) end end) end end local function stop_fling() fling.token += 1 fling.active = false fling.mode = 'stopped' restore_fling() S.fling_active = false end local function eligible_fling_target(player) return player and player ~= localplayer and player.Parent == players and not isit(player) and getroot(player) ~= nil end local function spin_at(player, token) local myroot, humanoid = getroot(localplayer) if not myroot or not humanoid or not eligible_fling_target(player) then return false end fling.original = { cf = myroot.CFrame, stand = humanoid.PlatformStand, rotate = humanoid.AutoRotate } fling.last_root, fling.last_humanoid = myroot, humanoid local installed = pcall(function() humanoid.PlatformStand = true humanoid.AutoRotate = false local attachment = Instance.new('Attachment') attachment.Name = 'LunaFlingSpin' attachment.Parent = myroot fling.attachment = attachment local motor = Instance.new('AngularVelocity') motor.Name = 'LunaFlingMotor' motor.Attachment0 = attachment motor.RelativeTo = Enum.ActuatorRelativeTo.World motor.MaxTorque = 1000000000 motor.AngularVelocity = Vector3.new(fling.power, fling.power, fling.power) motor.Parent = myroot fling.spinner = motor end) if not installed then restore_fling(); return false end local began = os.clock() local direction = 1 while alive and fling.active and token == fling.token and eligible_fling_target(player) and os.clock() - began < 1.15 do local targetroot = getroot(player) if not targetroot or not myroot.Parent or getroot(localplayer) ~= myroot then break end direction = -direction local angle = math.random() * math.pi * 2 local radius = 0.45 + math.random() * 1.45 local wobble = (math.random() - 0.5) * 3.2 local offset = Vector3.new(math.cos(angle) * radius, wobble, math.sin(angle) * radius) pcall(function() myroot.CFrame = CFrame.new(targetroot.Position + offset) myroot.AssemblyAngularVelocity = Vector3.new( fling.power * direction, fling.power * (math.random(0, 1) == 1 and 1 or -1), fling.power * -direction) myroot.AssemblyLinearVelocity = Vector3.new( math.random(-90, 90), math.random(-145, 145), math.random(-90, 90)) if fling.spinner then fling.spinner.AngularVelocity = myroot.AssemblyAngularVelocity end end) task.wait(0.035) end if token == fling.token then restore_fling() end return true end local function start_fling(mode) if fling.active then notify('A fling is already running. Use STOP FLING first.'); return end local targets = {} if mode == 'selected' then if not eligible_fling_target(S.selected) then notify('Select a living player other than It first.') return end table.insert(targets, S.selected) else for _, player in ipairs(players:GetPlayers()) do if eligible_fling_target(player) then table.insert(targets, player) end end end if #targets == 0 then notify('No eligible players: It and you are excluded.'); return end table.sort(targets, function(a, b) return a.UserId < b.UserId end) fling.token += 1 local token = fling.token fling.active, fling.mode = true, mode fling.attempts, fling.skipped = 0, 0 S.fling_active = true task.spawn(function() for _, player in ipairs(targets) do if not alive or not fling.active or token ~= fling.token then break end if eligible_fling_target(player) then fling.last = player.DisplayName local ok, result = pcall(spin_at, player, token) if token ~= fling.token then break end if not ok then restore_fling() end if ok and result then fling.attempts += 1 else fling.skipped += 1 end task.wait(0.16) else fling.skipped += 1 end end if token == fling.token then fling.active, fling.mode = false, 'finished' restore_fling() S.fling_active = false notify('Spin fling finished: ' .. fling.attempts .. ' attempts. Auto Farm resumed if enabled.') end end) end buttons('players', { { 'FLING SELECTED', function() start_fling('selected') end, true }, { 'FLING ALL EXCEPT IT', function() start_fling('all') end } }) buttons('players', { { 'STOP FLING', function() stop_fling(); notify('Fling stopped and character restored.') end } }) every(0.3, function() fling_status.Text = 'Status: ' .. fling.mode .. ' | Running: ' .. (fling.active and 'YES' or 'NO') .. '\nAttempts: ' .. fling.attempts .. ' | Skipped: ' .. fling.skipped .. '\nLast target: ' .. fling.last .. ' | Spin: ' .. fling.power .. '\nAuto Farm: ' .. (S.fling_active and 'movement paused for fling' or (settings.auto_farm and 'running' or 'off')) end) table.insert(cleanups, stop_fling) end do toggle('visuals', 'Player ESP', 'Highlight players through walls; It is red', 'esp', on.esp) toggle('visuals', 'Name labels', 'Show name and role above characters', 'labels') toggle('visuals', 'Distance on labels', 'Distance from your character in studs', 'distance') toggle('visuals', 'Credit ESP', 'Highlight uncollected credit pickups', 'credit_esp', on.credit_esp) toggle('visuals', 'Closest credit line', 'On-screen line to the nearest coin', 'closest_credit_esp', on.closest_credit_esp) toggle('visuals', 'Fullbright', 'Bright environment, no fog (local)', 'fullbright', on.fullbright) toggle('visuals', 'Early It indicator', 'Show the next It above the selection UI', 'early_it') toggle('visuals', 'Teleporter ESP', 'Map teleporter pads and destinations', 'teleporter_esp', on.teleporter_esp) toggle('visuals', 'Jump pad ESP', 'Mark jump pads with green boxes', 'jump_pad_esp', on.jump_pad_esp) toggle('visuals', 'Seeker radius', 'Range ring and live seeker distance', 'seeker_radius_esp', on.seeker_radius_esp) toggle('visuals', 'Glue ESP', 'Highlight placed glue hazards', 'glue_esp', on.glue_esp) toggle('visuals', 'Camera ESP (experimental)', 'Mark likely seeker cameras', 'camera_esp', on.camera_esp) input_row('visuals', 'Seeker warning distance', 'Studs before the warning turns red (10-150)', settings.seeker_warning_distance, 10, 150, function(value) settings.seeker_warning_distance = math.floor(value + 0.5) storage.schedule() notify('Seeker warning distance: ' .. settings.seeker_warning_distance .. ' studs.') end) info('visuals', 'RED = IT PURPLE = HIDER GREY = LOBBY CYAN = TELEPORTER', palette.dim, 9) end do toggle('movement', 'Walk speed', 'Subtle +6% by default; type a value to override', 'speed', on.speed, { value = move.speed, min = 0, max = 150, apply = function(value) move.subtle_speed = false move.speed = value if not settings.speed then settings.speed = true; update_toggle('speed') end storage.schedule() notify('Walk speed set to ' .. value .. '.') end }) toggle('movement', 'Jump power', 'Subtle +6% by default; type a value to override', 'jump', on.jump, { value = move.jump, min = 0, max = 200, apply = function(value) move.subtle_jump = false move.jump = value if not settings.jump then settings.jump = true; update_toggle('jump') end storage.schedule() notify('Jump power set to ' .. value .. '.') end }) toggle('movement', 'Noclip', 'Pass through collidable map parts locally', 'noclip', on.noclip) toggle('movement', 'Infinite jump', 'Jump again while airborne', 'infinite_jump') toggle('movement', 'Auto seek teleport', 'As It, teleport to the nearest hider every 2s', 'auto_seek', on.auto_seek) buttons('movement', { { 'TP TO NEAREST CREDIT', function() local part = find_nearest_credit(false) if part and F.teleport_credit(part, false) then notify('Teleported to nearby credit.') else notify('No available credits found.') end end, true }, { 'RETURN TO OLD SPOT', function() local root = getroot(localplayer) if root and S.return_cframe then settings.auto_credits = false F.loop_origin = nil update_toggle('auto_credits') local destination = S.return_cframe S.return_cframe = root.CFrame root.AssemblyLinearVelocity = Vector3.zero root.CFrame = destination notify('Returned to previous position.') else notify('No previous position saved.') end end } }) end do heading('farming', 'AUTOMATED COLLECTION') toggle('farming', 'Loop credit teleport', 'Visits available credits every 0.7 seconds', 'auto_credits', on.auto_credits) toggle('farming', 'Loop pull lobby players', 'Overlaps lobby players with your character', 'pull_lobby', on.pull_lobby) warn_card('farming', 'WARNING: VERY OBVIOUS CHEATING', 'Loop pull moves other players over your character locally and can look very obvious. Server-side tags and credit rewards are not guaranteed.') ui.farm_status = info('farming', 'Credit teleports: 0 | Lobby targets: 0 | Pull ticks: 0', palette.muted, 10) ui.lobby_debug = info('farming', 'Lobby diagnostic: pending', palette.dim, 10) buttons('farming', { { 'DESTRUCT LUNA.DEV', function() ui.shutdown() end } }) end do local auto = { phase = 'idle', empty = 0, passes = 0, pulls = 0, scans = 0, last_target = 'none', shelter = nil, shelter_origin = nil, map = nil, target = nil, target_since = 0, time_left = nil, time_valid = false, round_started = false, release_all = false, hop_attempt = false, hop_last = 0, hop_status = 'Monitoring population', seed = nil, seed_userid = nil, seed_captured = false, sweep_index = 0, lobby_index = 0, round_resets = 0, last_round_reset = 'Startup', seen_running = nil, seen_selecting = nil, seen_it = nil, seen_role = nil, shelter_character = nil, shelter_recovery_at = 0, seed_replacements = 0, seed_last_left = 'none', seed_replacement_after = 0 } toggle('autofarm', 'Hop from dead servers', 'Only you in server: seek a busier server and reinject (executor queue required)', 'auto_server_hop') toggle('autofarm', 'Smart AFK farming', 'One initial hider, then LOBBY ONLY; hiders in final 30s', 'auto_farm', function(enabled) if enabled then for _, key in ipairs({ 'auto_credits', 'pull_lobby', 'auto_seek', 'pull_credits' }) do if settings[key] then settings[key] = false if on[key] then on[key](false) end end update_toggle(key) end auto.empty = 0 auto.phase = 'checking new round' auto.map = nil auto.shelter_character = nil auto.seed = nil auto.seed_userid = nil auto.seed_captured = false auto.seed_replacements, auto.seed_last_left, auto.seed_replacement_after = 0, 'none', 0 auto.time_valid = false auto.release_all = false else auto.phase, auto.empty, auto.target = 'idle', 0, nil auto.seed = nil auto.seed_userid = nil auto.release_all = false ui.clear_shelter(true) end end) info('autofarm', 'Credits > eight checks > ONE hider if lobby empty > LOBBY ONLY until final 30s', palette.muted, 10) info('autofarm', 'Server hops need a supported teleport-queue API. Restarting and round capture still depend on the executor and server.', palette.dim, 10) ui.auto_state = status_card('autofarm') warn_card('autofarm', 'NOTICE: HIGHLY VISIBLE / EXPERIMENTAL', 'Client-side player pulling does not guarantee tags or credit rewards. The out-of-map resting platform is local and the server may move you back. Auto farming can be reported by other players.') function ui.clear_shelter(restore) if auto.shelter then auto.shelter:Destroy(); auto.shelter = nil end if restore and auto.shelter_origin then local root = getroot(localplayer) if root then root.CFrame = auto.shelter_origin end end auto.shelter_origin = nil auto.shelter_character = nil auto.shelter_recovery_at = 0 end local function reset_round(reason) if not settings.auto_farm then return end auto.round_resets += 1 auto.last_round_reset = reason auto.empty = 0 auto.map = nil auto.target, auto.target_since = nil, 0 auto.seed, auto.seed_userid, auto.seed_captured = nil, nil, false auto.seed_replacements, auto.seed_last_left, auto.seed_replacement_after = 0, 'none', 0 auto.sweep_index, auto.lobby_index = 0, 0 auto.time_left, auto.time_valid, auto.release_all = nil, false, false auto.phase = 'Round reset (' .. reason .. '): waiting for next role' ui.clear_shelter(false) end local function on_seed_departure(player) if not settings.auto_farm or not player or auto.seed_userid ~= player.UserId then return end auto.seed_replacements += 1 auto.seed_last_left = player.DisplayName auto.seed, auto.seed_userid, auto.seed_captured = nil, nil, false auto.seed_replacement_after = os.clock() + 0.75 auto.target, auto.target_since = nil, 0 auto.phase = 'Captured target left: checking lobby or one new hider' notify('Auto Farm: ' .. player.DisplayName .. ' left; replacing only if the lobby is empty.') end bind(players.PlayerRemoving, on_seed_departure) local function is_round_ready() local running = gamedata:FindFirstChild('GameRunning') local selecting = gamedata:FindFirstChild('SelectingIt') if not running or not running.Value then return false, 'waiting for next round' end if selecting and selecting.Value then return false, 'waiting for It selection' end if not isit(localplayer) and not ingame(localplayer) then return false, 'waiting for role assignment' end return true end local function monitor_round() local running = gamedata:FindFirstChild('GameRunning') local selecting = gamedata:FindFirstChild('SelectingIt') local now_running = running and running.Value == true or false local now_selecting = selecting and selecting.Value == true or false local it = getit() local now_it = it and it.UserId or 0 local now_role = isit(localplayer) and 'IT' or (ingame(localplayer) and 'HIDER' or 'LOBBY') if auto.seen_running ~= nil then if auto.seen_running ~= now_running then reset_round(now_running and 'round started' or 'round ended') elseif auto.seen_selecting ~= now_selecting then reset_round(now_selecting and 'It selection started' or 'It selection finished') elseif auto.seen_it ~= now_it and now_it ~= 0 then reset_round('new It chosen') elseif auto.seen_role ~= now_role and now_running then reset_round('your role changed to ' .. now_role) end end auto.seen_running, auto.seen_selecting = now_running, now_selecting auto.seen_it, auto.seen_role = now_it, now_role end for _, name in ipairs({ 'GameRunning', 'SelectingIt' }) do local signal = gamedata:FindFirstChild(name) if signal and signal:IsA('ValueBase') then bind(signal:GetPropertyChangedSignal('Value'), monitor_round) end end local it_data = gamedata:FindFirstChild('It') local it_object = it_data and it_data:FindFirstChild('PlayerObject') if it_object and it_object:IsA('ObjectValue') then bind(it_object:GetPropertyChangedSignal('Value'), monitor_round) end bind(localplayer.CharacterAdded, function() reset_round('character respawned') end) monitor_round() every(0.5, monitor_round) local function outside_map() local root = getroot(localplayer) local map = workspace:FindFirstChild('Map') if not root or not map then return false end local center, extents if map:IsA('Model') then center, extents = map:GetBoundingBox() elseif map:IsA('BasePart') then center, extents = map.CFrame, map.Size else return false end if extents.X > 20000 or extents.Z > 20000 then return false end if not auto.shelter_origin then auto.shelter_origin = root.CFrame end local position = Vector3.new(center.Position.X + extents.X * 0.5 + 115, center.Position.Y + math.max(20, extents.Y * 0.35), center.Position.Z) if not auto.shelter or not auto.shelter.Parent then auto.shelter = new('Part', { Name = 'luna_shelter', Anchored = true, CastShadow = false, CanCollide = true, CanTouch = false, Size = Vector3.new(18, 1, 18), CFrame = CFrame.new(position), Material = Enum.Material.SmoothPlastic, Color = palette.accentdark, Transparency = 0.5 }, workspace) end root.AssemblyLinearVelocity = Vector3.zero root.CFrame = auto.shelter.CFrame + Vector3.new(0, 4, 0) auto.shelter_character = localplayer.Character auto.shelter_recovery_at = os.clock() + 3 return true end local function credit_count() local objects = workspace:FindFirstChild('GameObjects') if not objects then return nil end local count = 0 for _, part in ipairs(objects:GetChildren()) do if part:IsA('BasePart') and part.Name == 'Credit' then local collected = part:FindFirstChild('Collected') if not collected or not collected.Value then count += 1 end end end return count end local function round_seconds() local timer = replicatedstorage:FindFirstChild('Timer') local remaining = timer and timer:FindFirstChild('Time') local visible = timer and timer:FindFirstChild('TimeVisible') if not remaining or not remaining:IsA('ValueBase') then return nil end if visible and visible:IsA('BoolValue') and not visible.Value then return nil end local value = tonumber(remaining.Value) if not value or value < 0 or value > 86400 then return nil end return value end local function active_hiders() local result = {} for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and player.Parent == players and not isit(player) and ingame(player) and getroot(player) then table.insert(result, player) end end table.sort(result, function(a, b) return a.UserId < b.UserId end) return result end local function sweep_target() local candidates = active_hiders() if #candidates == 0 then return nil end auto.sweep_index = auto.sweep_index % #candidates + 1 return candidates[auto.sweep_index] end local function lobby_target() local candidates = {} for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and player.Parent == players and not isit(player) and not ingame(player) and getroot(player) then table.insert(candidates, player) end end if #candidates == 0 then return nil end table.sort(candidates, function(a, b) return a.UserId < b.UserId end) auto.lobby_index = auto.lobby_index % #candidates + 1 return candidates[auto.lobby_index] end local function queue_loader() local q = (type(queue_on_teleport) == 'function' and queue_on_teleport) or (type(queueonteleport) == 'function' and queueonteleport) or (type(syn) == 'table' and type(syn.queue_on_teleport) == 'function' and syn.queue_on_teleport) or (type(fluxus) == 'table' and type(fluxus.queue_on_teleport) == 'function' and fluxus.queue_on_teleport) if type(q) ~= 'function' then auto.hop_status = 'Executor has no teleport-queue API' return false end local local_path = 'luna.dev/scripts/hide_and_seek_extreme_v22.lua' local hosted_url = 'https://lunadev.fixseroalt.workers.dev/release/game-scripts/hide_and_seek_extreme.lua' local loader if type(readfile) == 'function' then local ok, content = pcall(readfile, local_path) if ok and type(content) == 'string' and content:find("luna.dev v22 loaded", 1, true) then loader = 'local s = readfile("luna.dev/scripts/hide_and_seek_extreme_v22.lua"); local f = loadstring(s); if f then f() end' end end if not loader then local ok, content = pcall(function() return game:HttpGet(hosted_url) end) if ok and type(content) == 'string' and content:find("luna.dev v22 loaded", 1, true) then loader = 'local f = loadstring(game:HttpGet("https://lunadev.fixseroalt.workers.dev/release/game-scripts/hide_and_seek_extreme.lua")); if f then f() end' end end if not loader then auto.hop_status = 'Save v22 as ' .. local_path .. ' to enable reinjection' return false end local ok = pcall(q, loader) if not ok then auto.hop_status = 'Teleport reinjection could not be queued' end return ok end local function fetch_public_servers(cursor) local url = 'https://games.roblox.com/v1/games/' .. tostring(game.PlaceId) .. '/servers/Public?sortOrder=Desc&limit=100' if cursor and cursor ~= '' then url = url .. '&cursor=' .. httpservice:UrlEncode(cursor) end local provider = (type(request) == 'function' and request) or (type(http_request) == 'function' and http_request) or (type(syn) == 'table' and type(syn.request) == 'function' and syn.request) local ok, body if provider then ok, body = pcall(function() local result = provider({ Url = url, Method = 'GET' }) if not result or result.StatusCode and result.StatusCode ~= 200 then error('server list request failed') end return result.Body end) else ok, body = pcall(function() return game:HttpGet(url) end) end if not ok or type(body) ~= 'string' then return nil end local decoded, result = pcall(httpservice.JSONDecode, httpservice, body) return decoded and type(result) == 'table' and result or nil end local function hop_to_busier_server() if auto.hop_attempt or not alive or S.fling_active or not settings.auto_server_hop or not settings.auto_farm then return end if #players:GetPlayers() >= 2 or os.clock() - started_at < 5 then return end if auto.hop_last > 0 and os.clock() - auto.hop_last < 35 then return end auto.hop_attempt = true auto.hop_last = os.clock() auto.hop_status = 'Looking for a populated server...' task.spawn(function() local best, largest = nil, 1 local cursor = nil for _ = 1, 2 do if not alive or not settings.auto_farm or #players:GetPlayers() >= 2 then break end local response = fetch_public_servers(cursor) if not response or type(response.data) ~= 'table' then auto.hop_status = 'Server list unavailable; will retry' break end for _, server in ipairs(response.data) do if type(server) == 'table' and type(server.id) == 'string' and server.id ~= game.JobId and type(server.playing) == 'number' and type(server.maxPlayers) == 'number' and server.playing >= 2 and server.playing < server.maxPlayers and server.playing > largest then best, largest = server.id, server.playing end end if best then break end cursor = response.nextPageCursor if not cursor then break end end if best and alive and settings.auto_farm and #players:GetPlayers() < 2 then if not queue_loader() then if auto.hop_status == 'Looking for a populated server...' then auto.hop_status = 'Autoexec not ready; staying in current server' end else storage.save() auto.hop_status = 'Joining server with ' .. largest .. ' players' local ok, err = pcall(function() teleportservice:TeleportToPlaceInstance(game.PlaceId, best, localplayer) end) if not ok then auto.hop_status = 'Teleport failed: ' .. tostring(err) end end elseif auto.hop_status == 'Looking for a populated server...' then auto.hop_status = 'No suitable public server found; retrying' end auto.hop_attempt = false end) end every(2, hop_to_busier_server) every(0.8, function() if not settings.auto_farm then return end if S.fling_active then auto.phase = 'Paused for player fling'; return end local ready, reason = is_round_ready() if not ready then auto.empty = 0 auto.phase = reason if auto.shelter then ui.clear_shelter(false) end return end local map = workspace:FindFirstChild('Map') if map ~= auto.map then auto.map, auto.empty, auto.target, auto.phase = map, 0, nil, 'checking' auto.seed, auto.seed_userid, auto.seed_captured = nil, nil, false auto.seed_replacements, auto.seed_last_left, auto.seed_replacement_after = 0, 'none', 0 auto.time_valid, auto.release_all = false, false ui.clear_shelter(true) end local count = credit_count() auto.scans += 1 if count == nil then auto.empty = 0 auto.phase = 'waiting for GameObjects' elseif count > 0 then auto.empty = 0 auto.phase = 'credits (' .. count .. ' available)' ui.clear_shelter(true) local part = find_nearest_credit(true) if part and F.teleport_credit(part, true) then auto.passes += 1 end else auto.empty = math.min(8, auto.empty + 1) auto.phase = auto.empty < 8 and ('confirming no credits (' .. auto.empty .. '/8)') or 'no credits confirmed' end end) every(0.06, function() if not settings.auto_farm or auto.empty < 8 or S.fling_active then return end local ready, reason = is_round_ready() if not ready then auto.phase = reason if auto.shelter then ui.clear_shelter(false) end return end local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') if not running or not running.Value then auto.phase = 'waiting for a round' auto.seed, auto.seed_userid, auto.target = nil, nil, nil auto.time_valid, auto.release_all = false, false elseif isit(localplayer) and seeking and seeking.Value then ui.clear_shelter(false) local now = os.clock() local remaining = round_seconds() auto.time_left = remaining if remaining and remaining > 0 then auto.time_valid = true end auto.release_all = auto.time_valid and remaining ~= nil and remaining <= 30 if auto.release_all then auto.phase = 'FINAL 30 SECONDS: remaining hiders eligible' if not auto.target or auto.target.Parent ~= players or not ingame(auto.target) or now - auto.target_since >= 0.75 then auto.target = sweep_target() auto.target_since = now end else if auto.seed_userid and auto.seed and auto.seed.Parent ~= players then on_seed_departure(auto.seed) end if auto.seed_userid == nil and os.clock() >= auto.seed_replacement_after then local lobby_available = false for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and player.Parent == players and not isit(player) and not ingame(player) and getroot(player) then lobby_available = true break end end if not lobby_available then local hiders = active_hiders() if #hiders > 0 then auto.seed = hiders[1] auto.seed_userid = auto.seed.UserId auto.seed_captured = false end end end local seed = auto.seed if seed and seed.Parent == players and seed.UserId == auto.seed_userid and not ingame(seed) then auto.seed_captured = true end if not auto.seed_captured and seed and ingame(seed) and getroot(seed) then auto.target = seed auto.phase = 'FIRST hider only: ' .. seed.DisplayName else auto.target = lobby_target() auto.phase = auto.target and 'LOBBY ONLY: remaining hiders protected' or 'Waiting for a lobby target; other hiders protected' end if not remaining then auto.phase = auto.phase .. ' (round timer unavailable)' end end if auto.target then local eligible = auto.release_all and ingame(auto.target) or (not auto.release_all and ((auto.seed_userid ~= nil and not auto.seed_captured and auto.target.UserId == auto.seed_userid and ingame(auto.target)) or (not ingame(auto.target)))) if eligible and F.pull_player(auto.target) then auto.pulls += 1 auto.last_target = auto.target.DisplayName end end elseif ingame(localplayer) and not isit(localplayer) then local character = localplayer.Character if auto.shelter_character ~= character then ui.clear_shelter(false) end if not auto.shelter or not auto.shelter.Parent then auto.phase = outside_map() and 'hider: local out-of-map shelter' or 'hider: shelter unavailable' else auto.phase = 'hider: local out-of-map shelter' if os.clock() >= auto.shelter_recovery_at then auto.shelter_recovery_at = os.clock() + 3 local root = getroot(localplayer) if root and (root.Position - auto.shelter.Position).Magnitude > 14 then root.AssemblyLinearVelocity = Vector3.zero root.CFrame = auto.shelter.CFrame + Vector3.new(0, 4, 0) auto.phase = 'hider: shelter position recovered' end end end else auto.phase = 'waiting for It to start seeking' auto.seed = nil auto.seed_userid = nil auto.time_valid, auto.release_all = false, false end end) every(0.3, function() ui.auto_state.Text = string.format('Status: %s\nRound: %s | Players: %d | Sweep: %s\nScans: %d | Empty: %d/8 | Credit TPs: %d\nPull updates: %d | Last: %s\nTarget departures: %d | Last left: %s\nRound resets: %d (%s)\nServer: %s', (S.fling_active and settings.auto_farm) and 'Paused for player fling' or auto.phase, auto.time_left and (math.floor(auto.time_left) .. 's') or 'unavailable', #players:GetPlayers(), auto.release_all and 'FINAL 30s' or 'LOBBY ONLY', auto.scans, auto.empty, auto.passes, auto.pulls, auto.last_target, auto.seed_replacements, auto.seed_last_left, auto.round_resets, auto.last_round_reset, auto.hop_status) end) table.insert(cleanups, function() ui.clear_shelter(false) end) end do heading('abilities', 'IT ABILITIES') toggle('abilities', 'No local cooldown', 'Clears the client timer; server cooldown may remain', 'it_no_cooldown', on.it_no_cooldown) toggle('abilities', 'Keep ability active', 'Re-uses your It ability while seeking', 'it_keep_active', on.it_keep_active) ui.ability_status = status_card('abilities') buttons('abilities', { { 'ACTIVATE ABILITY', function() if settings.it_no_cooldown then A.clear_cooldown() end A.press() notify('Ability input: ' .. A.last_result .. '. Server activation is not confirmed.') end, true }, { 'RESET CLIENT TIMER', function() if not A.can_use() then notify('Reset needs your seeker character during the seeking phase.') elseif A.clear_cooldown() then notify('Client timer cleared. Server cooldowns may still apply.') else notify('Client timer clear failed; check game state or the ability UI.') end end } }) warn_card('abilities', 'EXPERIMENTAL / CLIENT SIDE', 'Clears the AbilityHandler timer locally. Server-side cooldowns and durations remain enforced, and Sprint is never spam-toggled.') heading('abilities', 'PRACTICE AS A HIDER') info('abilities', 'Local previews. They run without being It and never activate server abilities.', palette.muted, 10) buttons('abilities', { { 'PRACTICE SPRINT', A.practice_sprint, true }, { 'PRACTICE GLUE', A.practice_glue } }) buttons('abilities', { { 'PRACTICE CAMERA / EXIT', A.practice_camera_toggle }, { 'PRACTICE SMASH', A.practice_smash } }) every(0.2, function() if settings.it_no_cooldown then A.bridge() A.clear_cooldown() end end) every(1, function() local character = localplayer.Character if character ~= A.last_character then A.last_character = character A.sprint_first = nil A.active, A.active_known = false, false end if settings.it_no_cooldown or settings.it_keep_active then A.bridge() end if settings.it_no_cooldown then A.clear_cooldown() end if settings.it_keep_active and A.can_use() then A.name = A.equipped_name() local is_sprint = string.lower(A.name) == 'sprint' local should_press = not A.active if is_sprint and not A.active_known and A.sprint_first == character then should_press = false end if should_press and os.clock() - A.last_attempt > (is_sprint and 4 or 2.3) then A.last_attempt = os.clock() if is_sprint then A.sprint_first = character end A.press() end elseif not A.can_use() then A.name = 'Unknown' end end) end do local purchase = { auto = false, running = false, queued = false, cancelled = false, bought = 0, spent = 0, failed = 0, scanned = 0, unconfirmed = 0, status = 'Ready. Purchases can deduct credits without awarding an item.', last_balance = nil } heading('shop', 'CREDIT AUTO BUYER') info('shop', 'Characters > Taunts > Pets, cheapest first. In-game credits only.', palette.accent, 10) local balance_label = info('shop', 'Balance: checking...', palette.text, 11) local scan_label = info('shop', 'Shop: not scanned', palette.muted, 10) local status_label = info('shop', purchase.status, palette.text, 10) local stats_label = info('shop', '', palette.muted, 10) local warning_label = warn_card('shop', 'CREDIT PURCHASE WARNING', 'Purchases may deduct credits without granting items. Auto Buy starts OFF. Both purchase buttons need a second click to confirm.') local pending_action, pending_expires = nil, 0 local function acknowledge(action) if pending_action == action and os.clock() < pending_expires then pending_action = nil warning_label.Text = 'Spending acknowledged. Inventory is checked after each purchase.' return true end pending_action = action pending_expires = os.clock() + 10 warning_label.Text = 'CAUTION: credits may be deducted without the item appearing. Click the same option again within 10 seconds to proceed.' notify('Purchase warning: click again within 10 seconds to confirm.') return false end local auto_button local function update_display() if not alive then return end local data = localplayer:FindFirstChild('PlayerData') local credit = data and data:FindFirstChild('Credits') balance_label.Text = 'Balance: ' .. (credit and tostring(credit.Value) or 'unavailable') .. ' credits' scan_label.Text = 'Found ' .. purchase.scanned .. ' credit-priced shop items' status_label.Text = purchase.status stats_label.Text = 'Confirmed: ' .. purchase.bought .. ' | Spent: ' .. purchase.spent .. ' | Unconfirmed: ' .. purchase.unconfirmed .. ' | Failed: ' .. purchase.failed if auto_button then auto_button.Text = 'AUTO BUY: ' .. (purchase.auto and 'ON' or 'OFF') auto_button.BackgroundColor3 = purchase.auto and palette.accentdark or palette.raised end end local function scan_shop() local maingui = playergui:FindFirstChild('MainGui') local shopframe = maingui and maingui:FindFirstChild('ShopFrame') local results, seen = {}, {} if not shopframe then return results, false end local kinds = { CharacterCredits = { 'Character', 'Characters', 'CharacterName', 1 }, TauntCredits = { 'Taunt', 'Taunts', 'TauntName', 2 }, PetCredits = { 'Pet', 'Pets', 'PetName', 3 } } local has_scroller = false for _, main_name in ipairs({ 'MainFrame', 'XBoxMainFrame' }) do local main = shopframe:FindFirstChild(main_name) local scrolling = main and main:FindFirstChild('ScrollingFrame') if scrolling then has_scroller = true for _, element in ipairs(scrolling:GetDescendants()) do local data = element:FindFirstChild('Data') if data then local entry_type = data:FindFirstChild('Type') local kind = entry_type and kinds[entry_type.Value] if kind then local name_obj = data:FindFirstChild(kind[3]) local price_obj = data:FindFirstChild('Prize') local name = name_obj and tostring(name_obj.Value) or '' local price = price_obj and tonumber(price_obj.Value) local key = kind[1] .. ':' .. name if name ~= '' and price and price >= 0 and price < 1000000000 and not seen[key] then seen[key] = true table.insert(results, { category = kind[1], bag = kind[2], name = name, price = price, priority = kind[4] }) end end end end end end table.sort(results, function(a, b) if a.priority ~= b.priority then return a.priority < b.priority end if a.price ~= b.price then return a.price < b.price end return a.name < b.name end) return results, has_scroller end local function start_purchase() if not alive or purchase.running then return end purchase.running = true purchase.cancelled = false task.spawn(function() local items, has_shop = scan_shop() purchase.scanned = #items local data = localplayer:FindFirstChild('PlayerData') local credit = data and data:FindFirstChild('Credits') local inventory = localplayer:FindFirstChild('Inventory') local remotes = replicatedstorage:FindFirstChild('Remotes') local remote = remotes and remotes:FindFirstChild('PurchaseItem') if not has_shop or not credit or not inventory or not remote or not remote:IsA('RemoteFunction') then purchase.status = 'Shop, inventory, credits or purchase remote not ready.' purchase.running = false update_display() return end local successful, pending = 0, 0 for _, item in ipairs(items) do if not alive or purchase.cancelled then break end local bag = inventory:FindFirstChild(item.bag) if bag and not bag:FindFirstChild(item.name) then local balance = tonumber(credit.Value) if balance and balance >= item.price then purchase.status = 'Buying ' .. item.category .. ': ' .. item.name .. ' (' .. item.price .. ' Cr)' update_display() local before = balance local ok, result = pcall(function() return remote:InvokeServer(item.name, item.category) end) if not alive then break end if ok and result then local expiration = os.clock() + 3 while alive and not purchase.cancelled and not bag:FindFirstChild(item.name) and os.clock() < expiration do task.wait(0.1) end if bag:FindFirstChild(item.name) then purchase.bought += 1 successful += 1 purchase.spent += math.max(0, before - (tonumber(credit.Value) or before)) else pending += 1 purchase.status = 'Server accepted ' .. item.name .. '; inventory not yet confirmed' end else purchase.failed += 1 purchase.status = 'Purchase declined: ' .. item.name end local charged = math.max(0, before - (tonumber(credit.Value) or before)) if charged > 0 and not bag:FindFirstChild(item.name) then purchase.unconfirmed += 1 purchase.spent += charged purchase.auto = false settings.auto_buy = false purchase.cancelled = true purchase.status = 'WARNING: spent ' .. charged .. ' credits on ' .. item.name .. ' but ownership was not confirmed. Purchases stopped.' warning_label.Text = 'WARNING: credits were deducted but ownership is not confirmed. Buying stopped to prevent further losses.' storage.schedule() update_display() break end update_display() task.wait(0.25) end end end purchase.running = false if alive then if purchase.cancelled then purchase.status = purchase.unconfirmed > 0 and purchase.status or 'Purchase run stopped.' else purchase.status = 'Finished: ' .. successful .. ' confirmed, ' .. pending .. ' pending. Other items may be unaffordable or rejected.' end update_display() if purchase.auto and purchase.queued and not purchase.cancelled then purchase.queued = false task.delay(0.5, function() if alive and purchase.auto and not purchase.running then start_purchase() end end) else purchase.queued = false end end end) end local made = buttons('shop', { { 'BUY AFFORDABLE NOW', function() if not acknowledge('buy') then return end if purchase.running then notify('A purchase run is already active.') else purchase.queued = false; start_purchase() end end, true }, { 'AUTO BUY: OFF', function() if not purchase.auto and not acknowledge('auto') then return end purchase.auto = not purchase.auto settings.auto_buy = purchase.auto storage.schedule() if purchase.auto then purchase.cancelled = false if purchase.running then purchase.queued = true else start_purchase() end else purchase.queued = false if purchase.running then purchase.cancelled = true purchase.status = 'Auto buy disabled; finishing current request.' end end update_display() end } }) auto_button = made[2] buttons('shop', { { 'STOP PURCHASES', function() purchase.auto = false settings.auto_buy = false storage.schedule() purchase.queued = false purchase.cancelled = true purchase.status = 'Stopping after the current server request...' update_display() end } }) info('shop', 'Skips gamepasses, developer products and owned items. Auto buy re-checks whenever you earn credits.', palette.dim, 9) update_display() task.spawn(function() local data = localplayer:WaitForChild('PlayerData', 12) local credit = data and data:WaitForChild('Credits', 12) if not alive or not credit then return end purchase.last_balance = tonumber(credit.Value) bind(credit:GetPropertyChangedSignal('Value'), function() if not alive then return end local current = tonumber(credit.Value) local increased = current and purchase.last_balance and current > purchase.last_balance purchase.last_balance = current update_display() if purchase.auto and increased then if purchase.running then purchase.queued = true else task.delay(0.35, function() if alive and purchase.auto and not purchase.running then start_purchase() end end) end end end) update_display() end) end do heading('tests', 'SEEKER CHANCE MONITOR') local chance_status = status_card('tests') info('tests', 'This is the client-calculated display chance, not verified server odds. A local multiplier can make the UI show 83% without changing who the server chooses.', palette.muted, 10) local preview = { value = 2, active = false, original = nil, instance = nil } local function multiplier_object() local data = localplayer:FindFirstChild('PlayerData') local obj = data and data:FindFirstChild('ItWeightMultiplier') if obj and obj:IsA('ValueBase') and type(obj.Value) == 'number' then return obj end return nil end local function reset_preview() if preview.active and preview.instance and preview.instance.Parent and preview.original ~= nil then pcall(function() preview.instance.Value = preview.original end) end preview.active, preview.original, preview.instance = false, nil, nil end info('tests', 'EXPERIMENTAL: The value below only changes the local client copy. It can change the game UI percentage without changing your server-controlled chance.', palette.danger, 10) input_row('tests', 'Client multiplier preview', '0.1–20x; not a server-side boost', 2, 0.1, 20, function(value) preview.value = value end) buttons('tests', { { 'APPLY LOCAL TEST', function() local obj = multiplier_object() if not obj then notify('ItWeightMultiplier is not available on your client.'); return end if preview.active and preview.instance ~= obj then reset_preview() end if not preview.active then preview.original = obj.Value preview.instance = obj end local ok = pcall(function() obj.Value = preview.value end) if ok then preview.active = true notify('Client UI preview: x' .. tostring(preview.value) .. '. Server chance is unchanged unless the server explicitly accepts it.') else notify('Experimental local multiplier could not be changed.') end end }, { 'RESET LOCAL TEST', function() reset_preview() notify('Restored the pre-test client multiplier.') end } }) every(0.6, function() if preview.active and (not preview.instance or not preview.instance.Parent) then preview.active, preview.original, preview.instance = false, nil, nil end local data = localplayer:FindFirstChild('PlayerData') local weight_obj = data and data:FindFirstChild('ItWeight') local multi_obj = multiplier_object() local afk_obj = data and data:FindFirstChild('AFK') local weight = weight_obj and tonumber(weight_obj.Value) local multiplier = multi_obj and tonumber(multi_obj.Value) local afk_known = afk_obj and afk_obj:IsA('BoolValue') local is_afk = afk_known and afk_obj.Value or false local eligible, combined, missing = 0, 0, 0 for _, player in ipairs(players:GetPlayers()) do local pdata = player:FindFirstChild('PlayerData') local pw = pdata and pdata:FindFirstChild('ItWeight') local pm = pdata and pdata:FindFirstChild('ItWeightMultiplier') local pa = pdata and pdata:FindFirstChild('AFK') local wn, mn = pw and tonumber(pw.Value), pm and tonumber(pm.Value) if not wn or not mn or not pa or not pa:IsA('BoolValue') then missing += 1 elseif not pa.Value then eligible += 1 combined += math.max(0, wn * mn) end end local estimate if missing > 0 or weight == nil or multiplier == nil or not afk_known then estimate = 'Loading selection data' elseif is_afk then estimate = '0.00% (game AFK flag is ON)' elseif combined <= 0 then estimate = 'Unavailable (zero total weight)' else estimate = string.format('%.2f%%', math.clamp(weight * multiplier / combined * 100, 0, 100)) end local state = not afk_known and 'UNKNOWN' or (is_afk and 'AFK: INELIGIBLE' or 'ELIGIBLE') local weight_text = weight and string.format('%.2f', weight) or '?' local multiplier_text = multiplier and string.format('%.2fx', multiplier) or '?' local preview_text = preview.active and ('ON (local x' .. tostring(preview.value) .. ')') or 'OFF' local msg = 'CLIENT DISPLAY estimate: ' .. estimate .. ' | SERVER chance: UNKNOWN\n' .. 'Game AFK flag: ' .. state .. ' | ItWeight: ' .. weight_text .. ' | Multiplier: ' .. multiplier_text .. '\n' .. 'Candidates: ' .. tostring(eligible) .. ' | Missing player data: ' .. tostring(missing) .. '\n' .. 'Experimental preview: ' .. preview_text .. ' | A missed selection does not prove the odds' chance_status.Text = msg if ui.home_chance then ui.home_chance.Text = msg end end) table.insert(cleanups, reset_preview) end do heading('tests', 'LOCAL EXPERIMENTS') toggle('tests', 'Pull credits to me', 'Holds one coin at you for 1.15s (local test)', 'pull_credits', on.pull_credits) warn_card('tests', 'CLIENT-ONLY TEST: NOT CONFIRMED REWARDS', 'Credit pickups may disappear locally without awarding coins. Server-authoritative rewards and gamepasses cannot be granted by moving client-side copies.') local owned_label = info('tests', 'Triple Coin Value (pass 592144): not checked', palette.muted, 10) ui.test_stats = info('tests', 'Coin pull attempts: 0 | Credits: +0', palette.muted, 10) local running_equip = false local function discover_gamepass_items() local main = playergui:FindFirstChild('MainGui') local shop = main and main:FindFirstChild('ShopFrame') if not shop then return {} end local items, recorded = {}, {} local remote_for = { CharacterGamepass = 'EquipCharacter', TauntGamepass = 'EquipTaunt', PetGamepass = 'EquipPet' } local name_for = { CharacterGamepass = 'CharacterName', TauntGamepass = 'TauntName', PetGamepass = 'PetName' } for _, section in ipairs({ 'MainFrame', 'XBoxMainFrame' }) do local frame = shop:FindFirstChild(section) local scroller = frame and frame:FindFirstChild('ScrollingFrame') if scroller then for _, item in ipairs(scroller:GetDescendants()) do local data = item:FindFirstChild('Data') local type_value = data and data:FindFirstChild('Type') local kind = type_value and type(type_value.Value) == 'string' and type_value.Value if kind and remote_for[kind] then local name_value = data:FindFirstChild(name_for[kind]) if name_value and name_value.Value ~= '' then local id = remote_for[kind] .. ':' .. tostring(name_value.Value) if not recorded[id] then recorded[id] = true table.insert(items, { name = name_value.Value, remote = remote_for[kind] }) end end end end end end return items end buttons('tests', { { 'CHECK 3X OWNERSHIP', function() notify('Checking gamepass ownership...') task.spawn(function() local ok, result = pcall(function() return marketplace:UserOwnsGamePassAsync(localplayer.UserId, 592144) end) if not alive then return end owned_label.Text = 'Triple Coin Value: ' .. (ok and (result and 'OWNED' or 'NOT OWNED') or 'check unavailable') notify(ok and 'Gamepass ownership check complete.' or 'Could not check gamepass ownership.') end) end }, { 'TRY GAMEPASS EQUIPS', function() if running_equip then notify('An equip test is already running.'); return end local items = discover_gamepass_items() if #items == 0 then notify('No gamepass entries found in the shop UI.'); return end local remotes = replicatedstorage:FindFirstChild('Remotes') if not remotes then notify('Game equip remotes are unavailable.'); return end running_equip = true notify('Sending normal equip requests. Non-owned gamepasses are not granted.') task.spawn(function() local attempted = 0 for i, entry in ipairs(items) do if not alive or i > 16 then break end local remote = remotes:FindFirstChild(entry.remote) if remote and remote:IsA('RemoteEvent') then if pcall(function() remote:FireServer(entry.name) end) then attempted += 1 end end task.wait(0.4) end running_equip = false if alive then notify('Sent ' .. attempted .. ' equip requests. Ownership is server-controlled.') end end) end } }) end do heading('config', 'SAVED PREFERENCES') storage.label = info('config', storage.state, palette.muted, 10) buttons('config', { { 'SAVE SETTINGS NOW', function() if storage.save() then notify('Saved all luna.dev settings.') else notify('Could not save: executor file access may be unavailable.') end end, true }, { 'RESET TO DEFAULTS', function() for key, value in pairs(storage.defaults) do if settings[key] ~= value then settings[key] = value if on[key] then on[key](value) end end update_toggle(key) end move.subtle_speed, move.subtle_jump = true, true storage.schedule() notify('Settings reset to defaults.') end } }) heading('config', 'SYSTEM') toggle('config', 'Anti-AFK', 'Sends a harmless input when you go idle', 'anti_afk') ui.config_afk = info('config', 'Anti-AFK pulses sent: 0', palette.muted, 10) info('config', 'Auto-save covers every switch, the warning distance and the movement values. Right Shift hides or shows the menu.', palette.dim, 10) info('config', 'Storage: ' .. storage.path, palette.dim, 9) end local selecting_it = gamedata:FindFirstChild('SelectingIt') local it_record = gamedata:FindFirstChild('It') local it_object = it_record and it_record:FindFirstChild('PlayerObject') local last_seen_it = it_object and it_object.Value local early_candidate local function refresh_early_it() if not settings.early_it or not selecting_it or not selecting_it.Value then early_banner.Visible = false return end early_banner.Visible = true if early_candidate and early_candidate.Parent == players then early_text.Text = 'NEXT IT: ' .. early_candidate.DisplayName .. ' (@' .. early_candidate.Name .. ')' early_text.TextColor3 = palette.gold else early_text.Text = 'SELECTING IT | Awaiting server choice' early_text.TextColor3 = palette.muted end end if selecting_it then bind(selecting_it:GetPropertyChangedSignal('Value'), function() early_candidate = nil if selecting_it.Value and it_object and it_object.Value and it_object.Value ~= last_seen_it then early_candidate = it_object.Value end refresh_early_it() end) end if it_object then bind(it_object:GetPropertyChangedSignal('Value'), function() if selecting_it and selecting_it.Value and it_object.Value and it_object.Value:IsA('Player') then early_candidate = it_object.Value end last_seen_it = it_object.Value refresh_early_it() end) end local function watch_it_flag(player) task.spawn(function() local data = player:FindFirstChild('PlayerData') or player:WaitForChild('PlayerData', 10) local it_flag = data and (data:FindFirstChild('It') or data:WaitForChild('It', 10)) if not alive or player.Parent ~= players or not it_flag then return end bind(it_flag:GetPropertyChangedSignal('Value'), function() if selecting_it and selecting_it.Value and it_flag.Value == true then early_candidate = player refresh_early_it() end end) end) end for _, player in ipairs(players:GetPlayers()) do watch_it_flag(player) end bind(players.PlayerAdded, watch_it_flag) do local function reveal(entry) show_page(entry.page) task.delay(0.05, function() local page = pages[entry.page] if not alive or not page or not entry.row.Parent then return end page.CanvasPosition = Vector2.new(0, math.max(0, entry.row.AbsolutePosition.Y - page.AbsolutePosition.Y + page.CanvasPosition.Y - 4)) end) end local function update_results() local query = string.lower(ui.search.Text):match('^%s*(.-)%s*$') for _, child in ipairs(ui.results:GetChildren()) do if child:IsA('GuiObject') then child:Destroy() end end if query == '' or S.minimized then ui.results.Visible = false return end ui.log_panel.Visible = false ui.results.Visible = true local hits = 0 for _, entry in ipairs(search_index) do if hits >= 25 then break end if string.find(string.lower(entry.title), query, 1, true) or string.find(string.lower(entry.desc), query, 1, true) then hits += 1 local item = new('TextButton', { Size = UDim2.new(1, 0, 0, 26), BackgroundColor3 = palette.card, BorderSizePixel = 0, Text = string.upper(entry.page) .. ' / ' .. entry.title, TextColor3 = palette.text, TextSize = 10, TextTruncate = Enum.TextTruncate.AtEnd, TextXAlignment = Enum.TextXAlignment.Left, Font = Enum.Font.GothamMedium, ZIndex = 41, LayoutOrder = hits }, ui.results) round(item, 5) new('UIPadding', { PaddingLeft = UDim.new(0, 8) }, item) bind(item.MouseButton1Click, function() ui.search.Text = '' reveal(entry) end) end end if hits == 0 then text(ui.results, 'No feature matches "' .. ui.search.Text .. '".', 11, palette.muted, { Size = UDim2.new(1, 0, 0, 26), ZIndex = 41 }) end end bind(ui.search:GetPropertyChangedSignal('Text'), update_results) end function ui.shutdown() if not alive then return end storage.revision += 1 storage.save() alive = false for _, connection in ipairs(connections) do connection:Disconnect() end for _, fn in ipairs(cleanups) do pcall(fn) end early_gui:Destroy() gui:Destroy() end bind(close_button.MouseButton1Click, ui.shutdown) bind(min_button.MouseButton1Click, function() S.minimized = not S.minimized window.Size = S.minimized and UDim2.fromOffset(win_w, HEADER) or UDim2.fromOffset(win_w, win_h) sidebar.Visible = not S.minimized content.Visible = not S.minimized min_button.Text = S.minimized and '+' or '-' ui.results.Visible = false ui.log_panel.Visible = false show_page(current_page) end) local dragging, drag_origin, window_origin = false, nil, nil bind(header.InputBegan, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true drag_origin = input.Position window_origin = window.Position end end) bind(userinputservice.InputChanged, function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - drag_origin window.Position = UDim2.new(window_origin.X.Scale, window_origin.X.Offset + delta.X, window_origin.Y.Scale, window_origin.Y.Offset + delta.Y) end end) local resizing, resize_start, resize_w, resize_h = false, nil, 0, 0 local resize_handle = new('TextButton', { Name = 'ResizeHandle', Position = UDim2.new(1, -18, 1, -18), Size = UDim2.fromOffset(16, 16), Text = '', BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 180 }, window) for _, offset in ipairs({ 5, 9, 13 }) do new('Frame', { Size = UDim2.fromOffset(offset, 1), Position = UDim2.fromOffset(15 - offset, offset + 1), Rotation = -45, BackgroundColor3 = palette.accent, BorderSizePixel = 0, ZIndex = 180 }, resize_handle) end bind(resize_handle.InputBegan, function(input) if S.minimized then return end if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then resizing = true resize_start = input.Position resize_w, resize_h = win_w, win_h end end) bind(userinputservice.InputChanged, function(input) if resizing and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - resize_start win_w = math.clamp(resize_w + delta.X * 2, 500, 980) win_h = math.clamp(resize_h + delta.Y * 2, 300, 780) window.Size = UDim2.fromOffset(win_w, win_h) end end) bind(userinputservice.InputEnded, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false resizing = false end end) bind(userinputservice.InputBegan, function(input, processed) if not processed and input.KeyCode == Enum.KeyCode.RightShift then window.Visible = not window.Visible end end) bind(gui.AncestryChanged, function(_, parent) if not parent then ui.shutdown() end end) do local frames, frame_time = 0, 0 local function ping() local ok, value = pcall(function() return statsservice.Network.ServerStatsItem['Data Ping']:GetValue() end) return ok and math.floor(value + 0.5) or nil end bind(runservice.Heartbeat, function(dt) frames += 1 frame_time += dt if frame_time >= 0.5 then local fps = math.floor(frames / frame_time + 0.5) local p = ping() ui.stats.Text = 'FPS ' .. fps .. ' / ' .. (p and (p .. 'ms') or '--') frames, frame_time = 0, 0 end end) end local function format_time(seconds) seconds = math.floor(seconds) return string.format('%dh %02dm', seconds // 3600, (seconds % 3600) // 60) end every(0.15, function() if settings.fullbright then lighting.Brightness = 3 lighting.ClockTime = 14 lighting.FogEnd = 100000 lighting.GlobalShadows = false lighting.Ambient = Color3.fromRGB(210, 210, 220) lighting.OutdoorAmbient = Color3.fromRGB(210, 210, 220) end V.sync_players() ui.update_rows() refresh_early_it() V.update_seeker_radius() V.update_credit_direction() local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') local it = getit() local phase = (not running or not running.Value) and 'INTERMISSION' or (seeking and seeking.Value and 'SEEKING' or 'HIDING') local role = isit(localplayer) and 'IT' or (ingame(localplayer) and 'HIDER' or 'SPECTATOR') ui.status.Text = phase .. ' / ' .. role .. ' / IT: ' .. (it and it.Name or '?') local data = localplayer:FindFirstChild('PlayerData') local credit = data and data:FindFirstChild('Credits') local balance = credit and typeof(credit.Value) == 'number' and credit.Value if balance then if F.credit_last ~= nil and balance > F.credit_last then F.verified_gains += balance - F.credit_last end F.credit_last = balance end local lobby_count, hider_count = 0, 0 for _, player in ipairs(players:GetPlayers()) do if player ~= localplayer and getroot(player) then if not ingame(player) and not isit(player) then lobby_count += 1 elseif ingame(player) and not isit(player) then hider_count += 1 end end end local reason = not isit(localplayer) and 'not It' or (not running or not running.Value) and 'no round' or (not seeking or not seeking.Value) and 'waiting for seek' or lobby_count == 0 and 'no eligible lobby targets' or 'server acceptance unknown' ui.lobby_debug.Text = string.format('%d lobby targets / %d hiders | %s', lobby_count, hider_count, reason) ui.farm_status.Text = 'Credit TPs: ' .. F.credit_attempts .. ' | Lobby targets: ' .. F.lobby_targets .. ' | Pull ticks: ' .. F.pull_ticks ui.test_stats.Text = 'Coin pull attempts: ' .. F.pull_credit_attempts .. ' | Credits: +' .. F.verified_gains ui.ability_status.Text = 'Ability: ' .. A.name .. ' | Active: ' .. (A.active_known and (A.active and 'YES' or 'NO') or 'UNKNOWN') .. ' | Attempts: ' .. A.attempts .. '\nClient cooldown: ' .. (settings.it_no_cooldown and (A.err and 'clear failed' or ('cleared ' .. A.clears .. ' / intercepted ' .. A.intercepts)) or 'off') .. '\n' .. A.last_result ui.config_afk.Text = 'Anti-AFK pulses sent: ' .. S.afk_pulses ui.home_status.Text = string.format('Round: %s | Role: %s | It: %s\nCredits: %s | Session: %s | AFK pulses: %d', phase, role, it and it.DisplayName or '?', balance and tostring(balance) or '--', format_time(os.clock() - started_at), S.afk_pulses) if S.spectating then local _, humanoid = getroot(S.spectating) if not humanoid then restore_camera() end end end) every(0.2, function() V.sync_credits() V.sync_teleporters() V.sync_hazards() end) every(0.12, function() if not S.fling_active then F.try_evade() end end) every(1.6, function() if not S.fling_active and settings.pull_credits and F.try_pull_credit() then F.pull_credit_attempts += 1 end end) every(0.06, function() local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') if not S.fling_active and settings.pull_lobby and isit(localplayer) and running and running.Value and seeking and seeking.Value then F.try_pull_lobby() else F.lobby_target = nil F.lobby_started = 0 end end) every(0.7, function() if not S.fling_active and settings.auto_credits then local part = find_nearest_credit(true) if part and F.teleport_credit(part, true) then F.credit_attempts += 1 end end end) every(2, function() local running = gamedata:FindFirstChild('GameRunning') local seeking = gamedata:FindFirstChild('ItSeeking') if not S.fling_active and settings.auto_seek and isit(localplayer) and running and running.Value and seeking and seeking.Value then local target = nearest_hider() if target then teleport(target) end end end) ui.refresh_players() V.sync_players() show_page('home') if not storage.loaded then storage.save() end notify('luna.dev v22 loaded' .. (storage.loaded and ' (settings restored)' or '') .. '. Right Shift hides the menu.')