local function ref(obj)
local ok, cloned = pcall(function()
return cloneref(obj)
end)
return (ok and cloned) or obj
end
local Players = ref(game:GetService("Players"))
local RunService = ref(game:GetService("RunService"))
local UserInputService = ref(game:GetService("UserInputService"))
local CoreGui = ref(game:GetService("CoreGui"))
local HttpService = ref(game:GetService("HttpService"))
local Lighting = ref(game:GetService("Lighting"))
local TweenService = ref(game:GetService("TweenService"))
local LocalPlayer = Players.LocalPlayer
local function rndName(prefix)
local suffix = HttpService:GenerateGUID(false):gsub("-", ""):sub(1, 12)
return (prefix or "") .. suffix
end
local SESSION = rndName("s")
local BIND_NAME = rndName("rb")
local GUI_NAME = rndName("ui")
local HOLDER_NAME = rndName("hd")
local COLOR_PRESETS = {
{ name = "Red", color = Color3.fromRGB(255, 70, 70) },
{ name = "Orange", color = Color3.fromRGB(255, 140, 40) },
{ name = "Yellow", color = Color3.fromRGB(255, 220, 60) },
{ name = "Green", color = Color3.fromRGB(60, 220, 100) },
{ name = "Cyan", color = Color3.fromRGB(60, 220, 230) },
{ name = "Blue", color = Color3.fromRGB(70, 170, 255) },
{ name = "Purple", color = Color3.fromRGB(170, 90, 255) },
{ name = "Pink", color = Color3.fromRGB(255, 90, 180) },
{ name = "White", color = Color3.fromRGB(240, 240, 245) },
{ name = "Black", color = Color3.fromRGB(20, 20, 24) },
}
local Settings = {
Enabled = true,
ShowTeammates = false,
Skeleton = true,
Box = true,
Health = true,
Name = true,
Glow = true,
EnemyColor = Color3.fromRGB(255, 70, 70),
TeamColor = Color3.fromRGB(70, 170, 255),
SkeletonThickness = 1.4,
BoxThickness = 1.4,
-- Misc
AntiFlash = false,
RemoveSmoke = false,
CustomEnv = false,
CustomSky = false,
EnvColor = Color3.fromRGB(128, 128, 128),
SkyColor = Color3.fromRGB(80, 140, 220),
MenuAccent = Color3.fromRGB(47, 128, 255),
}
-- Original lighting snapshot for restore
local LightingBackup = {
Ambient = Lighting.Ambient,
OutdoorAmbient = Lighting.OutdoorAmbient,
ColorShift_Top = Lighting.ColorShift_Top,
ColorShift_Bottom = Lighting.ColorShift_Bottom,
Brightness = Lighting.Brightness,
FogColor = Lighting.FogColor,
}
----------------------------------------------------------------
-- Languages (en default, tr, ru, vi)
----------------------------------------------------------------
local LANGUAGE_OPTIONS = {
{ code = "en", label = "English" },
{ code = "tr", label = "Türkçe" },
{ code = "ru", label = "Русский" },
{ code = "vi", label = "Tiếng Việt" },
}
local LANGUAGE_FILE = "DedeHub/Language.txt"
local Locales = {
en = {
hub_name = "DEDE HUB",
nav_vision = "Vision",
nav_entities = "Entities",
nav_misc = "Misc",
nav_settings = "Settings",
sec_esp = "ESP",
sec_esp_sub = "Wall vision overlays",
tog_skeleton = "Bone / Skeleton",
tog_skeleton_desc = "Joint line overlay",
tog_box = "Box",
tog_box_desc = "2D bounding box",
tog_health = "Health",
tog_health_desc = "Side health bar",
tog_name = "Name",
tog_name_desc = "Player name tag",
tog_glow = "Glow",
tog_glow_desc = "Filled body glow",
sec_filters = "Filters",
tog_teammates = "Show teammates",
tog_teammates_desc = "Include same team",
tog_master = "Master ESP",
tog_master_desc = "Enable all overlays",
sec_players = "Players",
sec_players_sub = "Who appears on ESP",
tog_teammates_ent_desc = "Same team players",
tog_master_ent_desc = "Global ESP switch",
sec_protection = "Protection",
sec_protection_sub = "Visual countermeasures",
tog_antiflash = "Anti Flash",
tog_antiflash_desc = "Lighting + screen flash block",
tog_smoke = "Remove Smoke",
tog_smoke_desc = "Smoke / fog / particles",
sec_world = "World",
sec_world_sub = "Lighting & atmosphere",
tog_env = "Environment color",
tog_env_desc = "Tint ambient lighting",
tog_sky = "Sky color",
tog_sky_desc = "Tint sky / atmosphere",
color_env = "Environment tint",
color_sky = "Sky tint",
sec_esp_colors = "ESP Colors",
sec_esp_colors_sub = "Overlay palette",
color_enemy = "Enemy color",
color_team = "Teammate color",
sec_interface = "Interface",
sec_interface_sub = "Menu controls",
tip_controls = "• DEL — hide / show menu\n• Drag from the top to move\n• Use the left sidebar to switch tabs",
sec_appearance = "Appearance",
sec_appearance_sub = "Menu accent color",
color_menu = "Menu color",
sec_language = "Language",
sec_language_sub = "UI language",
sec_session = "Session",
sec_session_sub = "Unload cheat completely",
btn_destroy = "Destroy — kill script",
btn_closing = "Closing...",
},
tr = {
hub_name = "DEDE HUB",
nav_vision = "Görüş",
nav_entities = "Varlıklar",
nav_misc = "Diğer",
nav_settings = "Ayarlar",
sec_esp = "ESP",
sec_esp_sub = "Duvar arkası görüş",
tog_skeleton = "Kemik / Skeleton",
tog_skeleton_desc = "Eklem çizgileri",
tog_box = "Kutu",
tog_box_desc = "2D sınır kutusu",
tog_health = "Can",
tog_health_desc = "Yan can barı",
tog_name = "İsim",
tog_name_desc = "Oyuncu isim etiketi",
tog_glow = "Parlama",
tog_glow_desc = "Gövde dolgu parlaması",
sec_filters = "Filtreler",
tog_teammates = "Takımı göster",
tog_teammates_desc = "Aynı takımı dahil et",
tog_master = "Ana ESP",
tog_master_desc = "Tüm overlay'leri aç",
sec_players = "Oyuncular",
sec_players_sub = "ESP'de kimler görünsün",
tog_teammates_ent_desc = "Aynı takım oyuncuları",
tog_master_ent_desc = "Global ESP anahtarı",
sec_protection = "Koruma",
sec_protection_sub = "Görsel karşı önlemler",
tog_antiflash = "Anti Flash",
tog_antiflash_desc = "Işık + ekran flash engeli",
tog_smoke = "Smoke Kaldır",
tog_smoke_desc = "Duman / sis / particle",
sec_world = "Dünya",
sec_world_sub = "Işık ve atmosfer",
tog_env = "Çevre rengi",
tog_env_desc = "Ortam ışığını renklendir",
tog_sky = "Gökyüzü rengi",
tog_sky_desc = "Gökyüzü / atmosfer tonu",
color_env = "Çevre tonu",
color_sky = "Gökyüzü tonu",
sec_esp_colors = "ESP Renkleri",
sec_esp_colors_sub = "Overlay paleti",
color_enemy = "Düşman rengi",
color_team = "Takım rengi",
sec_interface = "Arayüz",
sec_interface_sub = "Menü kontrolleri",
tip_controls = "• DEL — menüyü gizle / göster\n• Üstten tutup sürükle\n• Sol menüden sekmeler arasında geç",
sec_appearance = "Görünüm",
sec_appearance_sub = "Menü vurgu rengi",
color_menu = "Menü rengi",
sec_language = "Dil",
sec_language_sub = "Arayüz dili",
sec_session = "Oturum",
sec_session_sub = "Hileyi tamamen kapat",
btn_destroy = "Destroy — scripti kapat",
btn_closing = "Kapatılıyor...",
},
ru = {
hub_name = "DEDE HUB",
nav_vision = "Обзор",
nav_entities = "Сущности",
nav_misc = "Разное",
nav_settings = "Настройки",
sec_esp = "ESP",
sec_esp_sub = "Обзор сквозь стены",
tog_skeleton = "Кости / Skeleton",
tog_skeleton_desc = "Линии суставов",
tog_box = "Бокс",
tog_box_desc = "2D рамка",
tog_health = "Здоровье",
tog_health_desc = "Полоска здоровья",
tog_name = "Имя",
tog_name_desc = "Имя игрока",
tog_glow = "Свечение",
tog_glow_desc = "Заливка тела",
sec_filters = "Фильтры",
tog_teammates = "Показывать команду",
tog_teammates_desc = "Включать союзников",
tog_master = "Главный ESP",
tog_master_desc = "Включить все оверлеи",
sec_players = "Игроки",
sec_players_sub = "Кто виден в ESP",
tog_teammates_ent_desc = "Игроки своей команды",
tog_master_ent_desc = "Глобальный ESP",
sec_protection = "Защита",
sec_protection_sub = "Визуальные контрмеры",
tog_antiflash = "Anti Flash",
tog_antiflash_desc = "Блок вспышек света / экрана",
tog_smoke = "Убрать дым",
tog_smoke_desc = "Дым / туман / частицы",
sec_world = "Мир",
sec_world_sub = "Освещение и атмосфера",
tog_env = "Цвет окружения",
tog_env_desc = "Оттенок ambient света",
tog_sky = "Цвет неба",
tog_sky_desc = "Оттенок неба / атмосферы",
color_env = "Тон окружения",
color_sky = "Тон неба",
sec_esp_colors = "Цвета ESP",
sec_esp_colors_sub = "Палитра оверлея",
color_enemy = "Цвет врага",
color_team = "Цвет союзника",
sec_interface = "Интерфейс",
sec_interface_sub = "Управление меню",
tip_controls = "• DEL — скрыть / показать меню\n• Тяни за верх, чтобы переместить\n• Вкладки слева",
sec_appearance = "Оформление",
sec_appearance_sub = "Акцентный цвет меню",
color_menu = "Цвет меню",
sec_language = "Язык",
sec_language_sub = "Язык интерфейса",
sec_session = "Сессия",
sec_session_sub = "Полностью выгрузить чит",
btn_destroy = "Destroy — закрыть скрипт",
btn_closing = "Закрытие...",
},
vi = {
hub_name = "DEDE HUB",
nav_vision = "Tầm nhìn",
nav_entities = "Thực thể",
nav_misc = "Khác",
nav_settings = "Cài đặt",
sec_esp = "ESP",
sec_esp_sub = "Nhìn xuyên tường",
tog_skeleton = "Xương / Skeleton",
tog_skeleton_desc = "Đường khớp xương",
tog_box = "Hộp",
tog_box_desc = "Khung 2D",
tog_health = "Máu",
tog_health_desc = "Thanh máu bên cạnh",
tog_name = "Tên",
tog_name_desc = "Nhãn tên người chơi",
tog_glow = "Phát sáng",
tog_glow_desc = "Tô sáng cơ thể",
sec_filters = "Bộ lọc",
tog_teammates = "Hiện đồng đội",
tog_teammates_desc = "Bao gồm cùng đội",
tog_master = "ESP chính",
tog_master_desc = "Bật mọi overlay",
sec_players = "Người chơi",
sec_players_sub = "Ai hiện trên ESP",
tog_teammates_ent_desc = "Người cùng đội",
tog_master_ent_desc = "Công tắc ESP toàn cục",
sec_protection = "Bảo vệ",
sec_protection_sub = "Chống hiệu ứng thị giác",
tog_antiflash = "Anti Flash",
tog_antiflash_desc = "Chặn flash ánh sáng / màn hình",
tog_smoke = "Xóa khói",
tog_smoke_desc = "Khói / sương / particle",
sec_world = "Thế giới",
sec_world_sub = "Ánh sáng & bầu khí quyển",
tog_env = "Màu môi trường",
tog_env_desc = "Tô màu ánh sáng ambient",
tog_sky = "Màu bầu trời",
tog_sky_desc = "Tông bầu trời / atmosphere",
color_env = "Tông môi trường",
color_sky = "Tông bầu trời",
sec_esp_colors = "Màu ESP",
sec_esp_colors_sub = "Bảng màu overlay",
color_enemy = "Màu địch",
color_team = "Màu đồng đội",
sec_interface = "Giao diện",
sec_interface_sub = "Điều khiển menu",
tip_controls = "• DEL — ẩn / hiện menu\n• Kéo từ trên để di chuyển\n• Đổi tab ở thanh bên trái",
sec_appearance = "Giao diện màu",
sec_appearance_sub = "Màu nhấn menu",
color_menu = "Màu menu",
sec_language = "Ngôn ngữ",
sec_language_sub = "Ngôn ngữ giao diện",
sec_session = "Phiên",
sec_session_sub = "Tắt hoàn toàn cheat",
btn_destroy = "Destroy — tắt script",
btn_closing = "Đang đóng...",
},
}
local function normalizeLanguage(code)
code = tostring(code or "en"):lower()
if Locales[code] then
return code
end
return "en"
end
local function readSavedLanguage()
local fromEnv = nil
pcall(function()
if typeof(getgenv) == "function" then
fromEnv = getgenv().DedeHubLanguage
end
end)
if type(fromEnv) == "string" and #fromEnv > 0 then
return fromEnv
end
if typeof(isfile) == "function" and typeof(readfile) == "function" then
local ok, content = pcall(function()
if isfile(LANGUAGE_FILE) then
return readfile(LANGUAGE_FILE)
end
return nil
end)
if ok and type(content) == "string" and #content > 0 then
return content:match("%S+")
end
end
return "en"
end
local function persistLanguage(code)
pcall(function()
if typeof(getgenv) == "function" then
getgenv().DedeHubLanguage = code
end
end)
if typeof(writefile) == "function" then
pcall(function()
if typeof(makefolder) == "function" and typeof(isfolder) == "function" and not isfolder("DedeHub") then
makefolder("DedeHub")
end
writefile(LANGUAGE_FILE, code)
end)
end
end
local currentLanguage = normalizeLanguage(readSavedLanguage())
persistLanguage(currentLanguage)
local function t(key, ...)
local pack = Locales[currentLanguage] or Locales.en
local str = pack[key] or Locales.en[key] or tostring(key)
if select("#", ...) > 0 then
local ok, formatted = pcall(string.format, str, ...)
if ok then
return formatted
end
end
return str
end
local localeBindings = {}
local function bindLocale(inst, key, opts)
opts = opts or {}
localeBindings[#localeBindings + 1] = {
inst = inst,
key = key,
prop = opts.prop or "Text",
upper = opts.upper == true,
prefix = opts.prefix,
suffix = opts.suffix,
icon = opts.icon,
}
local str = t(key)
if opts.upper then
str = string.upper(str)
end
if opts.icon then
str = " " .. opts.icon .. " " .. str
end
if opts.prefix then
str = opts.prefix .. str
end
if opts.suffix then
str = str .. opts.suffix
end
inst[opts.prop or "Text"] = str
end
local function applyLocaleToUI()
for i = 1, #localeBindings do
local b = localeBindings[i]
if b.inst and b.inst.Parent then
local str = t(b.key)
if b.upper then
str = string.upper(str)
end
if b.icon then
str = " " .. b.icon .. " " .. str
end
if b.prefix then
str = b.prefix .. str
end
if b.suffix then
str = str .. b.suffix
end
b.inst[b.prop] = str
end
end
end
local function setLanguage(code)
currentLanguage = normalizeLanguage(code)
persistLanguage(currentLanguage)
applyLocaleToUI()
return currentLanguage
end
----------------------------------------------------------------
-- Script body
----------------------------------------------------------------
local function getHiddenUiParent()
local parent
pcall(function()
if typeof(gethui) == "function" then
parent = gethui()
end
end)
if not parent then
parent = CoreGui
end
return parent
end
local function protect(gui)
pcall(function()
if syn and syn.protect_gui then
syn.protect_gui(gui)
elseif protect_gui then
protect_gui(gui)
elseif typeof(protectgui) == "function" then
protectgui(gui)
end
end)
end
-- Tear down previous session markers stored weakly via attribute on holder
local uiParent = getHiddenUiParent()
pcall(function()
for _, child in ipairs(uiParent:GetChildren()) do
if child:GetAttribute("_sid") == true then
child:Destroy()
end
end
end)
local holder = Instance.new("Folder")
holder.Name = HOLDER_NAME
holder:SetAttribute("_sid", true)
holder.Parent = uiParent
local tracked = {}
local connections = {}
local alive = true
local DRAWING_OK = typeof(Drawing) == "table" and typeof(Drawing.new) == "function"
local R15_PAIRS = {
{ "Head", "UpperTorso" },
{ "UpperTorso", "LowerTorso" },
{ "UpperTorso", "LeftUpperArm" },
{ "LeftUpperArm", "LeftLowerArm" },
{ "LeftLowerArm", "LeftHand" },
{ "UpperTorso", "RightUpperArm" },
{ "RightUpperArm", "RightLowerArm" },
{ "RightLowerArm", "RightHand" },
{ "LowerTorso", "LeftUpperLeg" },
{ "LeftUpperLeg", "LeftLowerLeg" },
{ "LeftLowerLeg", "LeftFoot" },
{ "LowerTorso", "RightUpperLeg" },
{ "RightUpperLeg", "RightLowerLeg" },
{ "RightLowerLeg", "RightFoot" },
}
local R6_PAIRS = {
{ "Head", "Torso" },
{ "Torso", "Left Arm" },
{ "Torso", "Right Arm" },
{ "Torso", "Left Leg" },
{ "Torso", "Right Leg" },
}
local boundBuf = { x = 0, y = 0, w = 0, h = 0 }
local camCache = nil
local frameId = 0
local playerList = {} -- flat list for staggered updates
local playerListDirty = true
local function rebuildPlayerList()
table.clear(playerList)
for player in pairs(tracked) do
playerList[#playerList + 1] = player
end
playerListDirty = false
end
local function trackConn(conn)
connections[#connections + 1] = conn
return conn
end
local function safeRemove(obj)
if not obj then return end
pcall(function()
obj.Visible = false
obj:Remove()
end)
end
local function isTeammate(player)
local a, b = player.Team, LocalPlayer.Team
return a ~= nil and b ~= nil and a == b
end
local function shouldShow(player)
if not Settings.Enabled or not alive then return false end
if player == LocalPlayer then return false end
if not Settings.ShowTeammates and isTeammate(player) then return false end
return true
end
local function getColor(player)
return isTeammate(player) and Settings.TeamColor or Settings.EnemyColor
end
local function w2s(pos)
local cam = camCache
if not cam then return nil, false end
local v, onScreen = cam:WorldToViewportPoint(pos)
if (not onScreen) or v.Z <= 0 then return nil, false end
return v, true
end
local function healthColor(ratio)
ratio = math.clamp(ratio, 0, 1)
return Color3.fromRGB(
math.floor(255 * (1 - ratio)),
math.floor(255 * ratio),
35
)
end
local function getCharacterBounds(entry)
local cam = camCache
local hrp = entry.hrp
if not cam or not hrp or not hrp.Parent then return nil end
local head = entry.head
local topPos = (head and head.Parent)
and (head.Position + Vector3.new(0, 0.4, 0))
or (hrp.Position + Vector3.new(0, 2.6, 0))
local footPos = hrp.Position - Vector3.new(0, 3.05, 0)
-- Don't require onScreen flag — Z depth alone; keeps size stable at range
local top = cam:WorldToViewportPoint(topPos)
local bottom = cam:WorldToViewportPoint(footPos)
if top.Z <= 0 or bottom.Z <= 0 then return nil end
local height = math.abs(top.Y - bottom.Y)
local dist = (cam.CFrame.Position - hrp.Position).Magnitude
-- Fallback if projection collapses (edge angles)
if height < 6 then
local vh = cam.ViewportSize.Y
height = (5 / math.max(dist, 1)) * (vh * 0.55)
end
-- Hard clamps so boxes never explode from accessories / angles
height = math.clamp(height, 6, math.min(cam.ViewportSize.Y * 0.55, 260))
local width = math.clamp(height * 0.5, 4, math.min(cam.ViewportSize.X * 0.28, 140))
local cx = (top.X + bottom.X) * 0.5
local topY = math.min(top.Y, bottom.Y)
boundBuf.x = cx - width * 0.5
boundBuf.y = topY
boundBuf.w = width
boundBuf.h = height
return boundBuf
end
local function hideDrawings(entry)
if not entry or not entry.drawn then return end
entry.drawn = false
if entry.box then
for i = 1, 4 do entry.box[i].Visible = false end
end
if entry.skeleton then
for i = 1, #entry.skeleton do entry.skeleton[i].Visible = false end
end
if entry.glow then entry.glow.Visible = false end
if entry.healthBg then entry.healthBg.Visible = false end
if entry.healthFg then entry.healthFg.Visible = false end
if entry.nameText then entry.nameText.Visible = false end
end
local function destroyDrawings(entry)
if not entry then return end
if entry.box then
for i = 1, #entry.box do safeRemove(entry.box[i]) end
entry.box = nil
end
if entry.skeleton then
for i = 1, #entry.skeleton do safeRemove(entry.skeleton[i]) end
entry.skeleton = nil
end
safeRemove(entry.glow)
safeRemove(entry.healthBg)
safeRemove(entry.healthFg)
safeRemove(entry.nameText)
entry.glow = nil
entry.healthBg = nil
entry.healthFg = nil
entry.nameText = nil
entry.drawn = false
end
local function removePlayer(player)
local entry = tracked[player]
if not entry then return end
destroyDrawings(entry)
local ec = entry.connections
if ec then
for i = 1, #ec do
pcall(function() ec[i]:Disconnect() end)
end
end
tracked[player] = nil
playerListDirty = true
end
local function newLine(thickness)
local line = Drawing.new("Line")
line.Thickness = thickness
line.Transparency = 1
line.Visible = false
return line
end
local function ensureDrawings(entry)
if not DRAWING_OK then return false end
if Settings.Box and not entry.box then
entry.box = {
newLine(Settings.BoxThickness),
newLine(Settings.BoxThickness),
newLine(Settings.BoxThickness),
newLine(Settings.BoxThickness),
}
end
if Settings.Skeleton and not entry.skeleton then
local n = math.max(1, entry.boneLive or entry.boneCount or #R15_PAIRS)
entry.skeleton = table.create(n)
for i = 1, n do
entry.skeleton[i] = newLine(Settings.SkeletonThickness)
end
end
if Settings.Glow and not entry.glow then
local g = Drawing.new("Square")
g.Filled = true
g.Thickness = 0
g.Transparency = 0.72
g.Visible = false
entry.glow = g
end
if Settings.Health and not entry.healthBg then
local bg = Drawing.new("Square")
bg.Filled = true
bg.Thickness = 0
bg.Transparency = 1
bg.Color = Color3.fromRGB(15, 15, 15)
bg.Visible = false
entry.healthBg = bg
local fg = Drawing.new("Square")
fg.Filled = true
fg.Thickness = 0
fg.Transparency = 1
fg.Visible = false
entry.healthFg = fg
end
if Settings.Name and not entry.nameText then
local text = Drawing.new("Text")
text.Center = true
text.Outline = true
text.Size = 13
text.Font = 2
text.Transparency = 1
text.Visible = false
entry.nameText = text
end
return true
end
local function cacheCharacter(entry, character)
entry.char = character
entry.hum = character:FindFirstChildOfClass("Humanoid")
entry.hrp = character:FindFirstChild("HumanoidRootPart")
entry.head = character:FindFirstChild("Head")
local pairsDef = character:FindFirstChild("UpperTorso") and R15_PAIRS or R6_PAIRS
entry.boneCount = #pairsDef
local bones = table.create(#pairsDef)
local count = 0
for i = 1, #pairsDef do
local a = character:FindFirstChild(pairsDef[i][1])
local b = character:FindFirstChild(pairsDef[i][2])
if a and b and a:IsA("BasePart") and b:IsA("BasePart") then
count += 1
bones[count] = { a, b }
end
end
entry.bones = bones
entry.boneLive = count
if entry.skeleton and #entry.skeleton ~= count and count > 0 then
for i = 1, #entry.skeleton do safeRemove(entry.skeleton[i]) end
entry.skeleton = nil
end
end
local function setBox(entry, bounds, color, visible)
local box = entry.box
if not box then return end
if not visible or not bounds then
for i = 1, 4 do box[i].Visible = false end
return
end
local x, y, w, h = bounds.x, bounds.y, bounds.w, bounds.h
local x2, y2 = x + w, y + h
local l1, l2, l3, l4 = box[1], box[2], box[3], box[4]
l1.From = Vector2.new(x, y); l1.To = Vector2.new(x2, y); l1.Color = color; l1.Visible = true
l2.From = Vector2.new(x2, y); l2.To = Vector2.new(x2, y2); l2.Color = color; l2.Visible = true
l3.From = Vector2.new(x2, y2); l3.To = Vector2.new(x, y2); l3.Color = color; l3.Visible = true
l4.From = Vector2.new(x, y2); l4.To = Vector2.new(x, y); l4.Color = color; l4.Visible = true
end
local function setGlow(entry, bounds, color, visible)
local g = entry.glow
if not g then return end
if not visible or not bounds then
g.Visible = false
return
end
g.Position = Vector2.new(bounds.x, bounds.y)
g.Size = Vector2.new(bounds.w, bounds.h)
g.Color = color
g.Visible = true
end
local function setSkeleton(entry, color, visible)
local lines = entry.skeleton
local bones = entry.bones
if not lines or not bones then return end
if not visible then
for i = 1, #lines do lines[i].Visible = false end
return
end
local n = math.min(#lines, entry.boneLive or 0)
for i = 1, n do
local bone = bones[i]
local line = lines[i]
local v1, ok1 = w2s(bone[1].Position)
local v2, ok2 = w2s(bone[2].Position)
if ok1 and ok2 then
line.From = Vector2.new(v1.X, v1.Y)
line.To = Vector2.new(v2.X, v2.Y)
line.Color = color
line.Visible = true
else
line.Visible = false
end
end
for i = n + 1, #lines do
lines[i].Visible = false
end
end
local function setHealth(entry, hum, bounds, visible)
local bg, fg = entry.healthBg, entry.healthFg
if not bg or not fg then return end
if not visible or not bounds or not hum then
bg.Visible = false
fg.Visible = false
return
end
local ratio = math.clamp(hum.Health / math.max(1, hum.MaxHealth), 0, 1)
local x = bounds.x - 6
local y, h = bounds.y, bounds.h
local filled = h * ratio
bg.Position = Vector2.new(x, y)
bg.Size = Vector2.new(3, h)
bg.Visible = true
fg.Position = Vector2.new(x, y + (h - filled))
fg.Size = Vector2.new(3, filled)
fg.Color = healthColor(ratio)
fg.Visible = true
end
local function setName(entry, player, bounds, head, color, visible)
local text = entry.nameText
if not text then return end
if not visible then
text.Visible = false
return
end
local posX, posY
if bounds then
posX = bounds.x + bounds.w * 0.5
posY = bounds.y - 15
elseif head then
local v, ok = w2s(head.Position + Vector3.new(0, 1.15, 0))
if not ok then
text.Visible = false
return
end
posX, posY = v.X, v.Y
else
text.Visible = false
return
end
if entry.nameStr == nil then
local dn, nm = player.DisplayName, player.Name
entry.nameStr = (dn ~= nm) and (dn .. " @" .. nm) or nm
text.Text = entry.nameStr
end
text.Position = Vector2.new(posX, posY)
text.Color = color
text.Visible = true
end
local function updatePlayer(player, entry)
local character = player.Character
if not character then
hideDrawings(entry)
entry.char = nil
return
end
-- Re-cache when character is new OR parts weren't ready on first cache
if character ~= entry.char
or not entry.hrp or entry.hrp.Parent ~= character
or not entry.hum or entry.hum.Parent ~= character
then
cacheCharacter(entry, character)
end
local hum = entry.hum
if not hum or hum.Health <= 0 then
hideDrawings(entry)
return
end
if not shouldShow(player) then
hideDrawings(entry)
return
end
local hrp = entry.hrp
if not hrp or hrp.Parent ~= character then
hideDrawings(entry)
return
end
local _, onHrp = w2s(hrp.Position)
if not onHrp then
hideDrawings(entry)
return
end
if not ensureDrawings(entry) then return end
entry.drawn = true
local color = getColor(player)
local needBounds = Settings.Box or Settings.Health or Settings.Name or Settings.Glow
local bounds = needBounds and getCharacterBounds(entry) or nil
local onScreen = bounds ~= nil
if Settings.Glow then
setGlow(entry, bounds, color, onScreen)
elseif entry.glow then
entry.glow.Visible = false
end
if Settings.Box then
setBox(entry, bounds, color, onScreen)
elseif entry.box then
for i = 1, 4 do entry.box[i].Visible = false end
end
if Settings.Skeleton then
-- Refresh bones if still incomplete (R15 parts stream in late)
if (entry.boneLive or 0) < 5 then
cacheCharacter(entry, character)
end
setSkeleton(entry, color, true)
elseif entry.skeleton then
for i = 1, #entry.skeleton do entry.skeleton[i].Visible = false end
end
if Settings.Health then
setHealth(entry, hum, bounds, onScreen)
elseif entry.healthBg then
entry.healthBg.Visible = false
if entry.healthFg then entry.healthFg.Visible = false end
end
if Settings.Name then
setName(entry, player, bounds, entry.head, color, true)
elseif entry.nameText then
entry.nameText.Visible = false
end
end
local function hookPlayer(player)
if player == LocalPlayer or tracked[player] then return end
local entry = {
drawn = false,
connections = {},
nameStr = nil,
}
tracked[player] = entry
playerListDirty = true
local function onCharacter(char)
if typeof(char) ~= "Instance" then return end
task.spawn(function()
if tracked[player] ~= entry or not alive then return end
char:WaitForChild("Humanoid", 8)
char:WaitForChild("HumanoidRootPart", 8)
char:WaitForChild("Head", 8)
if tracked[player] ~= entry or not alive then return end
if player.Character ~= char then return end
cacheCharacter(entry, char)
entry.nameStr = nil
playerListDirty = true
-- Parts can appear slightly later (R15)
task.wait(0.35)
if tracked[player] == entry and alive and player.Character == char then
cacheCharacter(entry, char)
end
end)
end
if player.Character then
onCharacter(player.Character)
end
entry.connections[#entry.connections + 1] = player.CharacterAdded:Connect(onCharacter)
entry.connections[#entry.connections + 1] = player.CharacterRemoving:Connect(function()
hideDrawings(entry)
entry.char = nil
entry.hrp = nil
entry.hum = nil
entry.head = nil
entry.bones = nil
end)
pcall(function()
entry.connections[#entry.connections + 1] = player.CharacterAppearanceLoaded:Connect(function(char)
if tracked[player] == entry and alive then
cacheCharacter(entry, char)
entry.nameStr = nil
end
end)
end)
end
for _, player in ipairs(Players:GetPlayers()) do
hookPlayer(player)
end
trackConn(Players.PlayerAdded:Connect(function(player)
hookPlayer(player)
end))
trackConn(Players.PlayerRemoving:Connect(removePlayer))
----------------------------------------------------------------
-- Misc visuals — universal Anti Flash / Anti Smoke
----------------------------------------------------------------
local miscAtm = nil
local miscSkyCC = nil
local smokeConn = nil
local smokeLoop = nil
local smokeWatched = setmetatable({}, { __mode = "k" })
local FogBackup = {
FogStart = Lighting.FogStart,
FogEnd = Lighting.FogEnd,
}
local antiFlashConn = nil
local antiFlashBrightConn = nil
local antiFlashExposureConn = nil
local antiFlashGuiConn = nil
local antiFlashLoop = nil
local antiFlashFxConns = {}
local flashGuiWatched = setmetatable({}, { __mode = "k" })
local flashFxHooked = setmetatable({}, { __mode = "k" })
local SMOKE_WORDS = {
"smoke", "smok", "fog", "mist", "dust", "cloud", "steam",
"haze", "gas", "smokescreen", "smokegrenade", "smoke_nade",
"particle_smoke", "smokeparticle", "vapor", "fume",
}
local FLASH_WORDS = {
"flash", "blind", "whiteout", "stun", "flashbang", "flashed",
"flashgui", "blindness", "screenflash", "whitflash", "impactflash",
}
local function textHasWord(text, words)
if not text or text == "" then return false end
local t = string.lower(text)
for i = 1, #words do
if string.find(t, words[i], 1, true) then
return true
end
end
return false
end
local function pathLooksSmoke(inst)
local cur = inst
for _ = 1, 5 do
if not cur then break end
if textHasWord(cur.Name, SMOKE_WORDS) then return true end
cur = cur.Parent
end
return false
end
local function isSmokeLike(inst)
if not inst or not inst.Parent then return false end
if inst:IsA("Smoke") then return true end
if inst:IsA("ParticleEmitter") then
if pathLooksSmoke(inst) then return true end
local ok, tex = pcall(function()
return tostring(inst.Texture)
end)
if ok and textHasWord(tex, SMOKE_WORDS) then return true end
-- Large soft gray clouds often used as smoke without keywords
local ok2, size = pcall(function()
return inst.Size
end)
if ok2 and typeof(size) == "NumberSequence" then
local keypoints = size.Keypoints
local maxSz = 0
for i = 1, #keypoints do
if keypoints[i].Value > maxSz then maxSz = keypoints[i].Value end
end
if maxSz >= 4 and inst.Rate >= 12 and pathLooksSmoke(inst.Parent) then
return true
end
end
return false
end
if inst:IsA("Fire") then
return pathLooksSmoke(inst)
end
return false
end
local function neutralizeSmoke(inst)
if not inst then return end
pcall(function()
if inst:IsA("Smoke") then
inst.Enabled = false
inst.Opacity = 0
inst.Size = 0
elseif inst:IsA("ParticleEmitter") then
inst.Enabled = false
inst.Rate = 0
pcall(function()
inst.Lifetime = NumberRange.new(0)
end)
elseif inst:IsA("Fire") then
inst.Enabled = false
inst.Size = 0
end
end)
if smokeWatched[inst] then return end
smokeWatched[inst] = true
if inst:IsA("ParticleEmitter") or inst:IsA("Smoke") or inst:IsA("Fire") then
local c1 = inst:GetPropertyChangedSignal("Enabled"):Connect(function()
if Settings.RemoveSmoke and inst.Parent and inst.Enabled then
inst.Enabled = false
end
end)
table.insert(connections, c1)
if inst:IsA("ParticleEmitter") then
local c2 = inst:GetPropertyChangedSignal("Rate"):Connect(function()
if Settings.RemoveSmoke and inst.Parent and inst.Rate > 0 then
inst.Rate = 0
end
end)
table.insert(connections, c2)
end
end
end
local function sweepSmokeIn(root)
if not root then return end
task.spawn(function()
local list = root:GetDescendants()
local i, n = 1, #list
while i <= n and Settings.RemoveSmoke and alive do
local last = math.min(i + 100, n)
for j = i, last do
local inst = list[j]
if isSmokeLike(inst) then
neutralizeSmoke(inst)
end
end
i = last + 1
task.wait()
end
end)
end
local function setRemoveSmoke(on)
if smokeLoop then
pcall(function() task.cancel(smokeLoop) end)
smokeLoop = nil
end
-- disconnect only the DescendantAdded we stored on smokeConn
if smokeConn then
pcall(function() smokeConn:Disconnect() end)
smokeConn = nil
end
if not on then
pcall(function()
Lighting.FogStart = FogBackup.FogStart
Lighting.FogEnd = FogBackup.FogEnd
end)
return
end
FogBackup.FogStart = Lighting.FogStart
FogBackup.FogEnd = Lighting.FogEnd
pcall(function()
Lighting.FogStart = 0
Lighting.FogEnd = 1e6
end)
if miscAtm and miscAtm.Parent then
pcall(function()
miscAtm.Haze = 0
miscAtm.Density = math.min(miscAtm.Density, 0.15)
end)
else
local atm = Lighting:FindFirstChildOfClass("Atmosphere")
if atm then
pcall(function()
atm.Haze = 0
end)
end
end
sweepSmokeIn(workspace)
local cam = workspace.CurrentCamera
if cam then sweepSmokeIn(cam) end
smokeConn = workspace.DescendantAdded:Connect(function(inst)
if not Settings.RemoveSmoke or not alive then return end
if inst:IsA("Smoke") or inst:IsA("ParticleEmitter") or inst:IsA("Fire") then
task.defer(function()
if isSmokeLike(inst) then
neutralizeSmoke(inst)
end
end)
end
end)
smokeLoop = task.spawn(function()
while Settings.RemoveSmoke and alive do
task.wait(1.25)
if not Settings.RemoveSmoke or not alive then break end
sweepSmokeIn(workspace)
local c = workspace.CurrentCamera
if c then sweepSmokeIn(c) end
pcall(function()
if Lighting.FogEnd < 1e5 then
Lighting.FogEnd = 1e6
end
end)
end
end)
end
local function clearAntiFlashHooks()
if antiFlashConn then
pcall(function() antiFlashConn:Disconnect() end)
antiFlashConn = nil
end
if antiFlashBrightConn then
pcall(function() antiFlashBrightConn:Disconnect() end)
antiFlashBrightConn = nil
end
if antiFlashExposureConn then
pcall(function() antiFlashExposureConn:Disconnect() end)
antiFlashExposureConn = nil
end
if antiFlashGuiConn then
pcall(function() antiFlashGuiConn:Disconnect() end)
antiFlashGuiConn = nil
end
if antiFlashLoop then
pcall(function() task.cancel(antiFlashLoop) end)
antiFlashLoop = nil
end
for i = 1, #antiFlashFxConns do
pcall(function() antiFlashFxConns[i]:Disconnect() end)
end
table.clear(antiFlashFxConns)
table.clear(flashFxHooked)
end
local function neutralizeFlashGui(gui)
if not gui or not gui.Parent then return end
pcall(function()
gui.Visible = false
if gui:IsA("GuiObject") then
gui.BackgroundTransparency = 1
end
if gui:IsA("ImageLabel") or gui:IsA("ImageButton") then
gui.ImageTransparency = 1
end
if gui:IsA("Frame") or gui:IsA("ImageLabel") then
-- collapse so layout can't re-cover screen
gui.Size = UDim2.fromOffset(0, 0)
end
end)
if flashGuiWatched[gui] then return end
flashGuiWatched[gui] = true
pcall(function()
local c = gui:GetPropertyChangedSignal("Visible"):Connect(function()
if Settings.AntiFlash and gui.Visible then
gui.Visible = false
end
end)
table.insert(connections, c)
end)
end
local function isFullscreenFlash(gui)
if not gui:IsA("GuiObject") then return false end
if gui.BackgroundTransparency >= 0.55 and not (gui:IsA("ImageLabel") and gui.ImageTransparency < 0.55) then
return false
end
local cam = workspace.CurrentCamera
if not cam then return false end
local vp = cam.ViewportSize
local size = gui.AbsoluteSize
if size.X < vp.X * 0.7 or size.Y < vp.Y * 0.7 then
return false
end
local c = gui.BackgroundColor3
local bright = (c.R + c.G + c.B) / 3
if bright >= 0.75 then return true end
if gui:IsA("ImageLabel") and gui.ImageTransparency < 0.4 then
return true
end
return false
end
local function maybeFlashGui(gui)
if not gui or not gui:IsA("GuiObject") then return end
if textHasWord(gui.Name, FLASH_WORDS) then
neutralizeFlashGui(gui)
return
end
if isFullscreenFlash(gui) then
neutralizeFlashGui(gui)
end
end
local function scanFlashGuisLight()
local pg = LocalPlayer:FindFirstChild("PlayerGui")
if not pg then return end
local cam = workspace.CurrentCamera
local vp = cam and cam.ViewportSize
for _, screen in ipairs(pg:GetChildren()) do
if screen:IsA("ScreenGui") or screen:IsA("BillboardGui") or screen:IsA("LayerCollector") then
if textHasWord(screen.Name, FLASH_WORDS) then
screen.Enabled = false
end
-- only direct children + one nested level (cheap, covers most flash UIs)
for _, child in ipairs(screen:GetChildren()) do
maybeFlashGui(child)
if child:IsA("Frame") or child:IsA("CanvasGroup") then
for _, nested in ipairs(child:GetChildren()) do
if nested:IsA("GuiObject") then
if textHasWord(nested.Name, FLASH_WORDS) or (vp and nested.AbsoluteSize.X >= vp.X * 0.7) then
maybeFlashGui(nested)
end
end
end
end
end
end
end
end
local function hookFlashFx(fx)
if not fx or fx == miscSkyCC or flashFxHooked[fx] then return end
if not (fx:IsA("BloomEffect") or fx:IsA("ColorCorrectionEffect") or fx:IsA("BlurEffect")
or fx:IsA("DepthOfFieldEffect") or fx:IsA("SunRaysEffect")) then
return
end
flashFxHooked[fx] = true
local function watchNumber(prop, maxKeep, setTo)
antiFlashFxConns[#antiFlashFxConns + 1] = fx:GetPropertyChangedSignal(prop):Connect(function()
if not Settings.AntiFlash or fx == miscSkyCC or not fx.Parent then return end
if fx[prop] > maxKeep then
fx[prop] = setTo
end
end)
end
local function watchDisable()
antiFlashFxConns[#antiFlashFxConns + 1] = fx:GetPropertyChangedSignal("Enabled"):Connect(function()
if Settings.AntiFlash and fx.Parent and fx.Enabled then
fx.Enabled = false
end
end)
end
if fx:IsA("BloomEffect") then
fx.Enabled = false
fx.Intensity = 0
fx.Size = 0
watchDisable()
watchNumber("Intensity", 0, 0)
elseif fx:IsA("ColorCorrectionEffect") then
if fx.Brightness > 0 then fx.Brightness = 0 end
if fx.Contrast > 0.35 then fx.Contrast = 0 end
watchNumber("Brightness", 0.02, 0)
watchNumber("Contrast", 0.35, 0)
elseif fx:IsA("BlurEffect") then
if fx.Size > 0 then fx.Size = 0 end
watchNumber("Size", 1, 0)
elseif fx:IsA("DepthOfFieldEffect") then
fx.Enabled = false
watchDisable()
elseif fx:IsA("SunRaysEffect") then
if fx.Intensity > 0.05 then fx.Intensity = 0.05 end
watchNumber("Intensity", 0.05, 0.05)
end
end
local function clampLightingFlash()
pcall(function()
if Lighting.Brightness > 1.2 then
Lighting.Brightness = 1.2
end
if Lighting.ExposureCompensation > 0.2 then
Lighting.ExposureCompensation = 0.2
end
end)
for _, fx in ipairs(Lighting:GetChildren()) do
if fx:IsA("BloomEffect") then
fx.Enabled = false
fx.Intensity = 0
elseif fx:IsA("ColorCorrectionEffect") and fx ~= miscSkyCC then
if fx.Brightness > 0.02 then fx.Brightness = 0 end
if fx.Contrast > 0.35 then fx.Contrast = 0 end
elseif fx:IsA("BlurEffect") and fx.Size > 1 then
fx.Size = 0
elseif fx:IsA("DepthOfFieldEffect") then
fx.Enabled = false
elseif fx:IsA("SunRaysEffect") and fx.Intensity > 0.05 then
fx.Intensity = 0.05
end
hookFlashFx(fx)
end
end
local function setAntiFlash(on)
clearAntiFlashHooks()
if not on then return end
clampLightingFlash()
antiFlashBrightConn = Lighting:GetPropertyChangedSignal("Brightness"):Connect(function()
if Settings.AntiFlash and Lighting.Brightness > 1.2 then
Lighting.Brightness = 1.2
end
end)
pcall(function()
antiFlashExposureConn = Lighting:GetPropertyChangedSignal("ExposureCompensation"):Connect(function()
if Settings.AntiFlash and Lighting.ExposureCompensation > 0.2 then
Lighting.ExposureCompensation = 0.2
end
end)
end)
antiFlashConn = Lighting.ChildAdded:Connect(function(fx)
if Settings.AntiFlash then
hookFlashFx(fx)
end
end)
local pg = LocalPlayer:FindFirstChild("PlayerGui") or LocalPlayer:WaitForChild("PlayerGui", 2)
if pg then
antiFlashGuiConn = pg.DescendantAdded:Connect(function(gui)
if not Settings.AntiFlash or not alive then return end
if not gui:IsA("Frame") and not gui:IsA("ImageLabel") and not gui:IsA("CanvasGroup") then
return
end
-- Name hit is instant; size check deferred (avoids layout thrash)
if textHasWord(gui.Name, FLASH_WORDS) then
neutralizeFlashGui(gui)
else
task.defer(function()
if Settings.AntiFlash and isFullscreenFlash(gui) then
neutralizeFlashGui(gui)
end
end)
end
end)
end
antiFlashLoop = task.spawn(function()
while Settings.AntiFlash and alive do
clampLightingFlash()
scanFlashGuisLight()
task.wait(0.35)
end
end)
end
local function applyAntiFlash()
if Settings.AntiFlash then
clampLightingFlash()
scanFlashGuisLight()
end
end
local function applyEnvColor()
if Settings.CustomEnv then
local c = Settings.EnvColor
Lighting.Ambient = c
Lighting.OutdoorAmbient = c
Lighting.ColorShift_Top = c
Lighting.ColorShift_Bottom = c
Lighting.FogColor = c
else
Lighting.Ambient = LightingBackup.Ambient
Lighting.OutdoorAmbient = LightingBackup.OutdoorAmbient
Lighting.ColorShift_Top = LightingBackup.ColorShift_Top
Lighting.ColorShift_Bottom = LightingBackup.ColorShift_Bottom
Lighting.FogColor = LightingBackup.FogColor
end
end
local function applySkyColor()
if Settings.CustomSky then
if not miscAtm or not miscAtm.Parent then
miscAtm = Lighting:FindFirstChildOfClass("Atmosphere")
if not miscAtm then
miscAtm = Instance.new("Atmosphere")
miscAtm.Name = rndName("a")
miscAtm.Parent = Lighting
end
end
local c = Settings.SkyColor
miscAtm.Color = c
miscAtm.Decay = Color3.new(
math.clamp(c.R * 0.55, 0, 1),
math.clamp(c.G * 0.55, 0, 1),
math.clamp(c.B * 0.55, 0, 1)
)
miscAtm.Density = 0.35
miscAtm.Haze = 1.4
miscAtm.Glare = 0.1
if not miscSkyCC or not miscSkyCC.Parent then
miscSkyCC = Instance.new("ColorCorrectionEffect")
miscSkyCC.Name = rndName("cc")
miscSkyCC.Parent = Lighting
end
miscSkyCC.Enabled = true
miscSkyCC.TintColor = Color3.new(
0.55 + c.R * 0.45,
0.55 + c.G * 0.45,
0.55 + c.B * 0.45
)
miscSkyCC.Brightness = 0
miscSkyCC.Contrast = 0.05
miscSkyCC.Saturation = 0.1
else
if miscSkyCC then
pcall(function() miscSkyCC:Destroy() end)
miscSkyCC = nil
end
if miscAtm and miscAtm.Parent then
pcall(function()
miscAtm.Density = 0
miscAtm.Haze = 0
end)
end
end
end
pcall(function()
RunService:UnbindFromRenderStep(BIND_NAME)
end)
-- Heartbeat is cheaper than Camera-priority RenderStep for overlays
trackConn(RunService.Heartbeat:Connect(function()
if not alive then return end
frameId += 1
camCache = workspace.CurrentCamera
if not camCache then return end
if not Settings.Enabled then
if frameId % 10 == 0 then
for _, entry in pairs(tracked) do
hideDrawings(entry)
end
end
return
end
if playerListDirty then
rebuildPlayerList()
end
-- Catch late joiners if PlayerAdded was missed
if frameId % 90 == 0 then
for _, player in ipairs(Players:GetPlayers()) do
if player ~= LocalPlayer and not tracked[player] then
hookPlayer(player)
end
end
if playerListDirty then
rebuildPlayerList()
end
end
local n = #playerList
if n == 0 then return end
-- Stagger: process ~half the roster each frame when crowded
local step = (n > 12) and 2 or 1
local start = ((frameId - 1) % step) + 1
for i = start, n, step do
local player = playerList[i]
local entry = tracked[player]
if entry then
updatePlayer(player, entry)
end
end
end))
----------------------------------------------------------------
-- Menu (DEDE HUB)
----------------------------------------------------------------
local Theme = {
Bg = Color3.fromRGB(18, 18, 20),
Sidebar = Color3.fromRGB(22, 22, 24),
Card = Color3.fromRGB(28, 28, 32),
NavIdle = Color3.fromRGB(22, 22, 24),
NavActive = Color3.fromRGB(40, 40, 44),
Text = Color3.fromRGB(245, 245, 247),
Muted = Color3.fromRGB(150, 150, 160),
Section = Color3.fromRGB(120, 120, 130),
Accent = Settings.MenuAccent,
ToggleOff = Color3.fromRGB(55, 55, 62),
Stroke = Color3.fromRGB(45, 45, 52),
}
local themeRefreshers = {}
local gui = Instance.new("ScreenGui")
gui.Name = GUI_NAME
gui.ResetOnSpawn = false
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.IgnoreGuiInset = true
gui.DisplayOrder = math.random(40, 90)
gui:SetAttribute("_sid", true)
protect(gui)
gui.Parent = uiParent
local window = Instance.new("Frame")
window.Name = rndName("w")
window.AnchorPoint = Vector2.new(0.5, 0.5)
window.Position = UDim2.fromScale(0.5, 0.5)
window.Size = UDim2.fromOffset(720, 420)
window.BackgroundColor3 = Theme.Bg
window.BackgroundTransparency = 0.06
window.BorderSizePixel = 0
window.Parent = gui
local windowCorner = Instance.new("UICorner")
windowCorner.CornerRadius = UDim.new(0, 14)
windowCorner.Parent = window
local windowStroke = Instance.new("UIStroke")
windowStroke.Color = Theme.Stroke
windowStroke.Thickness = 1
windowStroke.Transparency = 0.25
windowStroke.Parent = window
local accentBar = Instance.new("Frame")
accentBar.Name = rndName("ab")
accentBar.BorderSizePixel = 0
accentBar.BackgroundColor3 = Theme.Accent
accentBar.Size = UDim2.new(1, 0, 0, 3)
accentBar.Position = UDim2.fromOffset(0, 0)
accentBar.ZIndex = 25
accentBar.Parent = window
local accentBarCorner = Instance.new("UICorner")
accentBarCorner.CornerRadius = UDim.new(0, 14)
accentBarCorner.Parent = accentBar
-- Soft shadow
local shadow = Instance.new("ImageLabel")
shadow.Name = rndName("sh")
shadow.BackgroundTransparency = 1
shadow.Image = "rbxassetid://5028857084"
shadow.ImageColor3 = Color3.new(0, 0, 0)
shadow.ImageTransparency = 0.45
shadow.ScaleType = Enum.ScaleType.Slice
shadow.SliceCenter = Rect.new(24, 24, 276, 276)
shadow.Size = UDim2.new(1, 36, 1, 36)
shadow.Position = UDim2.fromOffset(-18, -14)
shadow.ZIndex = 0
shadow.Parent = window
-- Drag handle (top bar across window)
local dragBar = Instance.new("TextButton")
dragBar.Name = rndName("dg")
dragBar.BackgroundTransparency = 1
dragBar.Size = UDim2.new(1, 0, 0, 36)
dragBar.Position = UDim2.fromOffset(0, 0)
dragBar.Text = ""
dragBar.ZIndex = 20
dragBar.Parent = window
do
local dragging = false
local dragStart, startPos
dragBar.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = window.Position
end
end)
trackConn(UserInputService.InputChanged:Connect(function(input)
if not dragging then return end
if input.UserInputType == Enum.UserInputType.MouseMovement
or input.UserInputType == Enum.UserInputType.Touch then
local delta = input.Position - dragStart
window.Position = UDim2.new(
startPos.X.Scale, startPos.X.Offset + delta.X,
startPos.Y.Scale, startPos.Y.Offset + delta.Y
)
end
end))
trackConn(UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end))
end
-- Sidebar
local sidebar = Instance.new("Frame")
sidebar.Name = rndName("sb")
sidebar.Size = UDim2.new(0, 168, 1, 0)
sidebar.BackgroundColor3 = Theme.Sidebar
sidebar.BackgroundTransparency = 0.15
sidebar.BorderSizePixel = 0
sidebar.ZIndex = 2
sidebar.Parent = window
local sidebarCorner = Instance.new("UICorner")
sidebarCorner.CornerRadius = UDim.new(0, 14)
sidebarCorner.Parent = sidebar
local sidebarClip = Instance.new("Frame")
sidebarClip.BackgroundColor3 = Theme.Sidebar
sidebarClip.BackgroundTransparency = 0.15
sidebarClip.BorderSizePixel = 0
sidebarClip.Position = UDim2.new(1, -14, 0, 0)
sidebarClip.Size = UDim2.new(0, 14, 1, 0)
sidebarClip.ZIndex = 2
sidebarClip.Parent = sidebar
local brand = Instance.new("TextLabel")
brand.BackgroundTransparency = 1
brand.Position = UDim2.fromOffset(18, 18)
brand.Size = UDim2.new(1, -28, 0, 24)
brand.Font = Enum.Font.GothamBold
brand.TextSize = 16
brand.TextXAlignment = Enum.TextXAlignment.Left
brand.TextColor3 = Theme.Text
brand.ZIndex = 3
brand.Parent = sidebar
bindLocale(brand, "hub_name")
local navList = Instance.new("Frame")
navList.BackgroundTransparency = 1
navList.Position = UDim2.fromOffset(10, 56)
navList.Size = UDim2.new(1, -20, 1, -110)
navList.ZIndex = 3
navList.Parent = sidebar
local navLayout = Instance.new("UIListLayout")
navLayout.Padding = UDim.new(0, 4)
navLayout.SortOrder = Enum.SortOrder.LayoutOrder
navLayout.Parent = navList
local pages = {}
local navButtons = {}
local currentPage = "Vision"
local function setPage(name)
currentPage = name
for id, page in pairs(pages) do
page.Visible = (id == name)
end
for id, btn in pairs(navButtons) do
local active = id == name
btn.BackgroundColor3 = active and Theme.NavActive or Theme.NavIdle
btn.BackgroundTransparency = active and 0 or 1
btn.TextColor3 = active and Theme.Text or Theme.Muted
end
end
local function makeNav(id, labelKey, order, icon)
local btn = Instance.new("TextButton")
btn.Name = rndName("n")
btn.LayoutOrder = order
btn.Size = UDim2.new(1, 0, 0, 34)
btn.BackgroundColor3 = Theme.NavIdle
btn.BackgroundTransparency = 1
btn.AutoButtonColor = false
btn.Font = Enum.Font.Gotham
btn.TextSize = 13
btn.TextXAlignment = Enum.TextXAlignment.Left
btn.TextColor3 = Theme.Muted
btn.ZIndex = 4
btn.Parent = navList
bindLocale(btn, labelKey, { icon = icon })
local c = Instance.new("UICorner")
c.CornerRadius = UDim.new(0, 8)
c.Parent = btn
btn.MouseButton1Click:Connect(function()
setPage(id)
end)
navButtons[id] = btn
return btn
end
makeNav("Vision", "nav_vision", 1, "◇")
makeNav("Entities", "nav_entities", 2, "◎")
makeNav("Misc", "nav_misc", 3, "✦")
local settingsNav = Instance.new("TextButton")
settingsNav.Name = rndName("n")
settingsNav.AutoButtonColor = false
settingsNav.BackgroundColor3 = Theme.NavIdle
settingsNav.BackgroundTransparency = 1
settingsNav.Position = UDim2.new(0, 10, 1, -42)
settingsNav.Size = UDim2.new(1, -20, 0, 34)
settingsNav.Font = Enum.Font.Gotham
settingsNav.TextSize = 13
settingsNav.TextXAlignment = Enum.TextXAlignment.Left
settingsNav.TextColor3 = Theme.Muted
settingsNav.ZIndex = 4
settingsNav.Parent = sidebar
bindLocale(settingsNav, "nav_settings", { icon = "⚙" })
local settingsNavCorner = Instance.new("UICorner")
settingsNavCorner.CornerRadius = UDim.new(0, 8)
settingsNavCorner.Parent = settingsNav
settingsNav.MouseButton1Click:Connect(function()
setPage("Settings")
end)
navButtons["Settings"] = settingsNav
-- Content
local content = Instance.new("Frame")
content.Name = rndName("ct")
content.BackgroundTransparency = 1
content.Position = UDim2.fromOffset(168, 36)
content.Size = UDim2.new(1, -180, 1, -48)
content.ZIndex = 2
content.Parent = window
local function makePage(id)
local page = Instance.new("ScrollingFrame")
page.Name = rndName("p")
page.BackgroundTransparency = 1
page.BorderSizePixel = 0
page.Size = UDim2.fromScale(1, 1)
page.CanvasSize = UDim2.fromOffset(0, 0)
page.AutomaticCanvasSize = Enum.AutomaticSize.Y
page.ScrollBarThickness = 3
page.ScrollBarImageColor3 = Theme.Muted
page.Visible = false
page.ZIndex = 3
page.Parent = content
local pad = Instance.new("UIPadding")
pad.PaddingLeft = UDim.new(0, 8)
pad.PaddingRight = UDim.new(0, 8)
pad.PaddingTop = UDim.new(0, 4)
pad.PaddingBottom = UDim.new(0, 12)
pad.Parent = page
local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 18)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = page
pages[id] = page
return page
end
local function sectionHeader(parent, titleKey, subKey, order)
local wrap = Instance.new("Frame")
wrap.BackgroundTransparency = 1
wrap.Size = UDim2.new(1, 0, 0, subKey and 36 or 20)
wrap.LayoutOrder = order
wrap.ZIndex = 4
wrap.Parent = parent
local h = Instance.new("TextLabel")
h.BackgroundTransparency = 1
h.Size = UDim2.new(1, 0, 0, 16)
h.Font = Enum.Font.GothamBold
h.TextSize = 11
h.TextXAlignment = Enum.TextXAlignment.Left
h.TextColor3 = Theme.Section
h.ZIndex = 5
h.Parent = wrap
bindLocale(h, titleKey, { upper = true })
if subKey then
local s = Instance.new("TextLabel")
s.BackgroundTransparency = 1
s.Position = UDim2.fromOffset(0, 16)
s.Size = UDim2.new(1, 0, 0, 16)
s.Font = Enum.Font.Gotham
s.TextSize = 11
s.TextXAlignment = Enum.TextXAlignment.Left
s.TextColor3 = Theme.Muted
s.ZIndex = 5
s.Parent = wrap
bindLocale(s, subKey)
end
return wrap
end
local function makeToggleRow(parent, labelKey, key, descKey, order, onChange)
local row = Instance.new("TextButton")
row.Name = rndName("tg")
row.AutoButtonColor = false
row.BackgroundTransparency = 1
row.Size = UDim2.new(1, 0, 0, descKey and 44 or 32)
row.LayoutOrder = order
row.Text = ""
row.ZIndex = 4
row.Parent = parent
local nameLbl = Instance.new("TextLabel")
nameLbl.BackgroundTransparency = 1
nameLbl.Size = UDim2.new(1, -64, 0, 18)
nameLbl.Position = UDim2.fromOffset(0, descKey and 2 or 7)
nameLbl.Font = Enum.Font.Gotham
nameLbl.TextSize = 13
nameLbl.TextXAlignment = Enum.TextXAlignment.Left
nameLbl.TextColor3 = Theme.Text
nameLbl.ZIndex = 5
nameLbl.Parent = row
bindLocale(nameLbl, labelKey)
if descKey then
local d = Instance.new("TextLabel")
d.BackgroundTransparency = 1
d.Position = UDim2.fromOffset(0, 22)
d.Size = UDim2.new(1, -64, 0, 16)
d.Font = Enum.Font.Gotham
d.TextSize = 11
d.TextXAlignment = Enum.TextXAlignment.Left
d.TextColor3 = Theme.Muted
d.ZIndex = 5
d.Parent = row
bindLocale(d, descKey)
end
local track = Instance.new("Frame")
track.AnchorPoint = Vector2.new(1, 0.5)
track.Position = UDim2.new(1, -2, 0.5, 0)
track.Size = UDim2.fromOffset(42, 24)
track.BackgroundColor3 = Theme.ToggleOff
track.BorderSizePixel = 0
track.ZIndex = 5
track.Parent = row
local trackCorner = Instance.new("UICorner")
trackCorner.CornerRadius = UDim.new(1, 0)
trackCorner.Parent = track
local knob = Instance.new("Frame")
knob.Size = UDim2.fromOffset(18, 18)
knob.Position = UDim2.fromOffset(3, 3)
knob.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
knob.BorderSizePixel = 0
knob.ZIndex = 6
knob.Parent = track
local knobCorner = Instance.new("UICorner")
knobCorner.CornerRadius = UDim.new(1, 0)
knobCorner.Parent = knob
local function refresh()
local on = Settings[key] == true
track.BackgroundColor3 = on and Theme.Accent or Theme.ToggleOff
knob.Position = on and UDim2.fromOffset(21, 3) or UDim2.fromOffset(3, 3)
end
row.MouseButton1Click:Connect(function()
Settings[key] = not Settings[key]
refresh()
if onChange then
onChange(Settings[key])
end
end)
themeRefreshers[#themeRefreshers + 1] = refresh
refresh()
return row
end
local function applyMenuTheme(accent)
Settings.MenuAccent = accent
Theme.Accent = accent
Theme.Stroke = Color3.new(
math.clamp(accent.R * 0.25 + 0.14, 0, 1),
math.clamp(accent.G * 0.25 + 0.14, 0, 1),
math.clamp(accent.B * 0.25 + 0.16, 0, 1)
)
Theme.NavActive = Color3.new(
math.clamp(accent.R * 0.18 + 0.12, 0, 1),
math.clamp(accent.G * 0.18 + 0.12, 0, 1),
math.clamp(accent.B * 0.18 + 0.14, 0, 1)
)
if accentBar then
accentBar.BackgroundColor3 = accent
end
if windowStroke then
windowStroke.Color = Theme.Stroke
end
-- Refresh active nav highlight + toggles
if currentPage and setPage then
setPage(currentPage)
end
for i = 1, #themeRefreshers do
pcall(themeRefreshers[i])
end
end
local function makeColorRow(parent, titleKey, getColor, setColor, order)
local wrap = Instance.new("Frame")
wrap.BackgroundTransparency = 1
wrap.Size = UDim2.new(1, 0, 0, 56)
wrap.LayoutOrder = order
wrap.ZIndex = 4
wrap.Parent = parent
local label = Instance.new("TextLabel")
label.BackgroundTransparency = 1
label.Size = UDim2.new(1, -40, 0, 18)
label.Font = Enum.Font.Gotham
label.TextSize = 13
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextColor3 = Theme.Text
label.ZIndex = 5
label.Parent = wrap
bindLocale(label, titleKey)
local preview = Instance.new("Frame")
preview.AnchorPoint = Vector2.new(1, 0)
preview.Position = UDim2.new(1, 0, 0, 0)
preview.Size = UDim2.fromOffset(22, 22)
preview.BackgroundColor3 = getColor()
preview.BorderSizePixel = 0
preview.ZIndex = 5
preview.Parent = wrap
local pc = Instance.new("UICorner")
pc.CornerRadius = UDim.new(0, 6)
pc.Parent = preview
local row = Instance.new("Frame")
row.BackgroundTransparency = 1
row.Position = UDim2.fromOffset(0, 28)
row.Size = UDim2.new(1, 0, 0, 24)
row.ZIndex = 5
row.Parent = wrap
local list = Instance.new("UIListLayout")
list.FillDirection = Enum.FillDirection.Horizontal
list.Padding = UDim.new(0, 6)
list.Parent = row
for i = 1, #COLOR_PRESETS do
local preset = COLOR_PRESETS[i]
local sw = Instance.new("TextButton")
sw.AutoButtonColor = false
sw.Text = ""
sw.Size = UDim2.fromOffset(22, 22)
sw.BackgroundColor3 = preset.color
sw.BorderSizePixel = 0
sw.ZIndex = 6
sw.Parent = row
local sc = Instance.new("UICorner")
sc.CornerRadius = UDim.new(0, 6)
sc.Parent = sw
local ss = Instance.new("UIStroke")
ss.Thickness = 1
ss.Color = Color3.fromRGB(255, 255, 255)
ss.Transparency = 0.7
ss.Parent = sw
sw.MouseButton1Click:Connect(function()
setColor(preset.color)
preview.BackgroundColor3 = preset.color
end)
end
return wrap
end
local function twoColumn(parent, order)
local wrap = Instance.new("Frame")
wrap.BackgroundTransparency = 1
wrap.Size = UDim2.new(1, 0, 0, 0)
wrap.AutomaticSize = Enum.AutomaticSize.Y
wrap.LayoutOrder = order
wrap.ZIndex = 4
wrap.Parent = parent
local left = Instance.new("Frame")
left.BackgroundTransparency = 1
left.Size = UDim2.new(0.5, -10, 0, 0)
left.AutomaticSize = Enum.AutomaticSize.Y
left.ZIndex = 5
left.Parent = wrap
local leftLayout = Instance.new("UIListLayout")
leftLayout.Padding = UDim.new(0, 6)
leftLayout.Parent = left
local right = Instance.new("Frame")
right.BackgroundTransparency = 1
right.Position = UDim2.new(0.5, 10, 0, 0)
right.Size = UDim2.new(0.5, -10, 0, 0)
right.AutomaticSize = Enum.AutomaticSize.Y
right.ZIndex = 5
right.Parent = wrap
local rightLayout = Instance.new("UIListLayout")
rightLayout.Padding = UDim.new(0, 6)
rightLayout.Parent = right
local function syncHeight()
wrap.Size = UDim2.new(1, 0, 0, math.max(left.AbsoluteSize.Y, right.AbsoluteSize.Y))
end
left:GetPropertyChangedSignal("AbsoluteSize"):Connect(syncHeight)
right:GetPropertyChangedSignal("AbsoluteSize"):Connect(syncHeight)
return left, right
end
-- Vision page
local visionPage = makePage("Vision")
sectionHeader(visionPage, "sec_esp", "sec_esp_sub", 1)
local vLeft, vRight = twoColumn(visionPage, 2)
makeToggleRow(vLeft, "tog_skeleton", "Skeleton", "tog_skeleton_desc", 1)
makeToggleRow(vLeft, "tog_box", "Box", "tog_box_desc", 2)
makeToggleRow(vLeft, "tog_health", "Health", "tog_health_desc", 3)
makeToggleRow(vRight, "tog_name", "Name", "tog_name_desc", 1)
makeToggleRow(vRight, "tog_glow", "Glow", "tog_glow_desc", 2)
sectionHeader(visionPage, "sec_filters", nil, 3)
local fLeft = Instance.new("Frame")
fLeft.BackgroundTransparency = 1
fLeft.Size = UDim2.new(0.5, -10, 0, 0)
fLeft.AutomaticSize = Enum.AutomaticSize.Y
fLeft.LayoutOrder = 4
fLeft.Parent = visionPage
local fLayout = Instance.new("UIListLayout")
fLayout.Padding = UDim.new(0, 6)
fLayout.Parent = fLeft
makeToggleRow(fLeft, "tog_teammates", "ShowTeammates", "tog_teammates_desc", 1)
makeToggleRow(fLeft, "tog_master", "Enabled", "tog_master_desc", 2)
-- Entities page
local entitiesPage = makePage("Entities")
sectionHeader(entitiesPage, "sec_players", "sec_players_sub", 1)
local eLeft, eRight = twoColumn(entitiesPage, 2)
makeToggleRow(eLeft, "tog_teammates", "ShowTeammates", "tog_teammates_ent_desc", 1)
makeToggleRow(eRight, "tog_master", "Enabled", "tog_master_ent_desc", 1)
-- Misc page
local miscPage = makePage("Misc")
sectionHeader(miscPage, "sec_protection", "sec_protection_sub", 1)
local mLeft, mRight = twoColumn(miscPage, 2)
makeToggleRow(mLeft, "tog_antiflash", "AntiFlash", "tog_antiflash_desc", 1, function(on)
setAntiFlash(on)
end)
makeToggleRow(mRight, "tog_smoke", "RemoveSmoke", "tog_smoke_desc", 1, function(on)
setRemoveSmoke(on)
end)
sectionHeader(miscPage, "sec_world", "sec_world_sub", 3)
local wLeft, wRight = twoColumn(miscPage, 4)
makeToggleRow(wLeft, "tog_env", "CustomEnv", "tog_env_desc", 1, function()
applyEnvColor()
end)
makeToggleRow(wRight, "tog_sky", "CustomSky", "tog_sky_desc", 1, function()
applySkyColor()
end)
makeColorRow(miscPage, "color_env", function()
return Settings.EnvColor
end, function(c)
Settings.EnvColor = c
if Settings.CustomEnv then applyEnvColor() end
end, 5)
makeColorRow(miscPage, "color_sky", function()
return Settings.SkyColor
end, function(c)
Settings.SkyColor = c
if Settings.CustomSky then applySkyColor() end
end, 6)
sectionHeader(miscPage, "sec_esp_colors", "sec_esp_colors_sub", 7)
makeColorRow(miscPage, "color_enemy", function()
return Settings.EnemyColor
end, function(c)
Settings.EnemyColor = c
end, 8)
makeColorRow(miscPage, "color_team", function()
return Settings.TeamColor
end, function(c)
Settings.TeamColor = c
end, 9)
-- Settings page
local settingsPage = makePage("Settings")
sectionHeader(settingsPage, "sec_interface", "sec_interface_sub", 1)
local tip = Instance.new("TextLabel")
tip.BackgroundTransparency = 1
tip.Size = UDim2.new(1, 0, 0, 60)
tip.LayoutOrder = 2
tip.Font = Enum.Font.Gotham
tip.TextSize = 13
tip.TextXAlignment = Enum.TextXAlignment.Left
tip.TextYAlignment = Enum.TextYAlignment.Top
tip.TextColor3 = Theme.Muted
tip.TextWrapped = true
tip.ZIndex = 5
tip.Parent = settingsPage
bindLocale(tip, "tip_controls")
sectionHeader(settingsPage, "sec_appearance", "sec_appearance_sub", 3)
makeColorRow(settingsPage, "color_menu", function()
return Settings.MenuAccent
end, function(c)
applyMenuTheme(c)
end, 4)
sectionHeader(settingsPage, "sec_language", "sec_language_sub", 5)
local langRow = Instance.new("Frame")
langRow.BackgroundTransparency = 1
langRow.Size = UDim2.new(1, 0, 0, 34)
langRow.LayoutOrder = 6
langRow.ZIndex = 4
langRow.Parent = settingsPage
local langLayout = Instance.new("UIListLayout")
langLayout.FillDirection = Enum.FillDirection.Horizontal
langLayout.Padding = UDim.new(0, 8)
langLayout.Parent = langRow
local langButtons = {}
local function refreshLangButtons()
for code, btn in pairs(langButtons) do
local on = code == currentLanguage
btn.BackgroundColor3 = on and Theme.Accent or Color3.fromRGB(32, 32, 38)
btn.TextColor3 = on and Color3.fromRGB(255, 255, 255) or Theme.Muted
end
end
for i = 1, #LANGUAGE_OPTIONS do
local opt = LANGUAGE_OPTIONS[i]
local btn = Instance.new("TextButton")
btn.AutoButtonColor = false
btn.Size = UDim2.fromOffset(110, 32)
btn.BackgroundColor3 = Color3.fromRGB(32, 32, 38)
btn.BorderSizePixel = 0
btn.Font = Enum.Font.Gotham
btn.TextSize = 12
btn.Text = opt.label
btn.TextColor3 = Theme.Muted
btn.ZIndex = 5
btn.Parent = langRow
local bc = Instance.new("UICorner")
bc.CornerRadius = UDim.new(0, 8)
bc.Parent = btn
langButtons[opt.code] = btn
btn.MouseButton1Click:Connect(function()
setLanguage(opt.code)
refreshLangButtons()
end)
end
refreshLangButtons()
themeRefreshers[#themeRefreshers + 1] = refreshLangButtons
sectionHeader(settingsPage, "sec_session", "sec_session_sub", 7)
local destroying = false
local function destroyAll()
if destroying then return end
destroying = true
alive = false
pcall(function() RunService:UnbindFromRenderStep(BIND_NAME) end)
Settings.Enabled = false
Settings.CustomEnv = false
Settings.CustomSky = false
Settings.RemoveSmoke = false
Settings.AntiFlash = false
pcall(applyEnvColor)
pcall(applySkyColor)
pcall(function() setRemoveSmoke(false) end)
pcall(function() setAntiFlash(false) end)
if miscAtm then pcall(function() miscAtm:Destroy() end) miscAtm = nil end
if miscSkyCC then pcall(function() miscSkyCC:Destroy() end) miscSkyCC = nil end
for player in pairs(tracked) do
pcall(removePlayer, player)
end
table.clear(tracked)
for i = 1, #connections do
pcall(function() connections[i]:Disconnect() end)
end
table.clear(connections)
pcall(function()
if gui then gui:Destroy() end
end)
pcall(function()
if holder then holder:Destroy() end
end)
end
local destroyBtn = Instance.new("TextButton")
destroyBtn.Name = rndName("x")
destroyBtn.LayoutOrder = 8
destroyBtn.Size = UDim2.new(1, 0, 0, 44)
destroyBtn.BackgroundColor3 = Color3.fromRGB(160, 45, 55)
destroyBtn.AutoButtonColor = false
destroyBtn.Font = Enum.Font.GothamBold
destroyBtn.TextSize = 14
destroyBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
destroyBtn.ZIndex = 5
destroyBtn.Parent = settingsPage
bindLocale(destroyBtn, "btn_destroy")
local destroyCorner = Instance.new("UICorner")
destroyCorner.CornerRadius = UDim.new(0, 10)
destroyCorner.Parent = destroyBtn
local destroyStroke = Instance.new("UIStroke")
destroyStroke.Color = Color3.fromRGB(220, 80, 90)
destroyStroke.Thickness = 1
destroyStroke.Transparency = 0.4
destroyStroke.Parent = destroyBtn
destroyBtn.MouseEnter:Connect(function()
if destroying then return end
destroyBtn.BackgroundColor3 = Color3.fromRGB(190, 55, 65)
end)
destroyBtn.MouseLeave:Connect(function()
if destroying then return end
destroyBtn.BackgroundColor3 = Color3.fromRGB(160, 45, 55)
end)
destroyBtn.MouseButton1Click:Connect(function()
destroyBtn.Text = t("btn_closing")
destroyBtn.BackgroundColor3 = Color3.fromRGB(90, 30, 35)
task.defer(destroyAll)
end)
setPage("Vision")
local menuVisible = true
trackConn(UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed or not alive then return end
if input.KeyCode == Enum.KeyCode.Delete then
menuVisible = not menuVisible
window.Visible = menuVisible
end
end))
trackConn(holder.Destroying:Connect(function()
destroyAll()
end))[+] Draggable menu
[+] DEL to show/hide menu
[+] Language support: English / Turkish / Russian / Vietnamese
[+] Custom menu accent color
[+] Destroy (fully unload script)
[+] Master ESP toggle
[+] Bone / Skeleton ESP
[+] Box ESP (distance-scaled)
[+] Health bar
[+] Name tag
[+] Glow
[+] Show/hide teammates
[+] Enemy / teammate ESP colors
[+] Auto ESP
[+] Anti Flash
[+] Remove Smoke
[+] Environment color
[+] Sky / atmosphere color
[+] Performance-optimized ESP
[+] Stealth-oriented design
No comments yet. Be the first to comment!
1local function ref(obj)
2 local ok, cloned = pcall(function()
3 return cloneref(obj)
4 end)
5 return (ok and cloned) or obj
6end
7
8local Players = ref(game:GetService("Players"))
9local RunService = ref(game:GetService("RunService"))
10local UserInputService = ref(game:GetService("UserInputService"))
11local CoreGui = ref(game:GetService("CoreGui"))
12local HttpService = ref(game:GetService("HttpService"))
13local Lighting = ref(game:GetService("Lighting"))
14local TweenService = ref(game:GetService("TweenService"))
15
16local LocalPlayer = Players.LocalPlayer
17
18local function rndName(prefix)
19 local suffix = HttpService:GenerateGUID(false):gsub("-", ""):sub(1, 12)
20 return (prefix or "") .. suffix
21end
22
23local SESSION = rndName("s")
24local BIND_NAME = rndName("rb")
25local GUI_NAME = rndName("ui")
26local HOLDER_NAME = rndName("hd")
27
28local COLOR_PRESETS = {
29 { name = "Red", color = Color3.fromRGB(255, 70, 70) },
30 { name = "Orange", color = Color3.fromRGB(255, 140, 40) },
31 { name = "Yellow", color = Color3.fromRGB(255, 220, 60) },
32 { name = "Green", color = Color3.fromRGB(60, 220, 100) },
33 { name = "Cyan", color = Color3.fromRGB(60, 220, 230) },
34 { name = "Blue", color = Color3.fromRGB(70, 170, 255) },
35 { name = "Purple", color = Color3.fromRGB(170, 90, 255) },
36 { name = "Pink", color = Color3.fromRGB(255, 90, 180) },
37 { name = "White", color = Color3.fromRGB(240, 240, 245) },
38 { name = "Black", color = Color3.fromRGB(20, 20, 24) },
39}
40
41local Settings = {
42 Enabled = true,
43 ShowTeammates = false,
44 Skeleton = true,
45 Box = true,
46 Health = true,
47 Name = true,
48 Glow = true,
49 EnemyColor = Color3.fromRGB(255, 70, 70),
50 TeamColor = Color3.fromRGB(70, 170, 255),
51 SkeletonThickness = 1.4,
52 BoxThickness = 1.4,
53 -- Misc
54 AntiFlash = false,
55 RemoveSmoke = false,
56 CustomEnv = false,
57 CustomSky = false,
58 EnvColor = Color3.fromRGB(128, 128, 128),
59 SkyColor = Color3.fromRGB(80, 140, 220),
60 MenuAccent = Color3.fromRGB(47, 128, 255),
61}
62
63-- Original lighting snapshot for restore
64local LightingBackup = {
65 Ambient = Lighting.Ambient,
66 OutdoorAmbient = Lighting.OutdoorAmbient,
67 ColorShift_Top = Lighting.ColorShift_Top,
68 ColorShift_Bottom = Lighting.ColorShift_Bottom,
69 Brightness = Lighting.Brightness,
70 FogColor = Lighting.FogColor,
71}
72
73
74----------------------------------------------------------------
75-- Languages (en default, tr, ru, vi)
76----------------------------------------------------------------
77
78local LANGUAGE_OPTIONS = {
79 { code = "en", label = "English" },
80 { code = "tr", label = "Türkçe" },
81 { code = "ru", label = "Русский" },
82 { code = "vi", label = "Tiếng Việt" },
83}
84
85local LANGUAGE_FILE = "DedeHub/Language.txt"
86
87local Locales = {
88 en = {
89 hub_name = "DEDE HUB",
90 nav_vision = "Vision",
91 nav_entities = "Entities",
92 nav_misc = "Misc",
93 nav_settings = "Settings",
94 sec_esp = "ESP",
95 sec_esp_sub = "Wall vision overlays",
96 tog_skeleton = "Bone / Skeleton",
97 tog_skeleton_desc = "Joint line overlay",
98 tog_box = "Box",
99 tog_box_desc = "2D bounding box",
100 tog_health = "Health",
101 tog_health_desc = "Side health bar",
102 tog_name = "Name",
103 tog_name_desc = "Player name tag",
104 tog_glow = "Glow",
105 tog_glow_desc = "Filled body glow",
106 sec_filters = "Filters",
107 tog_teammates = "Show teammates",
108 tog_teammates_desc = "Include same team",
109 tog_master = "Master ESP",
110 tog_master_desc = "Enable all overlays",
111 sec_players = "Players",
112 sec_players_sub = "Who appears on ESP",
113 tog_teammates_ent_desc = "Same team players",
114 tog_master_ent_desc = "Global ESP switch",
115 sec_protection = "Protection",
116 sec_protection_sub = "Visual countermeasures",
117 tog_antiflash = "Anti Flash",
118 tog_antiflash_desc = "Lighting + screen flash block",
119 tog_smoke = "Remove Smoke",
120 tog_smoke_desc = "Smoke / fog / particles",
121 sec_world = "World",
122 sec_world_sub = "Lighting & atmosphere",
123 tog_env = "Environment color",
124 tog_env_desc = "Tint ambient lighting",
125 tog_sky = "Sky color",
126 tog_sky_desc = "Tint sky / atmosphere",
127 color_env = "Environment tint",
128 color_sky = "Sky tint",
129 sec_esp_colors = "ESP Colors",
130 sec_esp_colors_sub = "Overlay palette",
131 color_enemy = "Enemy color",
132 color_team = "Teammate color",
133 sec_interface = "Interface",
134 sec_interface_sub = "Menu controls",
135 tip_controls = "• DEL — hide / show menu\n• Drag from the top to move\n• Use the left sidebar to switch tabs",
136 sec_appearance = "Appearance",
137 sec_appearance_sub = "Menu accent color",
138 color_menu = "Menu color",
139 sec_language = "Language",
140 sec_language_sub = "UI language",
141 sec_session = "Session",
142 sec_session_sub = "Unload cheat completely",
143 btn_destroy = "Destroy — kill script",
144 btn_closing = "Closing...",
145 },
146 tr = {
147 hub_name = "DEDE HUB",
148 nav_vision = "Görüş",
149 nav_entities = "Varlıklar",
150 nav_misc = "Diğer",
151 nav_settings = "Ayarlar",
152 sec_esp = "ESP",
153 sec_esp_sub = "Duvar arkası görüş",
154 tog_skeleton = "Kemik / Skeleton",
155 tog_skeleton_desc = "Eklem çizgileri",
156 tog_box = "Kutu",
157 tog_box_desc = "2D sınır kutusu",
158 tog_health = "Can",
159 tog_health_desc = "Yan can barı",
160 tog_name = "İsim",
161 tog_name_desc = "Oyuncu isim etiketi",
162 tog_glow = "Parlama",
163 tog_glow_desc = "Gövde dolgu parlaması",
164 sec_filters = "Filtreler",
165 tog_teammates = "Takımı göster",
166 tog_teammates_desc = "Aynı takımı dahil et",
167 tog_master = "Ana ESP",
168 tog_master_desc = "Tüm overlay'leri aç",
169 sec_players = "Oyuncular",
170 sec_players_sub = "ESP'de kimler görünsün",
171 tog_teammates_ent_desc = "Aynı takım oyuncuları",
172 tog_master_ent_desc = "Global ESP anahtarı",
173 sec_protection = "Koruma",
174 sec_protection_sub = "Görsel karşı önlemler",
175 tog_antiflash = "Anti Flash",
176 tog_antiflash_desc = "Işık + ekran flash engeli",
177 tog_smoke = "Smoke Kaldır",
178 tog_smoke_desc = "Duman / sis / particle",
179 sec_world = "Dünya",
180 sec_world_sub = "Işık ve atmosfer",
181 tog_env = "Çevre rengi",
182 tog_env_desc = "Ortam ışığını renklendir",
183 tog_sky = "Gökyüzü rengi",
184 tog_sky_desc = "Gökyüzü / atmosfer tonu",
185 color_env = "Çevre tonu",
186 color_sky = "Gökyüzü tonu",
187 sec_esp_colors = "ESP Renkleri",
188 sec_esp_colors_sub = "Overlay paleti",
189 color_enemy = "Düşman rengi",
190 color_team = "Takım rengi",
191 sec_interface = "Arayüz",
192 sec_interface_sub = "Menü kontrolleri",
193 tip_controls = "• DEL — menüyü gizle / göster\n• Üstten tutup sürükle\n• Sol menüden sekmeler arasında geç",
194 sec_appearance = "Görünüm",
195 sec_appearance_sub = "Menü vurgu rengi",
196 color_menu = "Menü rengi",
197 sec_language = "Dil",
198 sec_language_sub = "Arayüz dili",
199 sec_session = "Oturum",
200 sec_session_sub = "Hileyi tamamen kapat",
201 btn_destroy = "Destroy — scripti kapat",
202 btn_closing = "Kapatılıyor...",
203 },
204 ru = {
205 hub_name = "DEDE HUB",
206 nav_vision = "Обзор",
207 nav_entities = "Сущности",
208 nav_misc = "Разное",
209 nav_settings = "Настройки",
210 sec_esp = "ESP",
211 sec_esp_sub = "Обзор сквозь стены",
212 tog_skeleton = "Кости / Skeleton",
213 tog_skeleton_desc = "Линии суставов",
214 tog_box = "Бокс",
215 tog_box_desc = "2D рамка",
216 tog_health = "Здоровье",
217 tog_health_desc = "Полоска здоровья",
218 tog_name = "Имя",
219 tog_name_desc = "Имя игрока",
220 tog_glow = "Свечение",
221 tog_glow_desc = "Заливка тела",
222 sec_filters = "Фильтры",
223 tog_teammates = "Показывать команду",
224 tog_teammates_desc = "Включать союзников",
225 tog_master = "Главный ESP",
226 tog_master_desc = "Включить все оверлеи",
227 sec_players = "Игроки",
228 sec_players_sub = "Кто виден в ESP",
229 tog_teammates_ent_desc = "Игроки своей команды",
230 tog_master_ent_desc = "Глобальный ESP",
231 sec_protection = "Защита",
232 sec_protection_sub = "Визуальные контрмеры",
233 tog_antiflash = "Anti Flash",
234 tog_antiflash_desc = "Блок вспышек света / экрана",
235 tog_smoke = "Убрать дым",
236 tog_smoke_desc = "Дым / туман / частицы",
237 sec_world = "Мир",
238 sec_world_sub = "Освещение и атмосфера",
239 tog_env = "Цвет окружения",
240 tog_env_desc = "Оттенок ambient света",
241 tog_sky = "Цвет неба",
242 tog_sky_desc = "Оттенок неба / атмосферы",
243 color_env = "Тон окружения",
244 color_sky = "Тон неба",
245 sec_esp_colors = "Цвета ESP",
246 sec_esp_colors_sub = "Палитра оверлея",
247 color_enemy = "Цвет врага",
248 color_team = "Цвет союзника",
249 sec_interface = "Интерфейс",
250 sec_interface_sub = "Управление меню",
251 tip_controls = "• DEL — скрыть / показать меню\n• Тяни за верх, чтобы переместить\n• Вкладки слева",
252 sec_appearance = "Оформление",
253 sec_appearance_sub = "Акцентный цвет меню",
254 color_menu = "Цвет меню",
255 sec_language = "Язык",
256 sec_language_sub = "Язык интерфейса",
257 sec_session = "Сессия",
258 sec_session_sub = "Полностью выгрузить чит",
259 btn_destroy = "Destroy — закрыть скрипт",
260 btn_closing = "Закрытие...",
261 },
262 vi = {
263 hub_name = "DEDE HUB",
264 nav_vision = "Tầm nhìn",
265 nav_entities = "Thực thể",
266 nav_misc = "Khác",
267 nav_settings = "Cài đặt",
268 sec_esp = "ESP",
269 sec_esp_sub = "Nhìn xuyên tường",
270 tog_skeleton = "Xương / Skeleton",
271 tog_skeleton_desc = "Đường khớp xương",
272 tog_box = "Hộp",
273 tog_box_desc = "Khung 2D",
274 tog_health = "Máu",
275 tog_health_desc = "Thanh máu bên cạnh",
276 tog_name = "Tên",
277 tog_name_desc = "Nhãn tên người chơi",
278 tog_glow = "Phát sáng",
279 tog_glow_desc = "Tô sáng cơ thể",
280 sec_filters = "Bộ lọc",
281 tog_teammates = "Hiện đồng đội",
282 tog_teammates_desc = "Bao gồm cùng đội",
283 tog_master = "ESP chính",
284 tog_master_desc = "Bật mọi overlay",
285 sec_players = "Người chơi",
286 sec_players_sub = "Ai hiện trên ESP",
287 tog_teammates_ent_desc = "Người cùng đội",
288 tog_master_ent_desc = "Công tắc ESP toàn cục",
289 sec_protection = "Bảo vệ",
290 sec_protection_sub = "Chống hiệu ứng thị giác",
291 tog_antiflash = "Anti Flash",
292 tog_antiflash_desc = "Chặn flash ánh sáng / màn hình",
293 tog_smoke = "Xóa khói",
294 tog_smoke_desc = "Khói / sương / particle",
295 sec_world = "Thế giới",
296 sec_world_sub = "Ánh sáng & bầu khí quyển",
297 tog_env = "Màu môi trường",
298 tog_env_desc = "Tô màu ánh sáng ambient",
299 tog_sky = "Màu bầu trời",
300 tog_sky_desc = "Tông bầu trời / atmosphere",
301 color_env = "Tông môi trường",
302 color_sky = "Tông bầu trời",
303 sec_esp_colors = "Màu ESP",
304 sec_esp_colors_sub = "Bảng màu overlay",
305 color_enemy = "Màu địch",
306 color_team = "Màu đồng đội",
307 sec_interface = "Giao diện",
308 sec_interface_sub = "Điều khiển menu",
309 tip_controls = "• DEL — ẩn / hiện menu\n• Kéo từ trên để di chuyển\n• Đổi tab ở thanh bên trái",
310 sec_appearance = "Giao diện màu",
311 sec_appearance_sub = "Màu nhấn menu",
312 color_menu = "Màu menu",
313 sec_language = "Ngôn ngữ",
314 sec_language_sub = "Ngôn ngữ giao diện",
315 sec_session = "Phiên",
316 sec_session_sub = "Tắt hoàn toàn cheat",
317 btn_destroy = "Destroy — tắt script",
318 btn_closing = "Đang đóng...",
319 },
320}
321
322local function normalizeLanguage(code)
323 code = tostring(code or "en"):lower()
324 if Locales[code] then
325 return code
326 end
327 return "en"
328end
329
330local function readSavedLanguage()
331 local fromEnv = nil
332 pcall(function()
333 if typeof(getgenv) == "function" then
334 fromEnv = getgenv().DedeHubLanguage
335 end
336 end)
337 if type(fromEnv) == "string" and #fromEnv > 0 then
338 return fromEnv
339 end
340 if typeof(isfile) == "function" and typeof(readfile) == "function" then
341 local ok, content = pcall(function()
342 if isfile(LANGUAGE_FILE) then
343 return readfile(LANGUAGE_FILE)
344 end
345 return nil
346 end)
347 if ok and type(content) == "string" and #content > 0 then
348 return content:match("%S+")
349 end
350 end
351 return "en"
352end
353
354local function persistLanguage(code)
355 pcall(function()
356 if typeof(getgenv) == "function" then
357 getgenv().DedeHubLanguage = code
358 end
359 end)
360 if typeof(writefile) == "function" then
361 pcall(function()
362 if typeof(makefolder) == "function" and typeof(isfolder) == "function" and not isfolder("DedeHub") then
363 makefolder("DedeHub")
364 end
365 writefile(LANGUAGE_FILE, code)
366 end)
367 end
368end
369
370local currentLanguage = normalizeLanguage(readSavedLanguage())
371persistLanguage(currentLanguage)
372
373local function t(key, ...)
374 local pack = Locales[currentLanguage] or Locales.en
375 local str = pack[key] or Locales.en[key] or tostring(key)
376 if select("#", ...) > 0 then
377 local ok, formatted = pcall(string.format, str, ...)
378 if ok then
379 return formatted
380 end
381 end
382 return str
383end
384
385local localeBindings = {}
386
387local function bindLocale(inst, key, opts)
388 opts = opts or {}
389 localeBindings[#localeBindings + 1] = {
390 inst = inst,
391 key = key,
392 prop = opts.prop or "Text",
393 upper = opts.upper == true,
394 prefix = opts.prefix,
395 suffix = opts.suffix,
396 icon = opts.icon,
397 }
398 local str = t(key)
399 if opts.upper then
400 str = string.upper(str)
401 end
402 if opts.icon then
403 str = " " .. opts.icon .. " " .. str
404 end
405 if opts.prefix then
406 str = opts.prefix .. str
407 end
408 if opts.suffix then
409 str = str .. opts.suffix
410 end
411 inst[opts.prop or "Text"] = str
412end
413
414local function applyLocaleToUI()
415 for i = 1, #localeBindings do
416 local b = localeBindings[i]
417 if b.inst and b.inst.Parent then
418 local str = t(b.key)
419 if b.upper then
420 str = string.upper(str)
421 end
422 if b.icon then
423 str = " " .. b.icon .. " " .. str
424 end
425 if b.prefix then
426 str = b.prefix .. str
427 end
428 if b.suffix then
429 str = str .. b.suffix
430 end
431 b.inst[b.prop] = str
432 end
433 end
434end
435
436local function setLanguage(code)
437 currentLanguage = normalizeLanguage(code)
438 persistLanguage(currentLanguage)
439 applyLocaleToUI()
440 return currentLanguage
441end
442
443
444----------------------------------------------------------------
445-- Script body
446----------------------------------------------------------------
447
448local function getHiddenUiParent()
449 local parent
450 pcall(function()
451 if typeof(gethui) == "function" then
452 parent = gethui()
453 end
454 end)
455 if not parent then
456 parent = CoreGui
457 end
458 return parent
459end
460
461local function protect(gui)
462 pcall(function()
463 if syn and syn.protect_gui then
464 syn.protect_gui(gui)
465 elseif protect_gui then
466 protect_gui(gui)
467 elseif typeof(protectgui) == "function" then
468 protectgui(gui)
469 end
470 end)
471end
472
473-- Tear down previous session markers stored weakly via attribute on holder
474local uiParent = getHiddenUiParent()
475pcall(function()
476 for _, child in ipairs(uiParent:GetChildren()) do
477 if child:GetAttribute("_sid") == true then
478 child:Destroy()
479 end
480 end
481end)
482
483local holder = Instance.new("Folder")
484holder.Name = HOLDER_NAME
485holder:SetAttribute("_sid", true)
486holder.Parent = uiParent
487
488
489local tracked = {}
490local connections = {}
491local alive = true
492local DRAWING_OK = typeof(Drawing) == "table" and typeof(Drawing.new) == "function"
493
494local R15_PAIRS = {
495 { "Head", "UpperTorso" },
496 { "UpperTorso", "LowerTorso" },
497 { "UpperTorso", "LeftUpperArm" },
498 { "LeftUpperArm", "LeftLowerArm" },
499 { "LeftLowerArm", "LeftHand" },
500 { "UpperTorso", "RightUpperArm" },
501 { "RightUpperArm", "RightLowerArm" },
502 { "RightLowerArm", "RightHand" },
503 { "LowerTorso", "LeftUpperLeg" },
504 { "LeftUpperLeg", "LeftLowerLeg" },
505 { "LeftLowerLeg", "LeftFoot" },
506 { "LowerTorso", "RightUpperLeg" },
507 { "RightUpperLeg", "RightLowerLeg" },
508 { "RightLowerLeg", "RightFoot" },
509}
510
511local R6_PAIRS = {
512 { "Head", "Torso" },
513 { "Torso", "Left Arm" },
514 { "Torso", "Right Arm" },
515 { "Torso", "Left Leg" },
516 { "Torso", "Right Leg" },
517}
518
519local boundBuf = { x = 0, y = 0, w = 0, h = 0 }
520local camCache = nil
521local frameId = 0
522local playerList = {} -- flat list for staggered updates
523local playerListDirty = true
524
525local function rebuildPlayerList()
526 table.clear(playerList)
527 for player in pairs(tracked) do
528 playerList[#playerList + 1] = player
529 end
530 playerListDirty = false
531end
532
533local function trackConn(conn)
534 connections[#connections + 1] = conn
535 return conn
536end
537
538local function safeRemove(obj)
539 if not obj then return end
540 pcall(function()
541 obj.Visible = false
542 obj:Remove()
543 end)
544end
545
546local function isTeammate(player)
547 local a, b = player.Team, LocalPlayer.Team
548 return a ~= nil and b ~= nil and a == b
549end
550
551local function shouldShow(player)
552 if not Settings.Enabled or not alive then return false end
553 if player == LocalPlayer then return false end
554 if not Settings.ShowTeammates and isTeammate(player) then return false end
555 return true
556end
557
558local function getColor(player)
559 return isTeammate(player) and Settings.TeamColor or Settings.EnemyColor
560end
561
562local function w2s(pos)
563 local cam = camCache
564 if not cam then return nil, false end
565 local v, onScreen = cam:WorldToViewportPoint(pos)
566 if (not onScreen) or v.Z <= 0 then return nil, false end
567 return v, true
568end
569
570local function healthColor(ratio)
571 ratio = math.clamp(ratio, 0, 1)
572 return Color3.fromRGB(
573 math.floor(255 * (1 - ratio)),
574 math.floor(255 * ratio),
575 35
576 )
577end
578
579local function getCharacterBounds(entry)
580 local cam = camCache
581 local hrp = entry.hrp
582 if not cam or not hrp or not hrp.Parent then return nil end
583
584 local head = entry.head
585 local topPos = (head and head.Parent)
586 and (head.Position + Vector3.new(0, 0.4, 0))
587 or (hrp.Position + Vector3.new(0, 2.6, 0))
588 local footPos = hrp.Position - Vector3.new(0, 3.05, 0)
589
590 -- Don't require onScreen flag — Z depth alone; keeps size stable at range
591 local top = cam:WorldToViewportPoint(topPos)
592 local bottom = cam:WorldToViewportPoint(footPos)
593 if top.Z <= 0 or bottom.Z <= 0 then return nil end
594
595 local height = math.abs(top.Y - bottom.Y)
596 local dist = (cam.CFrame.Position - hrp.Position).Magnitude
597
598 -- Fallback if projection collapses (edge angles)
599 if height < 6 then
600 local vh = cam.ViewportSize.Y
601 height = (5 / math.max(dist, 1)) * (vh * 0.55)
602 end
603
604 -- Hard clamps so boxes never explode from accessories / angles
605 height = math.clamp(height, 6, math.min(cam.ViewportSize.Y * 0.55, 260))
606 local width = math.clamp(height * 0.5, 4, math.min(cam.ViewportSize.X * 0.28, 140))
607
608 local cx = (top.X + bottom.X) * 0.5
609 local topY = math.min(top.Y, bottom.Y)
610
611 boundBuf.x = cx - width * 0.5
612 boundBuf.y = topY
613 boundBuf.w = width
614 boundBuf.h = height
615 return boundBuf
616end
617
618local function hideDrawings(entry)
619 if not entry or not entry.drawn then return end
620 entry.drawn = false
621 if entry.box then
622 for i = 1, 4 do entry.box[i].Visible = false end
623 end
624 if entry.skeleton then
625 for i = 1, #entry.skeleton do entry.skeleton[i].Visible = false end
626 end
627 if entry.glow then entry.glow.Visible = false end
628 if entry.healthBg then entry.healthBg.Visible = false end
629 if entry.healthFg then entry.healthFg.Visible = false end
630 if entry.nameText then entry.nameText.Visible = false end
631end
632
633local function destroyDrawings(entry)
634 if not entry then return end
635 if entry.box then
636 for i = 1, #entry.box do safeRemove(entry.box[i]) end
637 entry.box = nil
638 end
639 if entry.skeleton then
640 for i = 1, #entry.skeleton do safeRemove(entry.skeleton[i]) end
641 entry.skeleton = nil
642 end
643 safeRemove(entry.glow)
644 safeRemove(entry.healthBg)
645 safeRemove(entry.healthFg)
646 safeRemove(entry.nameText)
647 entry.glow = nil
648 entry.healthBg = nil
649 entry.healthFg = nil
650 entry.nameText = nil
651 entry.drawn = false
652end
653
654local function removePlayer(player)
655 local entry = tracked[player]
656 if not entry then return end
657 destroyDrawings(entry)
658 local ec = entry.connections
659 if ec then
660 for i = 1, #ec do
661 pcall(function() ec[i]:Disconnect() end)
662 end
663 end
664 tracked[player] = nil
665 playerListDirty = true
666end
667
668local function newLine(thickness)
669 local line = Drawing.new("Line")
670 line.Thickness = thickness
671 line.Transparency = 1
672 line.Visible = false
673 return line
674end
675
676local function ensureDrawings(entry)
677 if not DRAWING_OK then return false end
678
679 if Settings.Box and not entry.box then
680 entry.box = {
681 newLine(Settings.BoxThickness),
682 newLine(Settings.BoxThickness),
683 newLine(Settings.BoxThickness),
684 newLine(Settings.BoxThickness),
685 }
686 end
687
688 if Settings.Skeleton and not entry.skeleton then
689 local n = math.max(1, entry.boneLive or entry.boneCount or #R15_PAIRS)
690 entry.skeleton = table.create(n)
691 for i = 1, n do
692 entry.skeleton[i] = newLine(Settings.SkeletonThickness)
693 end
694 end
695
696 if Settings.Glow and not entry.glow then
697 local g = Drawing.new("Square")
698 g.Filled = true
699 g.Thickness = 0
700 g.Transparency = 0.72
701 g.Visible = false
702 entry.glow = g
703 end
704
705 if Settings.Health and not entry.healthBg then
706 local bg = Drawing.new("Square")
707 bg.Filled = true
708 bg.Thickness = 0
709 bg.Transparency = 1
710 bg.Color = Color3.fromRGB(15, 15, 15)
711 bg.Visible = false
712 entry.healthBg = bg
713
714 local fg = Drawing.new("Square")
715 fg.Filled = true
716 fg.Thickness = 0
717 fg.Transparency = 1
718 fg.Visible = false
719 entry.healthFg = fg
720 end
721
722 if Settings.Name and not entry.nameText then
723 local text = Drawing.new("Text")
724 text.Center = true
725 text.Outline = true
726 text.Size = 13
727 text.Font = 2
728 text.Transparency = 1
729 text.Visible = false
730 entry.nameText = text
731 end
732
733 return true
734end
735
736local function cacheCharacter(entry, character)
737 entry.char = character
738 entry.hum = character:FindFirstChildOfClass("Humanoid")
739 entry.hrp = character:FindFirstChild("HumanoidRootPart")
740 entry.head = character:FindFirstChild("Head")
741
742 local pairsDef = character:FindFirstChild("UpperTorso") and R15_PAIRS or R6_PAIRS
743 entry.boneCount = #pairsDef
744 local bones = table.create(#pairsDef)
745 local count = 0
746 for i = 1, #pairsDef do
747 local a = character:FindFirstChild(pairsDef[i][1])
748 local b = character:FindFirstChild(pairsDef[i][2])
749 if a and b and a:IsA("BasePart") and b:IsA("BasePart") then
750 count += 1
751 bones[count] = { a, b }
752 end
753 end
754 entry.bones = bones
755 entry.boneLive = count
756
757 if entry.skeleton and #entry.skeleton ~= count and count > 0 then
758 for i = 1, #entry.skeleton do safeRemove(entry.skeleton[i]) end
759 entry.skeleton = nil
760 end
761end
762
763local function setBox(entry, bounds, color, visible)
764 local box = entry.box
765 if not box then return end
766 if not visible or not bounds then
767 for i = 1, 4 do box[i].Visible = false end
768 return
769 end
770 local x, y, w, h = bounds.x, bounds.y, bounds.w, bounds.h
771 local x2, y2 = x + w, y + h
772 local l1, l2, l3, l4 = box[1], box[2], box[3], box[4]
773 l1.From = Vector2.new(x, y); l1.To = Vector2.new(x2, y); l1.Color = color; l1.Visible = true
774 l2.From = Vector2.new(x2, y); l2.To = Vector2.new(x2, y2); l2.Color = color; l2.Visible = true
775 l3.From = Vector2.new(x2, y2); l3.To = Vector2.new(x, y2); l3.Color = color; l3.Visible = true
776 l4.From = Vector2.new(x, y2); l4.To = Vector2.new(x, y); l4.Color = color; l4.Visible = true
777end
778
779local function setGlow(entry, bounds, color, visible)
780 local g = entry.glow
781 if not g then return end
782 if not visible or not bounds then
783 g.Visible = false
784 return
785 end
786 g.Position = Vector2.new(bounds.x, bounds.y)
787 g.Size = Vector2.new(bounds.w, bounds.h)
788 g.Color = color
789 g.Visible = true
790end
791
792local function setSkeleton(entry, color, visible)
793 local lines = entry.skeleton
794 local bones = entry.bones
795 if not lines or not bones then return end
796 if not visible then
797 for i = 1, #lines do lines[i].Visible = false end
798 return
799 end
800 local n = math.min(#lines, entry.boneLive or 0)
801 for i = 1, n do
802 local bone = bones[i]
803 local line = lines[i]
804 local v1, ok1 = w2s(bone[1].Position)
805 local v2, ok2 = w2s(bone[2].Position)
806 if ok1 and ok2 then
807 line.From = Vector2.new(v1.X, v1.Y)
808 line.To = Vector2.new(v2.X, v2.Y)
809 line.Color = color
810 line.Visible = true
811 else
812 line.Visible = false
813 end
814 end
815 for i = n + 1, #lines do
816 lines[i].Visible = false
817 end
818end
819
820local function setHealth(entry, hum, bounds, visible)
821 local bg, fg = entry.healthBg, entry.healthFg
822 if not bg or not fg then return end
823 if not visible or not bounds or not hum then
824 bg.Visible = false
825 fg.Visible = false
826 return
827 end
828 local ratio = math.clamp(hum.Health / math.max(1, hum.MaxHealth), 0, 1)
829 local x = bounds.x - 6
830 local y, h = bounds.y, bounds.h
831 local filled = h * ratio
832 bg.Position = Vector2.new(x, y)
833 bg.Size = Vector2.new(3, h)
834 bg.Visible = true
835 fg.Position = Vector2.new(x, y + (h - filled))
836 fg.Size = Vector2.new(3, filled)
837 fg.Color = healthColor(ratio)
838 fg.Visible = true
839end
840
841local function setName(entry, player, bounds, head, color, visible)
842 local text = entry.nameText
843 if not text then return end
844 if not visible then
845 text.Visible = false
846 return
847 end
848
849 local posX, posY
850 if bounds then
851 posX = bounds.x + bounds.w * 0.5
852 posY = bounds.y - 15
853 elseif head then
854 local v, ok = w2s(head.Position + Vector3.new(0, 1.15, 0))
855 if not ok then
856 text.Visible = false
857 return
858 end
859 posX, posY = v.X, v.Y
860 else
861 text.Visible = false
862 return
863 end
864
865 if entry.nameStr == nil then
866 local dn, nm = player.DisplayName, player.Name
867 entry.nameStr = (dn ~= nm) and (dn .. " @" .. nm) or nm
868 text.Text = entry.nameStr
869 end
870 text.Position = Vector2.new(posX, posY)
871 text.Color = color
872 text.Visible = true
873end
874
875local function updatePlayer(player, entry)
876 local character = player.Character
877 if not character then
878 hideDrawings(entry)
879 entry.char = nil
880 return
881 end
882
883 -- Re-cache when character is new OR parts weren't ready on first cache
884 if character ~= entry.char
885 or not entry.hrp or entry.hrp.Parent ~= character
886 or not entry.hum or entry.hum.Parent ~= character
887 then
888 cacheCharacter(entry, character)
889 end
890
891 local hum = entry.hum
892 if not hum or hum.Health <= 0 then
893 hideDrawings(entry)
894 return
895 end
896
897 if not shouldShow(player) then
898 hideDrawings(entry)
899 return
900 end
901
902 local hrp = entry.hrp
903 if not hrp or hrp.Parent ~= character then
904 hideDrawings(entry)
905 return
906 end
907
908 local _, onHrp = w2s(hrp.Position)
909 if not onHrp then
910 hideDrawings(entry)
911 return
912 end
913
914 if not ensureDrawings(entry) then return end
915 entry.drawn = true
916
917 local color = getColor(player)
918 local needBounds = Settings.Box or Settings.Health or Settings.Name or Settings.Glow
919 local bounds = needBounds and getCharacterBounds(entry) or nil
920 local onScreen = bounds ~= nil
921
922 if Settings.Glow then
923 setGlow(entry, bounds, color, onScreen)
924 elseif entry.glow then
925 entry.glow.Visible = false
926 end
927
928 if Settings.Box then
929 setBox(entry, bounds, color, onScreen)
930 elseif entry.box then
931 for i = 1, 4 do entry.box[i].Visible = false end
932 end
933
934 if Settings.Skeleton then
935 -- Refresh bones if still incomplete (R15 parts stream in late)
936 if (entry.boneLive or 0) < 5 then
937 cacheCharacter(entry, character)
938 end
939 setSkeleton(entry, color, true)
940 elseif entry.skeleton then
941 for i = 1, #entry.skeleton do entry.skeleton[i].Visible = false end
942 end
943
944 if Settings.Health then
945 setHealth(entry, hum, bounds, onScreen)
946 elseif entry.healthBg then
947 entry.healthBg.Visible = false
948 if entry.healthFg then entry.healthFg.Visible = false end
949 end
950
951 if Settings.Name then
952 setName(entry, player, bounds, entry.head, color, true)
953 elseif entry.nameText then
954 entry.nameText.Visible = false
955 end
956end
957
958local function hookPlayer(player)
959 if player == LocalPlayer or tracked[player] then return end
960
961 local entry = {
962 drawn = false,
963 connections = {},
964 nameStr = nil,
965 }
966 tracked[player] = entry
967 playerListDirty = true
968
969 local function onCharacter(char)
970 if typeof(char) ~= "Instance" then return end
971 task.spawn(function()
972 if tracked[player] ~= entry or not alive then return end
973 char:WaitForChild("Humanoid", 8)
974 char:WaitForChild("HumanoidRootPart", 8)
975 char:WaitForChild("Head", 8)
976 if tracked[player] ~= entry or not alive then return end
977 if player.Character ~= char then return end
978 cacheCharacter(entry, char)
979 entry.nameStr = nil
980 playerListDirty = true
981
982 -- Parts can appear slightly later (R15)
983 task.wait(0.35)
984 if tracked[player] == entry and alive and player.Character == char then
985 cacheCharacter(entry, char)
986 end
987 end)
988 end
989
990 if player.Character then
991 onCharacter(player.Character)
992 end
993
994 entry.connections[#entry.connections + 1] = player.CharacterAdded:Connect(onCharacter)
995 entry.connections[#entry.connections + 1] = player.CharacterRemoving:Connect(function()
996 hideDrawings(entry)
997 entry.char = nil
998 entry.hrp = nil
999 entry.hum = nil
1000 entry.head = nil
1001 entry.bones = nil
1002 end)
1003
1004 pcall(function()
1005 entry.connections[#entry.connections + 1] = player.CharacterAppearanceLoaded:Connect(function(char)
1006 if tracked[player] == entry and alive then
1007 cacheCharacter(entry, char)
1008 entry.nameStr = nil
1009 end
1010 end)
1011 end)
1012end
1013
1014for _, player in ipairs(Players:GetPlayers()) do
1015 hookPlayer(player)
1016end
1017trackConn(Players.PlayerAdded:Connect(function(player)
1018 hookPlayer(player)
1019end))
1020trackConn(Players.PlayerRemoving:Connect(removePlayer))
1021
1022----------------------------------------------------------------
1023-- Misc visuals — universal Anti Flash / Anti Smoke
1024----------------------------------------------------------------
1025
1026local miscAtm = nil
1027local miscSkyCC = nil
1028
1029local smokeConn = nil
1030local smokeLoop = nil
1031local smokeWatched = setmetatable({}, { __mode = "k" })
1032local FogBackup = {
1033 FogStart = Lighting.FogStart,
1034 FogEnd = Lighting.FogEnd,
1035}
1036
1037local antiFlashConn = nil
1038local antiFlashBrightConn = nil
1039local antiFlashExposureConn = nil
1040local antiFlashGuiConn = nil
1041local antiFlashLoop = nil
1042local antiFlashFxConns = {}
1043local flashGuiWatched = setmetatable({}, { __mode = "k" })
1044local flashFxHooked = setmetatable({}, { __mode = "k" })
1045
1046local SMOKE_WORDS = {
1047 "smoke", "smok", "fog", "mist", "dust", "cloud", "steam",
1048 "haze", "gas", "smokescreen", "smokegrenade", "smoke_nade",
1049 "particle_smoke", "smokeparticle", "vapor", "fume",
1050}
1051
1052local FLASH_WORDS = {
1053 "flash", "blind", "whiteout", "stun", "flashbang", "flashed",
1054 "flashgui", "blindness", "screenflash", "whitflash", "impactflash",
1055}
1056
1057local function textHasWord(text, words)
1058 if not text or text == "" then return false end
1059 local t = string.lower(text)
1060 for i = 1, #words do
1061 if string.find(t, words[i], 1, true) then
1062 return true
1063 end
1064 end
1065 return false
1066end
1067
1068local function pathLooksSmoke(inst)
1069 local cur = inst
1070 for _ = 1, 5 do
1071 if not cur then break end
1072 if textHasWord(cur.Name, SMOKE_WORDS) then return true end
1073 cur = cur.Parent
1074 end
1075 return false
1076end
1077
1078local function isSmokeLike(inst)
1079 if not inst or not inst.Parent then return false end
1080 if inst:IsA("Smoke") then return true end
1081 if inst:IsA("ParticleEmitter") then
1082 if pathLooksSmoke(inst) then return true end
1083 local ok, tex = pcall(function()
1084 return tostring(inst.Texture)
1085 end)
1086 if ok and textHasWord(tex, SMOKE_WORDS) then return true end
1087 -- Large soft gray clouds often used as smoke without keywords
1088 local ok2, size = pcall(function()
1089 return inst.Size
1090 end)
1091 if ok2 and typeof(size) == "NumberSequence" then
1092 local keypoints = size.Keypoints
1093 local maxSz = 0
1094 for i = 1, #keypoints do
1095 if keypoints[i].Value > maxSz then maxSz = keypoints[i].Value end
1096 end
1097 if maxSz >= 4 and inst.Rate >= 12 and pathLooksSmoke(inst.Parent) then
1098 return true
1099 end
1100 end
1101 return false
1102 end
1103 if inst:IsA("Fire") then
1104 return pathLooksSmoke(inst)
1105 end
1106 return false
1107end
1108
1109local function neutralizeSmoke(inst)
1110 if not inst then return end
1111 pcall(function()
1112 if inst:IsA("Smoke") then
1113 inst.Enabled = false
1114 inst.Opacity = 0
1115 inst.Size = 0
1116 elseif inst:IsA("ParticleEmitter") then
1117 inst.Enabled = false
1118 inst.Rate = 0
1119 pcall(function()
1120 inst.Lifetime = NumberRange.new(0)
1121 end)
1122 elseif inst:IsA("Fire") then
1123 inst.Enabled = false
1124 inst.Size = 0
1125 end
1126 end)
1127
1128 if smokeWatched[inst] then return end
1129 smokeWatched[inst] = true
1130
1131 if inst:IsA("ParticleEmitter") or inst:IsA("Smoke") or inst:IsA("Fire") then
1132 local c1 = inst:GetPropertyChangedSignal("Enabled"):Connect(function()
1133 if Settings.RemoveSmoke and inst.Parent and inst.Enabled then
1134 inst.Enabled = false
1135 end
1136 end)
1137 table.insert(connections, c1)
1138 if inst:IsA("ParticleEmitter") then
1139 local c2 = inst:GetPropertyChangedSignal("Rate"):Connect(function()
1140 if Settings.RemoveSmoke and inst.Parent and inst.Rate > 0 then
1141 inst.Rate = 0
1142 end
1143 end)
1144 table.insert(connections, c2)
1145 end
1146 end
1147end
1148
1149local function sweepSmokeIn(root)
1150 if not root then return end
1151 task.spawn(function()
1152 local list = root:GetDescendants()
1153 local i, n = 1, #list
1154 while i <= n and Settings.RemoveSmoke and alive do
1155 local last = math.min(i + 100, n)
1156 for j = i, last do
1157 local inst = list[j]
1158 if isSmokeLike(inst) then
1159 neutralizeSmoke(inst)
1160 end
1161 end
1162 i = last + 1
1163 task.wait()
1164 end
1165 end)
1166end
1167
1168local function setRemoveSmoke(on)
1169 if smokeLoop then
1170 pcall(function() task.cancel(smokeLoop) end)
1171 smokeLoop = nil
1172 end
1173 -- disconnect only the DescendantAdded we stored on smokeConn
1174 if smokeConn then
1175 pcall(function() smokeConn:Disconnect() end)
1176 smokeConn = nil
1177 end
1178
1179 if not on then
1180 pcall(function()
1181 Lighting.FogStart = FogBackup.FogStart
1182 Lighting.FogEnd = FogBackup.FogEnd
1183 end)
1184 return
1185 end
1186
1187 FogBackup.FogStart = Lighting.FogStart
1188 FogBackup.FogEnd = Lighting.FogEnd
1189 pcall(function()
1190 Lighting.FogStart = 0
1191 Lighting.FogEnd = 1e6
1192 end)
1193 if miscAtm and miscAtm.Parent then
1194 pcall(function()
1195 miscAtm.Haze = 0
1196 miscAtm.Density = math.min(miscAtm.Density, 0.15)
1197 end)
1198 else
1199 local atm = Lighting:FindFirstChildOfClass("Atmosphere")
1200 if atm then
1201 pcall(function()
1202 atm.Haze = 0
1203 end)
1204 end
1205 end
1206
1207 sweepSmokeIn(workspace)
1208 local cam = workspace.CurrentCamera
1209 if cam then sweepSmokeIn(cam) end
1210
1211 smokeConn = workspace.DescendantAdded:Connect(function(inst)
1212 if not Settings.RemoveSmoke or not alive then return end
1213 if inst:IsA("Smoke") or inst:IsA("ParticleEmitter") or inst:IsA("Fire") then
1214 task.defer(function()
1215 if isSmokeLike(inst) then
1216 neutralizeSmoke(inst)
1217 end
1218 end)
1219 end
1220 end)
1221
1222 smokeLoop = task.spawn(function()
1223 while Settings.RemoveSmoke and alive do
1224 task.wait(1.25)
1225 if not Settings.RemoveSmoke or not alive then break end
1226 sweepSmokeIn(workspace)
1227 local c = workspace.CurrentCamera
1228 if c then sweepSmokeIn(c) end
1229 pcall(function()
1230 if Lighting.FogEnd < 1e5 then
1231 Lighting.FogEnd = 1e6
1232 end
1233 end)
1234 end
1235 end)
1236end
1237
1238local function clearAntiFlashHooks()
1239 if antiFlashConn then
1240 pcall(function() antiFlashConn:Disconnect() end)
1241 antiFlashConn = nil
1242 end
1243 if antiFlashBrightConn then
1244 pcall(function() antiFlashBrightConn:Disconnect() end)
1245 antiFlashBrightConn = nil
1246 end
1247 if antiFlashExposureConn then
1248 pcall(function() antiFlashExposureConn:Disconnect() end)
1249 antiFlashExposureConn = nil
1250 end
1251 if antiFlashGuiConn then
1252 pcall(function() antiFlashGuiConn:Disconnect() end)
1253 antiFlashGuiConn = nil
1254 end
1255 if antiFlashLoop then
1256 pcall(function() task.cancel(antiFlashLoop) end)
1257 antiFlashLoop = nil
1258 end
1259 for i = 1, #antiFlashFxConns do
1260 pcall(function() antiFlashFxConns[i]:Disconnect() end)
1261 end
1262 table.clear(antiFlashFxConns)
1263 table.clear(flashFxHooked)
1264end
1265
1266local function neutralizeFlashGui(gui)
1267 if not gui or not gui.Parent then return end
1268 pcall(function()
1269 gui.Visible = false
1270 if gui:IsA("GuiObject") then
1271 gui.BackgroundTransparency = 1
1272 end
1273 if gui:IsA("ImageLabel") or gui:IsA("ImageButton") then
1274 gui.ImageTransparency = 1
1275 end
1276 if gui:IsA("Frame") or gui:IsA("ImageLabel") then
1277 -- collapse so layout can't re-cover screen
1278 gui.Size = UDim2.fromOffset(0, 0)
1279 end
1280 end)
1281 if flashGuiWatched[gui] then return end
1282 flashGuiWatched[gui] = true
1283 pcall(function()
1284 local c = gui:GetPropertyChangedSignal("Visible"):Connect(function()
1285 if Settings.AntiFlash and gui.Visible then
1286 gui.Visible = false
1287 end
1288 end)
1289 table.insert(connections, c)
1290 end)
1291end
1292
1293local function isFullscreenFlash(gui)
1294 if not gui:IsA("GuiObject") then return false end
1295 if gui.BackgroundTransparency >= 0.55 and not (gui:IsA("ImageLabel") and gui.ImageTransparency < 0.55) then
1296 return false
1297 end
1298 local cam = workspace.CurrentCamera
1299 if not cam then return false end
1300 local vp = cam.ViewportSize
1301 local size = gui.AbsoluteSize
1302 if size.X < vp.X * 0.7 or size.Y < vp.Y * 0.7 then
1303 return false
1304 end
1305 local c = gui.BackgroundColor3
1306 local bright = (c.R + c.G + c.B) / 3
1307 if bright >= 0.75 then return true end
1308 if gui:IsA("ImageLabel") and gui.ImageTransparency < 0.4 then
1309 return true
1310 end
1311 return false
1312end
1313
1314local function maybeFlashGui(gui)
1315 if not gui or not gui:IsA("GuiObject") then return end
1316 if textHasWord(gui.Name, FLASH_WORDS) then
1317 neutralizeFlashGui(gui)
1318 return
1319 end
1320 if isFullscreenFlash(gui) then
1321 neutralizeFlashGui(gui)
1322 end
1323end
1324
1325local function scanFlashGuisLight()
1326 local pg = LocalPlayer:FindFirstChild("PlayerGui")
1327 if not pg then return end
1328 local cam = workspace.CurrentCamera
1329 local vp = cam and cam.ViewportSize
1330 for _, screen in ipairs(pg:GetChildren()) do
1331 if screen:IsA("ScreenGui") or screen:IsA("BillboardGui") or screen:IsA("LayerCollector") then
1332 if textHasWord(screen.Name, FLASH_WORDS) then
1333 screen.Enabled = false
1334 end
1335 -- only direct children + one nested level (cheap, covers most flash UIs)
1336 for _, child in ipairs(screen:GetChildren()) do
1337 maybeFlashGui(child)
1338 if child:IsA("Frame") or child:IsA("CanvasGroup") then
1339 for _, nested in ipairs(child:GetChildren()) do
1340 if nested:IsA("GuiObject") then
1341 if textHasWord(nested.Name, FLASH_WORDS) or (vp and nested.AbsoluteSize.X >= vp.X * 0.7) then
1342 maybeFlashGui(nested)
1343 end
1344 end
1345 end
1346 end
1347 end
1348 end
1349 end
1350end
1351
1352local function hookFlashFx(fx)
1353 if not fx or fx == miscSkyCC or flashFxHooked[fx] then return end
1354 if not (fx:IsA("BloomEffect") or fx:IsA("ColorCorrectionEffect") or fx:IsA("BlurEffect")
1355 or fx:IsA("DepthOfFieldEffect") or fx:IsA("SunRaysEffect")) then
1356 return
1357 end
1358 flashFxHooked[fx] = true
1359
1360 local function watchNumber(prop, maxKeep, setTo)
1361 antiFlashFxConns[#antiFlashFxConns + 1] = fx:GetPropertyChangedSignal(prop):Connect(function()
1362 if not Settings.AntiFlash or fx == miscSkyCC or not fx.Parent then return end
1363 if fx[prop] > maxKeep then
1364 fx[prop] = setTo
1365 end
1366 end)
1367 end
1368
1369 local function watchDisable()
1370 antiFlashFxConns[#antiFlashFxConns + 1] = fx:GetPropertyChangedSignal("Enabled"):Connect(function()
1371 if Settings.AntiFlash and fx.Parent and fx.Enabled then
1372 fx.Enabled = false
1373 end
1374 end)
1375 end
1376
1377 if fx:IsA("BloomEffect") then
1378 fx.Enabled = false
1379 fx.Intensity = 0
1380 fx.Size = 0
1381 watchDisable()
1382 watchNumber("Intensity", 0, 0)
1383 elseif fx:IsA("ColorCorrectionEffect") then
1384 if fx.Brightness > 0 then fx.Brightness = 0 end
1385 if fx.Contrast > 0.35 then fx.Contrast = 0 end
1386 watchNumber("Brightness", 0.02, 0)
1387 watchNumber("Contrast", 0.35, 0)
1388 elseif fx:IsA("BlurEffect") then
1389 if fx.Size > 0 then fx.Size = 0 end
1390 watchNumber("Size", 1, 0)
1391 elseif fx:IsA("DepthOfFieldEffect") then
1392 fx.Enabled = false
1393 watchDisable()
1394 elseif fx:IsA("SunRaysEffect") then
1395 if fx.Intensity > 0.05 then fx.Intensity = 0.05 end
1396 watchNumber("Intensity", 0.05, 0.05)
1397 end
1398end
1399
1400local function clampLightingFlash()
1401 pcall(function()
1402 if Lighting.Brightness > 1.2 then
1403 Lighting.Brightness = 1.2
1404 end
1405 if Lighting.ExposureCompensation > 0.2 then
1406 Lighting.ExposureCompensation = 0.2
1407 end
1408 end)
1409 for _, fx in ipairs(Lighting:GetChildren()) do
1410 if fx:IsA("BloomEffect") then
1411 fx.Enabled = false
1412 fx.Intensity = 0
1413 elseif fx:IsA("ColorCorrectionEffect") and fx ~= miscSkyCC then
1414 if fx.Brightness > 0.02 then fx.Brightness = 0 end
1415 if fx.Contrast > 0.35 then fx.Contrast = 0 end
1416 elseif fx:IsA("BlurEffect") and fx.Size > 1 then
1417 fx.Size = 0
1418 elseif fx:IsA("DepthOfFieldEffect") then
1419 fx.Enabled = false
1420 elseif fx:IsA("SunRaysEffect") and fx.Intensity > 0.05 then
1421 fx.Intensity = 0.05
1422 end
1423 hookFlashFx(fx)
1424 end
1425end
1426
1427local function setAntiFlash(on)
1428 clearAntiFlashHooks()
1429 if not on then return end
1430
1431 clampLightingFlash()
1432
1433 antiFlashBrightConn = Lighting:GetPropertyChangedSignal("Brightness"):Connect(function()
1434 if Settings.AntiFlash and Lighting.Brightness > 1.2 then
1435 Lighting.Brightness = 1.2
1436 end
1437 end)
1438
1439 pcall(function()
1440 antiFlashExposureConn = Lighting:GetPropertyChangedSignal("ExposureCompensation"):Connect(function()
1441 if Settings.AntiFlash and Lighting.ExposureCompensation > 0.2 then
1442 Lighting.ExposureCompensation = 0.2
1443 end
1444 end)
1445 end)
1446
1447 antiFlashConn = Lighting.ChildAdded:Connect(function(fx)
1448 if Settings.AntiFlash then
1449 hookFlashFx(fx)
1450 end
1451 end)
1452
1453 local pg = LocalPlayer:FindFirstChild("PlayerGui") or LocalPlayer:WaitForChild("PlayerGui", 2)
1454 if pg then
1455 antiFlashGuiConn = pg.DescendantAdded:Connect(function(gui)
1456 if not Settings.AntiFlash or not alive then return end
1457 if not gui:IsA("Frame") and not gui:IsA("ImageLabel") and not gui:IsA("CanvasGroup") then
1458 return
1459 end
1460 -- Name hit is instant; size check deferred (avoids layout thrash)
1461 if textHasWord(gui.Name, FLASH_WORDS) then
1462 neutralizeFlashGui(gui)
1463 else
1464 task.defer(function()
1465 if Settings.AntiFlash and isFullscreenFlash(gui) then
1466 neutralizeFlashGui(gui)
1467 end
1468 end)
1469 end
1470 end)
1471 end
1472
1473 antiFlashLoop = task.spawn(function()
1474 while Settings.AntiFlash and alive do
1475 clampLightingFlash()
1476 scanFlashGuisLight()
1477 task.wait(0.35)
1478 end
1479 end)
1480end
1481
1482local function applyAntiFlash()
1483 if Settings.AntiFlash then
1484 clampLightingFlash()
1485 scanFlashGuisLight()
1486 end
1487end
1488
1489local function applyEnvColor()
1490 if Settings.CustomEnv then
1491 local c = Settings.EnvColor
1492 Lighting.Ambient = c
1493 Lighting.OutdoorAmbient = c
1494 Lighting.ColorShift_Top = c
1495 Lighting.ColorShift_Bottom = c
1496 Lighting.FogColor = c
1497 else
1498 Lighting.Ambient = LightingBackup.Ambient
1499 Lighting.OutdoorAmbient = LightingBackup.OutdoorAmbient
1500 Lighting.ColorShift_Top = LightingBackup.ColorShift_Top
1501 Lighting.ColorShift_Bottom = LightingBackup.ColorShift_Bottom
1502 Lighting.FogColor = LightingBackup.FogColor
1503 end
1504end
1505
1506local function applySkyColor()
1507 if Settings.CustomSky then
1508 if not miscAtm or not miscAtm.Parent then
1509 miscAtm = Lighting:FindFirstChildOfClass("Atmosphere")
1510 if not miscAtm then
1511 miscAtm = Instance.new("Atmosphere")
1512 miscAtm.Name = rndName("a")
1513 miscAtm.Parent = Lighting
1514 end
1515 end
1516 local c = Settings.SkyColor
1517 miscAtm.Color = c
1518 miscAtm.Decay = Color3.new(
1519 math.clamp(c.R * 0.55, 0, 1),
1520 math.clamp(c.G * 0.55, 0, 1),
1521 math.clamp(c.B * 0.55, 0, 1)
1522 )
1523 miscAtm.Density = 0.35
1524 miscAtm.Haze = 1.4
1525 miscAtm.Glare = 0.1
1526
1527 if not miscSkyCC or not miscSkyCC.Parent then
1528 miscSkyCC = Instance.new("ColorCorrectionEffect")
1529 miscSkyCC.Name = rndName("cc")
1530 miscSkyCC.Parent = Lighting
1531 end
1532 miscSkyCC.Enabled = true
1533 miscSkyCC.TintColor = Color3.new(
1534 0.55 + c.R * 0.45,
1535 0.55 + c.G * 0.45,
1536 0.55 + c.B * 0.45
1537 )
1538 miscSkyCC.Brightness = 0
1539 miscSkyCC.Contrast = 0.05
1540 miscSkyCC.Saturation = 0.1
1541 else
1542 if miscSkyCC then
1543 pcall(function() miscSkyCC:Destroy() end)
1544 miscSkyCC = nil
1545 end
1546 if miscAtm and miscAtm.Parent then
1547 pcall(function()
1548 miscAtm.Density = 0
1549 miscAtm.Haze = 0
1550 end)
1551 end
1552 end
1553end
1554
1555pcall(function()
1556 RunService:UnbindFromRenderStep(BIND_NAME)
1557end)
1558
1559-- Heartbeat is cheaper than Camera-priority RenderStep for overlays
1560trackConn(RunService.Heartbeat:Connect(function()
1561 if not alive then return end
1562 frameId += 1
1563 camCache = workspace.CurrentCamera
1564 if not camCache then return end
1565
1566 if not Settings.Enabled then
1567 if frameId % 10 == 0 then
1568 for _, entry in pairs(tracked) do
1569 hideDrawings(entry)
1570 end
1571 end
1572 return
1573 end
1574
1575 if playerListDirty then
1576 rebuildPlayerList()
1577 end
1578
1579 -- Catch late joiners if PlayerAdded was missed
1580 if frameId % 90 == 0 then
1581 for _, player in ipairs(Players:GetPlayers()) do
1582 if player ~= LocalPlayer and not tracked[player] then
1583 hookPlayer(player)
1584 end
1585 end
1586 if playerListDirty then
1587 rebuildPlayerList()
1588 end
1589 end
1590
1591 local n = #playerList
1592 if n == 0 then return end
1593
1594 -- Stagger: process ~half the roster each frame when crowded
1595 local step = (n > 12) and 2 or 1
1596 local start = ((frameId - 1) % step) + 1
1597 for i = start, n, step do
1598 local player = playerList[i]
1599 local entry = tracked[player]
1600 if entry then
1601 updatePlayer(player, entry)
1602 end
1603 end
1604end))
1605
1606----------------------------------------------------------------
1607-- Menu (DEDE HUB)
1608----------------------------------------------------------------
1609local Theme = {
1610 Bg = Color3.fromRGB(18, 18, 20),
1611 Sidebar = Color3.fromRGB(22, 22, 24),
1612 Card = Color3.fromRGB(28, 28, 32),
1613 NavIdle = Color3.fromRGB(22, 22, 24),
1614 NavActive = Color3.fromRGB(40, 40, 44),
1615 Text = Color3.fromRGB(245, 245, 247),
1616 Muted = Color3.fromRGB(150, 150, 160),
1617 Section = Color3.fromRGB(120, 120, 130),
1618 Accent = Settings.MenuAccent,
1619 ToggleOff = Color3.fromRGB(55, 55, 62),
1620 Stroke = Color3.fromRGB(45, 45, 52),
1621}
1622
1623local themeRefreshers = {}
1624
1625local gui = Instance.new("ScreenGui")
1626gui.Name = GUI_NAME
1627gui.ResetOnSpawn = false
1628gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
1629gui.IgnoreGuiInset = true
1630gui.DisplayOrder = math.random(40, 90)
1631gui:SetAttribute("_sid", true)
1632protect(gui)
1633gui.Parent = uiParent
1634
1635local window = Instance.new("Frame")
1636window.Name = rndName("w")
1637window.AnchorPoint = Vector2.new(0.5, 0.5)
1638window.Position = UDim2.fromScale(0.5, 0.5)
1639window.Size = UDim2.fromOffset(720, 420)
1640window.BackgroundColor3 = Theme.Bg
1641window.BackgroundTransparency = 0.06
1642window.BorderSizePixel = 0
1643window.Parent = gui
1644
1645local windowCorner = Instance.new("UICorner")
1646windowCorner.CornerRadius = UDim.new(0, 14)
1647windowCorner.Parent = window
1648
1649local windowStroke = Instance.new("UIStroke")
1650windowStroke.Color = Theme.Stroke
1651windowStroke.Thickness = 1
1652windowStroke.Transparency = 0.25
1653windowStroke.Parent = window
1654
1655local accentBar = Instance.new("Frame")
1656accentBar.Name = rndName("ab")
1657accentBar.BorderSizePixel = 0
1658accentBar.BackgroundColor3 = Theme.Accent
1659accentBar.Size = UDim2.new(1, 0, 0, 3)
1660accentBar.Position = UDim2.fromOffset(0, 0)
1661accentBar.ZIndex = 25
1662accentBar.Parent = window
1663
1664local accentBarCorner = Instance.new("UICorner")
1665accentBarCorner.CornerRadius = UDim.new(0, 14)
1666accentBarCorner.Parent = accentBar
1667
1668-- Soft shadow
1669local shadow = Instance.new("ImageLabel")
1670shadow.Name = rndName("sh")
1671shadow.BackgroundTransparency = 1
1672shadow.Image = "rbxassetid://5028857084"
1673shadow.ImageColor3 = Color3.new(0, 0, 0)
1674shadow.ImageTransparency = 0.45
1675shadow.ScaleType = Enum.ScaleType.Slice
1676shadow.SliceCenter = Rect.new(24, 24, 276, 276)
1677shadow.Size = UDim2.new(1, 36, 1, 36)
1678shadow.Position = UDim2.fromOffset(-18, -14)
1679shadow.ZIndex = 0
1680shadow.Parent = window
1681
1682-- Drag handle (top bar across window)
1683local dragBar = Instance.new("TextButton")
1684dragBar.Name = rndName("dg")
1685dragBar.BackgroundTransparency = 1
1686dragBar.Size = UDim2.new(1, 0, 0, 36)
1687dragBar.Position = UDim2.fromOffset(0, 0)
1688dragBar.Text = ""
1689dragBar.ZIndex = 20
1690dragBar.Parent = window
1691
1692do
1693 local dragging = false
1694 local dragStart, startPos
1695
1696 dragBar.InputBegan:Connect(function(input)
1697 if input.UserInputType == Enum.UserInputType.MouseButton1
1698 or input.UserInputType == Enum.UserInputType.Touch then
1699 dragging = true
1700 dragStart = input.Position
1701 startPos = window.Position
1702 end
1703 end)
1704
1705 trackConn(UserInputService.InputChanged:Connect(function(input)
1706 if not dragging then return end
1707 if input.UserInputType == Enum.UserInputType.MouseMovement
1708 or input.UserInputType == Enum.UserInputType.Touch then
1709 local delta = input.Position - dragStart
1710 window.Position = UDim2.new(
1711 startPos.X.Scale, startPos.X.Offset + delta.X,
1712 startPos.Y.Scale, startPos.Y.Offset + delta.Y
1713 )
1714 end
1715 end))
1716
1717 trackConn(UserInputService.InputEnded:Connect(function(input)
1718 if input.UserInputType == Enum.UserInputType.MouseButton1
1719 or input.UserInputType == Enum.UserInputType.Touch then
1720 dragging = false
1721 end
1722 end))
1723end
1724
1725-- Sidebar
1726local sidebar = Instance.new("Frame")
1727sidebar.Name = rndName("sb")
1728sidebar.Size = UDim2.new(0, 168, 1, 0)
1729sidebar.BackgroundColor3 = Theme.Sidebar
1730sidebar.BackgroundTransparency = 0.15
1731sidebar.BorderSizePixel = 0
1732sidebar.ZIndex = 2
1733sidebar.Parent = window
1734
1735local sidebarCorner = Instance.new("UICorner")
1736sidebarCorner.CornerRadius = UDim.new(0, 14)
1737sidebarCorner.Parent = sidebar
1738
1739local sidebarClip = Instance.new("Frame")
1740sidebarClip.BackgroundColor3 = Theme.Sidebar
1741sidebarClip.BackgroundTransparency = 0.15
1742sidebarClip.BorderSizePixel = 0
1743sidebarClip.Position = UDim2.new(1, -14, 0, 0)
1744sidebarClip.Size = UDim2.new(0, 14, 1, 0)
1745sidebarClip.ZIndex = 2
1746sidebarClip.Parent = sidebar
1747
1748local brand = Instance.new("TextLabel")
1749brand.BackgroundTransparency = 1
1750brand.Position = UDim2.fromOffset(18, 18)
1751brand.Size = UDim2.new(1, -28, 0, 24)
1752brand.Font = Enum.Font.GothamBold
1753brand.TextSize = 16
1754brand.TextXAlignment = Enum.TextXAlignment.Left
1755brand.TextColor3 = Theme.Text
1756brand.ZIndex = 3
1757brand.Parent = sidebar
1758bindLocale(brand, "hub_name")
1759
1760local navList = Instance.new("Frame")
1761navList.BackgroundTransparency = 1
1762navList.Position = UDim2.fromOffset(10, 56)
1763navList.Size = UDim2.new(1, -20, 1, -110)
1764navList.ZIndex = 3
1765navList.Parent = sidebar
1766
1767local navLayout = Instance.new("UIListLayout")
1768navLayout.Padding = UDim.new(0, 4)
1769navLayout.SortOrder = Enum.SortOrder.LayoutOrder
1770navLayout.Parent = navList
1771
1772local pages = {}
1773local navButtons = {}
1774local currentPage = "Vision"
1775
1776local function setPage(name)
1777 currentPage = name
1778 for id, page in pairs(pages) do
1779 page.Visible = (id == name)
1780 end
1781 for id, btn in pairs(navButtons) do
1782 local active = id == name
1783 btn.BackgroundColor3 = active and Theme.NavActive or Theme.NavIdle
1784 btn.BackgroundTransparency = active and 0 or 1
1785 btn.TextColor3 = active and Theme.Text or Theme.Muted
1786 end
1787end
1788
1789local function makeNav(id, labelKey, order, icon)
1790 local btn = Instance.new("TextButton")
1791 btn.Name = rndName("n")
1792 btn.LayoutOrder = order
1793 btn.Size = UDim2.new(1, 0, 0, 34)
1794 btn.BackgroundColor3 = Theme.NavIdle
1795 btn.BackgroundTransparency = 1
1796 btn.AutoButtonColor = false
1797 btn.Font = Enum.Font.Gotham
1798 btn.TextSize = 13
1799 btn.TextXAlignment = Enum.TextXAlignment.Left
1800 btn.TextColor3 = Theme.Muted
1801 btn.ZIndex = 4
1802 btn.Parent = navList
1803 bindLocale(btn, labelKey, { icon = icon })
1804
1805 local c = Instance.new("UICorner")
1806 c.CornerRadius = UDim.new(0, 8)
1807 c.Parent = btn
1808
1809 btn.MouseButton1Click:Connect(function()
1810 setPage(id)
1811 end)
1812
1813 navButtons[id] = btn
1814 return btn
1815end
1816
1817makeNav("Vision", "nav_vision", 1, "◇")
1818makeNav("Entities", "nav_entities", 2, "◎")
1819makeNav("Misc", "nav_misc", 3, "✦")
1820
1821local settingsNav = Instance.new("TextButton")
1822settingsNav.Name = rndName("n")
1823settingsNav.AutoButtonColor = false
1824settingsNav.BackgroundColor3 = Theme.NavIdle
1825settingsNav.BackgroundTransparency = 1
1826settingsNav.Position = UDim2.new(0, 10, 1, -42)
1827settingsNav.Size = UDim2.new(1, -20, 0, 34)
1828settingsNav.Font = Enum.Font.Gotham
1829settingsNav.TextSize = 13
1830settingsNav.TextXAlignment = Enum.TextXAlignment.Left
1831settingsNav.TextColor3 = Theme.Muted
1832settingsNav.ZIndex = 4
1833settingsNav.Parent = sidebar
1834bindLocale(settingsNav, "nav_settings", { icon = "⚙" })
1835
1836local settingsNavCorner = Instance.new("UICorner")
1837settingsNavCorner.CornerRadius = UDim.new(0, 8)
1838settingsNavCorner.Parent = settingsNav
1839
1840settingsNav.MouseButton1Click:Connect(function()
1841 setPage("Settings")
1842end)
1843navButtons["Settings"] = settingsNav
1844
1845-- Content
1846local content = Instance.new("Frame")
1847content.Name = rndName("ct")
1848content.BackgroundTransparency = 1
1849content.Position = UDim2.fromOffset(168, 36)
1850content.Size = UDim2.new(1, -180, 1, -48)
1851content.ZIndex = 2
1852content.Parent = window
1853
1854local function makePage(id)
1855 local page = Instance.new("ScrollingFrame")
1856 page.Name = rndName("p")
1857 page.BackgroundTransparency = 1
1858 page.BorderSizePixel = 0
1859 page.Size = UDim2.fromScale(1, 1)
1860 page.CanvasSize = UDim2.fromOffset(0, 0)
1861 page.AutomaticCanvasSize = Enum.AutomaticSize.Y
1862 page.ScrollBarThickness = 3
1863 page.ScrollBarImageColor3 = Theme.Muted
1864 page.Visible = false
1865 page.ZIndex = 3
1866 page.Parent = content
1867
1868 local pad = Instance.new("UIPadding")
1869 pad.PaddingLeft = UDim.new(0, 8)
1870 pad.PaddingRight = UDim.new(0, 8)
1871 pad.PaddingTop = UDim.new(0, 4)
1872 pad.PaddingBottom = UDim.new(0, 12)
1873 pad.Parent = page
1874
1875 local layout = Instance.new("UIListLayout")
1876 layout.Padding = UDim.new(0, 18)
1877 layout.SortOrder = Enum.SortOrder.LayoutOrder
1878 layout.Parent = page
1879
1880 pages[id] = page
1881 return page
1882end
1883
1884local function sectionHeader(parent, titleKey, subKey, order)
1885 local wrap = Instance.new("Frame")
1886 wrap.BackgroundTransparency = 1
1887 wrap.Size = UDim2.new(1, 0, 0, subKey and 36 or 20)
1888 wrap.LayoutOrder = order
1889 wrap.ZIndex = 4
1890 wrap.Parent = parent
1891
1892 local h = Instance.new("TextLabel")
1893 h.BackgroundTransparency = 1
1894 h.Size = UDim2.new(1, 0, 0, 16)
1895 h.Font = Enum.Font.GothamBold
1896 h.TextSize = 11
1897 h.TextXAlignment = Enum.TextXAlignment.Left
1898 h.TextColor3 = Theme.Section
1899 h.ZIndex = 5
1900 h.Parent = wrap
1901 bindLocale(h, titleKey, { upper = true })
1902
1903 if subKey then
1904 local s = Instance.new("TextLabel")
1905 s.BackgroundTransparency = 1
1906 s.Position = UDim2.fromOffset(0, 16)
1907 s.Size = UDim2.new(1, 0, 0, 16)
1908 s.Font = Enum.Font.Gotham
1909 s.TextSize = 11
1910 s.TextXAlignment = Enum.TextXAlignment.Left
1911 s.TextColor3 = Theme.Muted
1912 s.ZIndex = 5
1913 s.Parent = wrap
1914 bindLocale(s, subKey)
1915 end
1916
1917 return wrap
1918end
1919
1920local function makeToggleRow(parent, labelKey, key, descKey, order, onChange)
1921 local row = Instance.new("TextButton")
1922 row.Name = rndName("tg")
1923 row.AutoButtonColor = false
1924 row.BackgroundTransparency = 1
1925 row.Size = UDim2.new(1, 0, 0, descKey and 44 or 32)
1926 row.LayoutOrder = order
1927 row.Text = ""
1928 row.ZIndex = 4
1929 row.Parent = parent
1930
1931 local nameLbl = Instance.new("TextLabel")
1932 nameLbl.BackgroundTransparency = 1
1933 nameLbl.Size = UDim2.new(1, -64, 0, 18)
1934 nameLbl.Position = UDim2.fromOffset(0, descKey and 2 or 7)
1935 nameLbl.Font = Enum.Font.Gotham
1936 nameLbl.TextSize = 13
1937 nameLbl.TextXAlignment = Enum.TextXAlignment.Left
1938 nameLbl.TextColor3 = Theme.Text
1939 nameLbl.ZIndex = 5
1940 nameLbl.Parent = row
1941 bindLocale(nameLbl, labelKey)
1942
1943 if descKey then
1944 local d = Instance.new("TextLabel")
1945 d.BackgroundTransparency = 1
1946 d.Position = UDim2.fromOffset(0, 22)
1947 d.Size = UDim2.new(1, -64, 0, 16)
1948 d.Font = Enum.Font.Gotham
1949 d.TextSize = 11
1950 d.TextXAlignment = Enum.TextXAlignment.Left
1951 d.TextColor3 = Theme.Muted
1952 d.ZIndex = 5
1953 d.Parent = row
1954 bindLocale(d, descKey)
1955 end
1956
1957 local track = Instance.new("Frame")
1958 track.AnchorPoint = Vector2.new(1, 0.5)
1959 track.Position = UDim2.new(1, -2, 0.5, 0)
1960 track.Size = UDim2.fromOffset(42, 24)
1961 track.BackgroundColor3 = Theme.ToggleOff
1962 track.BorderSizePixel = 0
1963 track.ZIndex = 5
1964 track.Parent = row
1965
1966 local trackCorner = Instance.new("UICorner")
1967 trackCorner.CornerRadius = UDim.new(1, 0)
1968 trackCorner.Parent = track
1969
1970 local knob = Instance.new("Frame")
1971 knob.Size = UDim2.fromOffset(18, 18)
1972 knob.Position = UDim2.fromOffset(3, 3)
1973 knob.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
1974 knob.BorderSizePixel = 0
1975 knob.ZIndex = 6
1976 knob.Parent = track
1977
1978 local knobCorner = Instance.new("UICorner")
1979 knobCorner.CornerRadius = UDim.new(1, 0)
1980 knobCorner.Parent = knob
1981
1982 local function refresh()
1983 local on = Settings[key] == true
1984 track.BackgroundColor3 = on and Theme.Accent or Theme.ToggleOff
1985 knob.Position = on and UDim2.fromOffset(21, 3) or UDim2.fromOffset(3, 3)
1986 end
1987
1988 row.MouseButton1Click:Connect(function()
1989 Settings[key] = not Settings[key]
1990 refresh()
1991 if onChange then
1992 onChange(Settings[key])
1993 end
1994 end)
1995
1996 themeRefreshers[#themeRefreshers + 1] = refresh
1997 refresh()
1998 return row
1999end
2000
2001local function applyMenuTheme(accent)
2002 Settings.MenuAccent = accent
2003 Theme.Accent = accent
2004 Theme.Stroke = Color3.new(
2005 math.clamp(accent.R * 0.25 + 0.14, 0, 1),
2006 math.clamp(accent.G * 0.25 + 0.14, 0, 1),
2007 math.clamp(accent.B * 0.25 + 0.16, 0, 1)
2008 )
2009 Theme.NavActive = Color3.new(
2010 math.clamp(accent.R * 0.18 + 0.12, 0, 1),
2011 math.clamp(accent.G * 0.18 + 0.12, 0, 1),
2012 math.clamp(accent.B * 0.18 + 0.14, 0, 1)
2013 )
2014
2015 if accentBar then
2016 accentBar.BackgroundColor3 = accent
2017 end
2018 if windowStroke then
2019 windowStroke.Color = Theme.Stroke
2020 end
2021
2022 -- Refresh active nav highlight + toggles
2023 if currentPage and setPage then
2024 setPage(currentPage)
2025 end
2026 for i = 1, #themeRefreshers do
2027 pcall(themeRefreshers[i])
2028 end
2029end
2030
2031local function makeColorRow(parent, titleKey, getColor, setColor, order)
2032 local wrap = Instance.new("Frame")
2033 wrap.BackgroundTransparency = 1
2034 wrap.Size = UDim2.new(1, 0, 0, 56)
2035 wrap.LayoutOrder = order
2036 wrap.ZIndex = 4
2037 wrap.Parent = parent
2038
2039 local label = Instance.new("TextLabel")
2040 label.BackgroundTransparency = 1
2041 label.Size = UDim2.new(1, -40, 0, 18)
2042 label.Font = Enum.Font.Gotham
2043 label.TextSize = 13
2044 label.TextXAlignment = Enum.TextXAlignment.Left
2045 label.TextColor3 = Theme.Text
2046 label.ZIndex = 5
2047 label.Parent = wrap
2048 bindLocale(label, titleKey)
2049
2050 local preview = Instance.new("Frame")
2051 preview.AnchorPoint = Vector2.new(1, 0)
2052 preview.Position = UDim2.new(1, 0, 0, 0)
2053 preview.Size = UDim2.fromOffset(22, 22)
2054 preview.BackgroundColor3 = getColor()
2055 preview.BorderSizePixel = 0
2056 preview.ZIndex = 5
2057 preview.Parent = wrap
2058 local pc = Instance.new("UICorner")
2059 pc.CornerRadius = UDim.new(0, 6)
2060 pc.Parent = preview
2061
2062 local row = Instance.new("Frame")
2063 row.BackgroundTransparency = 1
2064 row.Position = UDim2.fromOffset(0, 28)
2065 row.Size = UDim2.new(1, 0, 0, 24)
2066 row.ZIndex = 5
2067 row.Parent = wrap
2068
2069 local list = Instance.new("UIListLayout")
2070 list.FillDirection = Enum.FillDirection.Horizontal
2071 list.Padding = UDim.new(0, 6)
2072 list.Parent = row
2073
2074 for i = 1, #COLOR_PRESETS do
2075 local preset = COLOR_PRESETS[i]
2076 local sw = Instance.new("TextButton")
2077 sw.AutoButtonColor = false
2078 sw.Text = ""
2079 sw.Size = UDim2.fromOffset(22, 22)
2080 sw.BackgroundColor3 = preset.color
2081 sw.BorderSizePixel = 0
2082 sw.ZIndex = 6
2083 sw.Parent = row
2084 local sc = Instance.new("UICorner")
2085 sc.CornerRadius = UDim.new(0, 6)
2086 sc.Parent = sw
2087 local ss = Instance.new("UIStroke")
2088 ss.Thickness = 1
2089 ss.Color = Color3.fromRGB(255, 255, 255)
2090 ss.Transparency = 0.7
2091 ss.Parent = sw
2092 sw.MouseButton1Click:Connect(function()
2093 setColor(preset.color)
2094 preview.BackgroundColor3 = preset.color
2095 end)
2096 end
2097
2098 return wrap
2099end
2100
2101local function twoColumn(parent, order)
2102 local wrap = Instance.new("Frame")
2103 wrap.BackgroundTransparency = 1
2104 wrap.Size = UDim2.new(1, 0, 0, 0)
2105 wrap.AutomaticSize = Enum.AutomaticSize.Y
2106 wrap.LayoutOrder = order
2107 wrap.ZIndex = 4
2108 wrap.Parent = parent
2109
2110 local left = Instance.new("Frame")
2111 left.BackgroundTransparency = 1
2112 left.Size = UDim2.new(0.5, -10, 0, 0)
2113 left.AutomaticSize = Enum.AutomaticSize.Y
2114 left.ZIndex = 5
2115 left.Parent = wrap
2116
2117 local leftLayout = Instance.new("UIListLayout")
2118 leftLayout.Padding = UDim.new(0, 6)
2119 leftLayout.Parent = left
2120
2121 local right = Instance.new("Frame")
2122 right.BackgroundTransparency = 1
2123 right.Position = UDim2.new(0.5, 10, 0, 0)
2124 right.Size = UDim2.new(0.5, -10, 0, 0)
2125 right.AutomaticSize = Enum.AutomaticSize.Y
2126 right.ZIndex = 5
2127 right.Parent = wrap
2128
2129 local rightLayout = Instance.new("UIListLayout")
2130 rightLayout.Padding = UDim.new(0, 6)
2131 rightLayout.Parent = right
2132
2133 local function syncHeight()
2134 wrap.Size = UDim2.new(1, 0, 0, math.max(left.AbsoluteSize.Y, right.AbsoluteSize.Y))
2135 end
2136 left:GetPropertyChangedSignal("AbsoluteSize"):Connect(syncHeight)
2137 right:GetPropertyChangedSignal("AbsoluteSize"):Connect(syncHeight)
2138
2139 return left, right
2140end
2141
2142-- Vision page
2143local visionPage = makePage("Vision")
2144sectionHeader(visionPage, "sec_esp", "sec_esp_sub", 1)
2145local vLeft, vRight = twoColumn(visionPage, 2)
2146makeToggleRow(vLeft, "tog_skeleton", "Skeleton", "tog_skeleton_desc", 1)
2147makeToggleRow(vLeft, "tog_box", "Box", "tog_box_desc", 2)
2148makeToggleRow(vLeft, "tog_health", "Health", "tog_health_desc", 3)
2149makeToggleRow(vRight, "tog_name", "Name", "tog_name_desc", 1)
2150makeToggleRow(vRight, "tog_glow", "Glow", "tog_glow_desc", 2)
2151
2152sectionHeader(visionPage, "sec_filters", nil, 3)
2153local fLeft = Instance.new("Frame")
2154fLeft.BackgroundTransparency = 1
2155fLeft.Size = UDim2.new(0.5, -10, 0, 0)
2156fLeft.AutomaticSize = Enum.AutomaticSize.Y
2157fLeft.LayoutOrder = 4
2158fLeft.Parent = visionPage
2159local fLayout = Instance.new("UIListLayout")
2160fLayout.Padding = UDim.new(0, 6)
2161fLayout.Parent = fLeft
2162makeToggleRow(fLeft, "tog_teammates", "ShowTeammates", "tog_teammates_desc", 1)
2163makeToggleRow(fLeft, "tog_master", "Enabled", "tog_master_desc", 2)
2164
2165-- Entities page
2166local entitiesPage = makePage("Entities")
2167sectionHeader(entitiesPage, "sec_players", "sec_players_sub", 1)
2168local eLeft, eRight = twoColumn(entitiesPage, 2)
2169makeToggleRow(eLeft, "tog_teammates", "ShowTeammates", "tog_teammates_ent_desc", 1)
2170makeToggleRow(eRight, "tog_master", "Enabled", "tog_master_ent_desc", 1)
2171
2172-- Misc page
2173local miscPage = makePage("Misc")
2174sectionHeader(miscPage, "sec_protection", "sec_protection_sub", 1)
2175local mLeft, mRight = twoColumn(miscPage, 2)
2176makeToggleRow(mLeft, "tog_antiflash", "AntiFlash", "tog_antiflash_desc", 1, function(on)
2177 setAntiFlash(on)
2178end)
2179makeToggleRow(mRight, "tog_smoke", "RemoveSmoke", "tog_smoke_desc", 1, function(on)
2180 setRemoveSmoke(on)
2181end)
2182
2183sectionHeader(miscPage, "sec_world", "sec_world_sub", 3)
2184local wLeft, wRight = twoColumn(miscPage, 4)
2185makeToggleRow(wLeft, "tog_env", "CustomEnv", "tog_env_desc", 1, function()
2186 applyEnvColor()
2187end)
2188makeToggleRow(wRight, "tog_sky", "CustomSky", "tog_sky_desc", 1, function()
2189 applySkyColor()
2190end)
2191
2192makeColorRow(miscPage, "color_env", function()
2193 return Settings.EnvColor
2194end, function(c)
2195 Settings.EnvColor = c
2196 if Settings.CustomEnv then applyEnvColor() end
2197end, 5)
2198
2199makeColorRow(miscPage, "color_sky", function()
2200 return Settings.SkyColor
2201end, function(c)
2202 Settings.SkyColor = c
2203 if Settings.CustomSky then applySkyColor() end
2204end, 6)
2205
2206sectionHeader(miscPage, "sec_esp_colors", "sec_esp_colors_sub", 7)
2207makeColorRow(miscPage, "color_enemy", function()
2208 return Settings.EnemyColor
2209end, function(c)
2210 Settings.EnemyColor = c
2211end, 8)
2212
2213makeColorRow(miscPage, "color_team", function()
2214 return Settings.TeamColor
2215end, function(c)
2216 Settings.TeamColor = c
2217end, 9)
2218
2219-- Settings page
2220local settingsPage = makePage("Settings")
2221sectionHeader(settingsPage, "sec_interface", "sec_interface_sub", 1)
2222local tip = Instance.new("TextLabel")
2223tip.BackgroundTransparency = 1
2224tip.Size = UDim2.new(1, 0, 0, 60)
2225tip.LayoutOrder = 2
2226tip.Font = Enum.Font.Gotham
2227tip.TextSize = 13
2228tip.TextXAlignment = Enum.TextXAlignment.Left
2229tip.TextYAlignment = Enum.TextYAlignment.Top
2230tip.TextColor3 = Theme.Muted
2231tip.TextWrapped = true
2232tip.ZIndex = 5
2233tip.Parent = settingsPage
2234bindLocale(tip, "tip_controls")
2235
2236sectionHeader(settingsPage, "sec_appearance", "sec_appearance_sub", 3)
2237makeColorRow(settingsPage, "color_menu", function()
2238 return Settings.MenuAccent
2239end, function(c)
2240 applyMenuTheme(c)
2241end, 4)
2242
2243sectionHeader(settingsPage, "sec_language", "sec_language_sub", 5)
2244local langRow = Instance.new("Frame")
2245langRow.BackgroundTransparency = 1
2246langRow.Size = UDim2.new(1, 0, 0, 34)
2247langRow.LayoutOrder = 6
2248langRow.ZIndex = 4
2249langRow.Parent = settingsPage
2250
2251local langLayout = Instance.new("UIListLayout")
2252langLayout.FillDirection = Enum.FillDirection.Horizontal
2253langLayout.Padding = UDim.new(0, 8)
2254langLayout.Parent = langRow
2255
2256local langButtons = {}
2257local function refreshLangButtons()
2258 for code, btn in pairs(langButtons) do
2259 local on = code == currentLanguage
2260 btn.BackgroundColor3 = on and Theme.Accent or Color3.fromRGB(32, 32, 38)
2261 btn.TextColor3 = on and Color3.fromRGB(255, 255, 255) or Theme.Muted
2262 end
2263end
2264
2265for i = 1, #LANGUAGE_OPTIONS do
2266 local opt = LANGUAGE_OPTIONS[i]
2267 local btn = Instance.new("TextButton")
2268 btn.AutoButtonColor = false
2269 btn.Size = UDim2.fromOffset(110, 32)
2270 btn.BackgroundColor3 = Color3.fromRGB(32, 32, 38)
2271 btn.BorderSizePixel = 0
2272 btn.Font = Enum.Font.Gotham
2273 btn.TextSize = 12
2274 btn.Text = opt.label
2275 btn.TextColor3 = Theme.Muted
2276 btn.ZIndex = 5
2277 btn.Parent = langRow
2278 local bc = Instance.new("UICorner")
2279 bc.CornerRadius = UDim.new(0, 8)
2280 bc.Parent = btn
2281 langButtons[opt.code] = btn
2282 btn.MouseButton1Click:Connect(function()
2283 setLanguage(opt.code)
2284 refreshLangButtons()
2285 end)
2286end
2287refreshLangButtons()
2288themeRefreshers[#themeRefreshers + 1] = refreshLangButtons
2289
2290sectionHeader(settingsPage, "sec_session", "sec_session_sub", 7)
2291
2292local destroying = false
2293local function destroyAll()
2294 if destroying then return end
2295 destroying = true
2296 alive = false
2297
2298 pcall(function() RunService:UnbindFromRenderStep(BIND_NAME) end)
2299
2300 Settings.Enabled = false
2301 Settings.CustomEnv = false
2302 Settings.CustomSky = false
2303 Settings.RemoveSmoke = false
2304 Settings.AntiFlash = false
2305
2306 pcall(applyEnvColor)
2307 pcall(applySkyColor)
2308 pcall(function() setRemoveSmoke(false) end)
2309 pcall(function() setAntiFlash(false) end)
2310
2311 if miscAtm then pcall(function() miscAtm:Destroy() end) miscAtm = nil end
2312 if miscSkyCC then pcall(function() miscSkyCC:Destroy() end) miscSkyCC = nil end
2313
2314 for player in pairs(tracked) do
2315 pcall(removePlayer, player)
2316 end
2317 table.clear(tracked)
2318
2319 for i = 1, #connections do
2320 pcall(function() connections[i]:Disconnect() end)
2321 end
2322 table.clear(connections)
2323
2324 pcall(function()
2325 if gui then gui:Destroy() end
2326 end)
2327 pcall(function()
2328 if holder then holder:Destroy() end
2329 end)
2330end
2331
2332local destroyBtn = Instance.new("TextButton")
2333destroyBtn.Name = rndName("x")
2334destroyBtn.LayoutOrder = 8
2335destroyBtn.Size = UDim2.new(1, 0, 0, 44)
2336destroyBtn.BackgroundColor3 = Color3.fromRGB(160, 45, 55)
2337destroyBtn.AutoButtonColor = false
2338destroyBtn.Font = Enum.Font.GothamBold
2339destroyBtn.TextSize = 14
2340destroyBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
2341destroyBtn.ZIndex = 5
2342destroyBtn.Parent = settingsPage
2343bindLocale(destroyBtn, "btn_destroy")
2344
2345local destroyCorner = Instance.new("UICorner")
2346destroyCorner.CornerRadius = UDim.new(0, 10)
2347destroyCorner.Parent = destroyBtn
2348
2349local destroyStroke = Instance.new("UIStroke")
2350destroyStroke.Color = Color3.fromRGB(220, 80, 90)
2351destroyStroke.Thickness = 1
2352destroyStroke.Transparency = 0.4
2353destroyStroke.Parent = destroyBtn
2354
2355destroyBtn.MouseEnter:Connect(function()
2356 if destroying then return end
2357 destroyBtn.BackgroundColor3 = Color3.fromRGB(190, 55, 65)
2358end)
2359destroyBtn.MouseLeave:Connect(function()
2360 if destroying then return end
2361 destroyBtn.BackgroundColor3 = Color3.fromRGB(160, 45, 55)
2362end)
2363
2364destroyBtn.MouseButton1Click:Connect(function()
2365 destroyBtn.Text = t("btn_closing")
2366 destroyBtn.BackgroundColor3 = Color3.fromRGB(90, 30, 35)
2367 task.defer(destroyAll)
2368end)
2369
2370setPage("Vision")
2371
2372local menuVisible = true
2373trackConn(UserInputService.InputBegan:Connect(function(input, gameProcessed)
2374 if gameProcessed or not alive then return end
2375 if input.KeyCode == Enum.KeyCode.Delete then
2376 menuVisible = not menuVisible
2377 window.Visible = menuVisible
2378 end
2379end))
2380
2381trackConn(holder.Destroying:Connect(function()
2382 destroyAll()
2383end))