Grinding out credits in Hide and Seek Extreme script sessions can get super repetitive when you just want to grab cool characters from the shop. Running around maps trying to stay hidden or hunting down other players takes way too much active focus if you are busy multitasking.
The basic loop here puts one player in the role of It while everyone else scrambles to hide around the map. It characters come with special abilities you trigger by pressing 1, and you can even press T to taunt your friends. You dodge hazards, collect credits, and try to survive until the timer runs out.
Using the Luna.dev utility menu lets you automate a ton of the busywork so you can chill out. Here is the open-source code you need to get it running.
Hide and Seek Extreme Script – Luna.dev — Hide and Seek Extreme & More
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.')Copy the code above into a compatible Roblox script executor if you choose to test it.
Hide and Seek Extreme Script Status
Roblox and game updates can affect compatibility, so the script’s status should be treated as temporary rather than guaranteed.
Frequently Asked Questions
What is a Hide and Seek Extreme script?
A Hide and Seek Extreme script is third-party Lua code intended to run alongside the Roblox game through a compatible script executor.
What features does this Hide and Seek Extreme script include?
Different scripts contain different code. This version includes: Luna.dev — Hide and Seek Extreme, SMART AUTO FARM, Lobby player farming, Captures remaining hiders during the final 30 seconds, Automatic round and role detection, Replaces farming targets when players leave, AFK shelter and automatic recovery, PLAYER TOOLS, Teleport and spectate players, Fling selected player, Fling everyone except It.
How do you use the Hide and Seek Extreme script?
Pick a compatible executor such as Hydrogen, MacSploit, AWP.GG, Delta, Fluxus, Codex, launch Roblox and join the game, copy the complete Lua code from the script card above, paste it into the executor’s editor, and click Run or Execute. Compatibility changes over time, so a name here doesn’t guarantee current support.
Can a Hide and Seek Extreme script get your Roblox account banned?
Yes. Third-party scripts can violate Roblox rules and may put an account at risk. Only use code from a source you trust, never enter your Roblox password into a script or executor, and test on an alternate account first.
Does the Hide and Seek Extreme script work on mobile?
Check whether both the executor and the script support your device and the current Roblox version. Mobile executor support does not guarantee that every script will work.