Climb for Eggs! Script – Keyless - Verified script for Climb for Eggs!
Key Required

Climb for Eggs! Script – Keyless

Climb for Eggs!LunaBloxLunaBlox 1.1K views 1.9K executesUpdated Oct 24, 2026
Unrated
00
Lua Script•1612 lines (57526 chars)
--[[
    Climb for Animals Eggs — Toolkit v1.2
    Fly / Noclip / Телепорт в зоны (в т.ч. в самую высокую) / ESP яиц по редкости / Дамп структуры игры
    GUI: Obsidian → Rayfield → встроенное окно (автовыбор; принудительно: getgenv().CFE_GUI = "obsidian"|"rayfield"|"builtin"). RightShift — спрятать/показать окно.
    Повторный запуск сам выгружает прошлую копию.
]]

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CoreGui = game:GetService("CoreGui")

local LP = Players.LocalPlayer
local Camera = Workspace.CurrentCamera
local genv = (getgenv and getgenv()) or _G

if genv.CFE_Unload then pcall(genv.CFE_Unload) end

------------------------------------------------------------
-- КОНФИГ
------------------------------------------------------------
local Config = {
    Alive = true,
    -- движение
    Fly = false,
    FlySpeed = 80,
    Noclip = false,
    TpSpeed = 300,       -- скорость плавного телепорта (стадов/сек)
    TpInstant = false,   -- мгновенный телепорт (быстрее, но заметнее)
    -- ESP яиц
    EggESP = false,
    EggInfo = true,
    EggTracers = false,
    EggMin = "Rare+",
    EggShowUnknown = true,   -- показывать яйца, у которых не удалось прочитать редкость
    EggMaxDist = 2500,       -- дальше этого расстояния (в стадах) яйца не рисуем
}

local Conns = {}
local function bind(signal, fn)
    local c = signal:Connect(fn)
    table.insert(Conns, c)
    return c
end

------------------------------------------------------------
-- ПЕРСОНАЖ
------------------------------------------------------------
local function getChar() return LP.Character end
local function getRoot()
    local c = getChar()
    return c and c:FindFirstChild("HumanoidRootPart")
end
local function getHum()
    local c = getChar()
    return c and c:FindFirstChildOfClass("Humanoid")
end

------------------------------------------------------------
-- ТЕЛЕПОРТ (плавный по умолчанию)
------------------------------------------------------------
local tpToken = 0

local function teleportTo(pos)
    local root = getRoot()
    if not root then return end
    tpToken += 1
    local mine = tpToken
    local target = pos + Vector3.new(0, 5, 0)

    if Config.TpInstant then
        root.CFrame = CFrame.new(target)
        root.AssemblyLinearVelocity = Vector3.zero
        return
    end

    task.spawn(function()
        while Config.Alive and tpToken == mine do
            local r = getRoot()
            if not r then return end
            local delta = target - r.Position
            local dist = delta.Magnitude
            if dist < 3 then break end
            local dt = RunService.Heartbeat:Wait()
            local step = math.min(dist, math.max(Config.TpSpeed, 20) * dt)
            r.CFrame = CFrame.new(r.Position + delta.Unit * step) * (r.CFrame - r.CFrame.Position)
            r.AssemblyLinearVelocity = Vector3.zero
        end
    end)
end

local SavedPos = nil

------------------------------------------------------------
-- FLY (LinearVelocity + AlignOrientation) и NOCLIP
------------------------------------------------------------
local flyObjs = nil
local upHeld, downHeld = false, false

local function stopFly()
    if flyObjs then
        for _, o in pairs(flyObjs) do pcall(function() o:Destroy() end) end
        flyObjs = nil
    end
    local hum = getHum()
    if hum then pcall(function() hum.PlatformStand = false end) end
end

local function startFly()
    stopFly()
    local root, hum = getRoot(), getHum()
    if not root or not hum then return end
    local att = Instance.new("Attachment")
    att.Name = "CFE_Att"
    att.Parent = root

    local lv = Instance.new("LinearVelocity")
    lv.Attachment0 = att
    lv.RelativeTo = Enum.ActuatorRelativeTo.World
    lv.MaxForce = math.huge
    lv.VectorVelocity = Vector3.zero
    lv.Parent = root

    local ao = Instance.new("AlignOrientation")
    ao.Mode = Enum.OrientationAlignmentMode.OneAttachment
    ao.Attachment0 = att
    ao.RigidityEnabled = true
    ao.CFrame = root.CFrame.Rotation
    ao.Parent = root

    hum.PlatformStand = true
    flyObjs = { att = att, lv = lv, ao = ao }
end

local function updateFly()
    if not Config.Fly then
        if flyObjs then stopFly() end
        return
    end
    if not flyObjs or not flyObjs.lv.Parent then startFly() end
    if not flyObjs then return end

    local hum = getHum()
    if not hum then return end
    local speed = Config.FlySpeed
    local look = Camera.CFrame.LookVector
    local flatLook = Vector3.new(look.X, 0, look.Z)
    flatLook = flatLook.Magnitude > 0.01 and flatLook.Unit or Vector3.new(0, 0, -1)

    local m = hum.MoveDirection
    local forwardComp = m:Dot(flatLook)
    -- вперёд по взгляду камеры: если смотришь вверх, летишь вверх
    local vel = m * speed + Vector3.new(0, look.Y * forwardComp * speed, 0)

    local up = upHeld or UIS:IsKeyDown(Enum.KeyCode.Space)
    local down = downHeld or UIS:IsKeyDown(Enum.KeyCode.LeftControl) or UIS:IsKeyDown(Enum.KeyCode.LeftShift)
    if up then vel += Vector3.new(0, speed, 0) end
    if down then vel -= Vector3.new(0, speed, 0) end

    flyObjs.lv.VectorVelocity = vel
    flyObjs.ao.CFrame = CFrame.lookAt(Vector3.zero, flatLook)
end

local noclipBackup = {} -- [part] = исходный CanCollide
local function setNoclip(on)
    local c = getChar()
    if not c then return end
    if on then
        for _, p in ipairs(c:GetDescendants()) do
            if p:IsA("BasePart") and p.CanCollide then
                noclipBackup[p] = true
                p.CanCollide = false
            end
        end
    else
        for p in pairs(noclipBackup) do
            if p.Parent then pcall(function() p.CanCollide = true end) end
            noclipBackup[p] = nil
        end
    end
end

bind(RunService.Stepped, function()
    if Config.Alive and Config.Noclip then pcall(setNoclip, true) end
end)

bind(RunService.Heartbeat, function()
    if Config.Alive then pcall(updateFly) end
end)

-- респавн: Fly сам перезапустится на следующем кадре, noclip-кэш чистим
bind(LP.CharacterAdded, function()
    noclipBackup = {}
    flyObjs = nil
end)

------------------------------------------------------------
-- ЗОНЫ: берём из Workspace.Structures.Islands.<Зона>.SpawnEggs (точные координаты из дампа)
------------------------------------------------------------
local ZONE_DEFS = {
    { "Safe Zone", safe = true },
    { "Forest" },
    { "Winter" },
    { "Ocean" },
    { "Desert" },
    { "Crystal Mines" },
    { "Jungle" },
    { "Mystic Isles" },
    { "PreHistoric" },
    { "Divine Heights" },
    { "Celestial" },
    { "Realm of Legends" },
    { "Ocean Abyss" },
    -- Halloween-измерение (лежит далеко в стороне, ТП может не сработать без портала)
    { "Pumpkin Abyss", event = true },
    { "Bone Field", event = true },
    { "Witches Castle", event = true },
}
local Zones = {}        -- { name, pos, event } — в порядке прогрессии
local zoneInfoText = "Нажми «Найти зоны»"

local function child(root, ...)
    local cur = root
    for _, name in ipairs({ ... }) do
        cur = cur and cur:FindFirstChild(name)
    end
    return cur
end

local function normName(s)
    return (s:lower():gsub("[%s_%-]", ""))
end

local function pivotPos(inst)
    if inst:IsA("BasePart") then return inst.Position end
    local ok, cf = pcall(function() return inst:GetPivot() end)
    return ok and cf.Position or nil
end

-- центр и верхняя точка (запасной вариант, если у зоны нет SpawnEggs)
local function boundsOf(inst)
    if inst:IsA("BasePart") then
        return inst.Position, inst.Position.Y + inst.Size.Y / 2
    end
    if inst:IsA("Model") then
        local ok, cf, size = pcall(function() return inst:GetBoundingBox() end)
        if ok and cf then return cf.Position, cf.Position.Y + size.Y / 2 end
    end
    local minV, maxV, n = nil, nil, 0
    for _, d in ipairs(inst:GetDescendants()) do
        if d:IsA("BasePart") then
            local lo = d.Position - d.Size / 2
            local hi = d.Position + d.Size / 2
            minV = minV and Vector3.new(math.min(minV.X, lo.X), math.min(minV.Y, lo.Y), math.min(minV.Z, lo.Z)) or lo
            maxV = maxV and Vector3.new(math.max(maxV.X, hi.X), math.max(maxV.Y, hi.Y), math.max(maxV.Z, hi.Z)) or hi
            n += 1
            if n >= 400 then break end
        end
    end
    if minV then return (minV + maxV) / 2, maxV.Y end
    return nil, nil
end

local function groundAt(center, topY)
    local params = RaycastParams.new()
    params.FilterType = Enum.RaycastFilterType.Exclude
    local ignore = {}
    for _, p in ipairs(Players:GetPlayers()) do
        if p.Character then table.insert(ignore, p.Character) end
    end
    params.FilterDescendantsInstances = ignore
    local from = Vector3.new(center.X, topY + 20, center.Z)
    local res = Workspace:Raycast(from, Vector3.new(0, -(topY - center.Y) * 2 - 2000, 0), params)
    if res then return res.Position end
    return center
end

-- Safe Zone: ищем по имени среди детей и внуков Workspace (так она нормально находилась раньше)
local function safeZonePos()
    local exact, partial
    local function consider(inst)
        if inst:IsA("Folder") or inst:IsA("Model") or inst:IsA("BasePart") then
            local n = normName(inst.Name)
            if n == "safezone" then exact = exact or inst
            elseif n:find("safezone", 1, true) then partial = partial or inst end
        end
    end
    for _, a in ipairs(Workspace:GetChildren()) do
        if a ~= Camera and not Players:GetPlayerFromCharacter(a) then
            consider(a)
            for _, b in ipairs(a:GetChildren()) do consider(b) end
        end
    end
    local node = exact or partial
    if node then
        local c, topY = boundsOf(node)
        if c then return groundAt(c, topY) end
    end
    return nil
end

local function scanZones()
    Zones = {}
    local roots = {
        child(Workspace, "Structures", "Islands"),
        child(Workspace, "HalloweenDimension", "Islands"),
        Workspace:FindFirstChild("SpawnedEggs"),
    }
    local missing = {}
    for _, def in ipairs(ZONE_DEFS) do
        local pos
        if def.safe then
            pos = safeZonePos()
        else
            for _, root in ipairs(roots) do
                local node = root and root:FindFirstChild(def[1])
                if node then
                    local spawn = node:FindFirstChild("SpawnEggs")
                    if spawn then pos = pivotPos(spawn) end
                    if not pos then
                        local c, topY = boundsOf(node)
                        if c then pos = groundAt(c, topY) end
                    end
                    if pos then break end
                end
            end
        end
        if pos then
            table.insert(Zones, { name = def[1], pos = pos, event = def.event })
        else
            table.insert(missing, def[1])
        end
    end
    zoneInfoText = "Найдено зон: " .. #Zones .. " из " .. #ZONE_DEFS
    if #missing > 0 then zoneInfoText = zoneInfoText .. " (не нашёл: " .. table.concat(missing, ", ") .. ")" end
end

-- самая высокая видимая твёрдая деталь (запасной вариант «последней локации»)
local function highestPoint()
    local best, bestY = nil, -math.huge
    local all = Workspace:GetDescendants()
    for i, d in ipairs(all) do
        if i % 3000 == 0 then task.wait() end
        if d:IsA("BasePart") and d.CanCollide and d.Transparency < 0.9
            and d.Size.Magnitude < 1500 and not d:IsDescendantOf(Camera) then
            local m = d:FindFirstAncestorOfClass("Model")
            if not (m and Players:GetPlayerFromCharacter(m)) then
                local top = d.Position.Y + d.Size.Y / 2
                if top > bestY then best, bestY = d, top end
            end
        end
    end
    if best then return Vector3.new(best.Position.X, bestY, best.Position.Z) end
    return nil
end

------------------------------------------------------------
-- ЯЙЦА: настоящие яйца лежат в Workspace.SpawnedEggs.<Зона>.<Животное>.<яйцо>
-- (Nest/EggSpotBottom — пустые гнёзда, SpawnEggs — спавнеры, LimitedEggs — магазин: всё это пропускаем)
------------------------------------------------------------
local RARITY_ORDER = { "Common", "Uncommon", "Rare", "Epic", "Legendary", "Mythic", "Eternal", "Radiant", "Astral", "Royal" }
local RANK = { Unknown = 0 }
for i, n in ipairs(RARITY_ORDER) do RANK[n] = i end
local RARITY_COLOR = {
    Common = Color3.fromRGB(170, 170, 170),
    Uncommon = Color3.fromRGB(90, 210, 110),
    Rare = Color3.fromRGB(70, 150, 255),
    Epic = Color3.fromRGB(180, 90, 255),
    Legendary = Color3.fromRGB(255, 150, 30),
    Mythic = Color3.fromRGB(255, 60, 90),
    Eternal = Color3.fromRGB(0, 230, 230),
    Radiant = Color3.fromRGB(255, 240, 120),
    Astral = Color3.fromRGB(120, 130, 255),
    Royal = Color3.fromRGB(255, 215, 0),
    Unknown = Color3.fromRGB(150, 150, 160),
}
local MIN_OPTIONS = { "Все", "Uncommon+", "Rare+", "Epic+", "Legendary+", "Mythic+", "Eternal+", "Radiant+", "Astral+", "Royal" }
local MIN_THRESHOLD = {
    ["Все"] = 0, ["Uncommon+"] = 2, ["Rare+"] = 3, ["Epic+"] = 4, ["Legendary+"] = 5,
    ["Mythic+"] = 6, ["Eternal+"] = 7, ["Radiant+"] = 8, ["Astral+"] = 9, ["Royal"] = 10,
}
local SPECIAL_WORDS = { "golden", "gold", "diamond", "rainbow", "lava", "hacker", "candy" }

local function isEggName(name)
    local n = name:lower()
    return n:find("egg", 1, true) ~= nil and not n:find("eggplant", 1, true)
end

-- редкость из текста; перебираем с конца, чтобы «Uncommon» не принять за «Common»
local function rarityFromText(t)
    t = tostring(t or ""):lower()
    for i = #RARITY_ORDER, 1, -1 do
        if t:find(RARITY_ORDER[i]:lower(), 1, true) then return RARITY_ORDER[i] end
    end
    return nil
end

local function specialLabel(inst)
    local texts = { inst.Name }
    for _, key in ipairs({ "Mutation", "Type", "Variant" }) do
        local a = inst:GetAttribute(key)
        if a ~= nil then table.insert(texts, tostring(a)) end
    end
    for _, t in ipairs(texts) do
        local l = t:lower()
        for _, w in ipairs(SPECIAL_WORDS) do
            if l:find(w, 1, true) then return w:sub(1, 1):upper() .. w:sub(2) end
        end
    end
    return nil
end

local Eggs = {}  -- [inst] = { zone, animal }
local eggCount = 0

local function insideEgg(inst)
    local p = inst.Parent
    while p and p ~= Workspace do
        if Eggs[p] then return true end
        p = p.Parent
    end
    return false
end

local function tryAddEgg(inst)
    if Eggs[inst] then return end
    if not (inst:IsA("Model") or inst:IsA("BasePart") or inst:IsA("Tool")) then return end
    if not isEggName(inst.Name) then return end
    local n = inst.Name:lower()
    if n:find("spot", 1, true) or n:find("spawn", 1, true) then return end

    local root = Workspace:FindFirstChild("SpawnedEggs")
    local zone, animal
    if root and inst:IsDescendantOf(root) then
        local chain, p = {}, inst
        while p and p ~= root do
            table.insert(chain, 1, p)
            p = p.Parent
        end
        for _, c in ipairs(chain) do
            if c.Name == "Nest" then return end            -- гнёзда пропускаем
        end
        zone = chain[1] and chain[1].Name
        animal = (#chain >= 3) and chain[#chain - 1].Name or nil
    elseif inst.Parent == Workspace and inst:IsA("Model") then
        zone, animal = "Event", inst.Name                   -- одиночные яйца вроде halloweenegg
    else
        return
    end
    if insideEgg(inst) then return end

    Eggs[inst] = { zone = zone, animal = animal }
    eggCount += 1
end

local function removeEgg(inst)
    if Eggs[inst] then
        Eggs[inst] = nil
        eggCount -= 1
    end
end

-- центр яйца: у моделей pivot часто смещён, поэтому берём центр bounding box
local function eggPos(inst)
    if inst:IsA("BasePart") then return inst.Position end
    if inst:IsA("Model") then
        local ok, cf = pcall(function() return inst:GetBoundingBox() end)
        if ok and cf then return cf.Position end
    end
    local ok, cf = pcall(function() return inst:GetPivot() end)
    return ok and cf.Position or nil
end

local function eggAnchorPart(inst)
    if inst:IsA("BasePart") then return inst end
    return inst:FindFirstChildWhichIsA("BasePart", true)
end

-- подписи над яйцами из PlayerGui (там игра сама пишет Rarity / EggName / Mutation)
local BbInfo = {}
local function textOf(inst)
    if inst and inst:IsA("TextLabel") then
        local t = inst.Text:gsub("<[^>]->", "")
        return t
    end
    return nil
end

local function refreshBillboards()
    BbInfo = {}
    local pg = LP:FindFirstChildOfClass("PlayerGui")
    if not pg then return end
    for _, b in ipairs(pg:GetChildren()) do
        if b:IsA("BillboardGui") and b.Adornee then
            local p, egg = b.Adornee, nil
            for _ = 1, 8 do
                if not p or p == Workspace then break end
                if Eggs[p] then egg = p break end
                p = p.Parent
            end
            if egg then
                local mut = textOf(b:FindFirstChild("Mutation", true))
                if mut then
                    local l = mut:lower()
                    if mut == "" or l == "none" or l == "normal" then mut = nil end
                end
                BbInfo[egg] = {
                    rarity = textOf(b:FindFirstChild("Rarity", true)),
                    name = textOf(b:FindFirstChild("EggName", true)),
                    mutation = mut,
                }
            end
        end
    end
end

-- редкость: атрибуты → подпись игры → "Unknown"; возвращает (редкость, подпись особой мутации, приблизительно)
local function eggRarity(inst)
    if not Eggs[inst] then return "Unknown", nil, false end

    local p = inst
    for _ = 1, 4 do
        if not p or p == Workspace then break end
        for _, key in ipairs({ "Rarity", "rarity", "Tier" }) do
            local a = p:GetAttribute(key)
            if a ~= nil then
                local r = rarityFromText(a)
                if r then return r, specialLabel(inst), false end
            end
        end
        local v = p:FindFirstChild("Rarity")
        if v and v:IsA("ValueBase") then
            local r = rarityFromText(v.Value)
            if r then return r, specialLabel(inst), false end
        end
        p = p.Parent
    end

    local bi = BbInfo[inst]
    if bi then
        local r = rarityFromText(bi.rarity)
        if r then return r, bi.mutation or specialLabel(inst), false end
    end

    local lbl = inst:FindFirstChild("Rarity", true)
    if lbl and lbl:IsA("TextLabel") then
        local r = rarityFromText(lbl.Text)
        if r then return r, specialLabel(inst), false end
    end
    return "Unknown", (bi and bi.mutation) or specialLabel(inst), false
end

-- проходит ли яйцо текущий фильтр
local function eggPasses(r, label)
    if r == "Unknown" then return Config.EggShowUnknown or label ~= nil end
    if label then return true end
    return (RANK[r] or 0) >= (MIN_THRESHOLD[Config.EggMin] or 0)
end

local function eggDisplayName(inst)
    local bi = BbInfo[inst]
    if bi and bi.name and bi.name ~= "" then return bi.name end
    local info = Eggs[inst]
    return (info and info.animal) or inst.Name
end

-- первичный скан кусками, дальше следим за появлением/удалением
local scanDone = false
task.spawn(function()
    local root = Workspace:FindFirstChild("SpawnedEggs")
    if root then
        local all = root:GetDescendants()
        for i, d in ipairs(all) do
            if not Config.Alive then return end
            if i % 2000 == 0 then task.wait() end
            pcall(tryAddEgg, d)
        end
    end
    for _, c in ipairs(Workspace:GetChildren()) do pcall(tryAddEgg, c) end
    scanDone = true
end)

bind(Workspace.DescendantAdded, function(d)
    if isEggName(d.Name) then
        task.defer(function() pcall(tryAddEgg, d) end)
    end
end)
bind(Workspace.DescendantRemoving, function(d)
    if Eggs[d] then removeEgg(d) end
end)

------------------------------------------------------------
-- GUI ДЛЯ ОВЕРЛЕЕВ + ESP
------------------------------------------------------------
local okParent, guiParent = pcall(function() return (gethui and gethui()) or CoreGui end)
if not okParent or not guiParent then guiParent = LP:WaitForChild("PlayerGui") end

local gui = Instance.new("ScreenGui")
gui.Name = "CFE_" .. tostring(math.random(1000, 9999))
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.DisplayOrder = 999
gui.Parent = guiParent

local ESP = {} -- [inst] = {hl, bb, label, line}

local function destroyESP(inst)
    local e = ESP[inst]
    if e then
        for _, o in pairs(e) do pcall(function() o:Destroy() end) end
        ESP[inst] = nil
    end
end

local function clearESP()
    for inst in pairs(ESP) do destroyESP(inst) end
end

local MAX_RENDER = 80

task.spawn(function()
    while Config.Alive do
        if not Config.EggESP then
            clearESP()
        else
            pcall(refreshBillboards)
            local root = getRoot()
            local origin = root and root.Position or Camera.CFrame.Position
            local maxD = Config.EggMaxDist

            -- собираем подходящие яйца в радиусе, рисуем только ближайшие
            local list = {}
            for inst, info in pairs(Eggs) do
                if inst.Parent then
                    local pos = eggPos(inst)
                    if pos then
                        local d = (pos - origin).Magnitude
                        if d <= maxD then
                            local r, label = eggRarity(inst)
                            if eggPasses(r, label) then
                                table.insert(list, { inst = inst, pos = pos, r = r, label = label, d = d, info = info })
                            end
                        end
                    end
                end
            end
            table.sort(list, function(a, b) return a.d < b.d end)

            local keep = {}
            for i = 1, math.min(#list, MAX_RENDER) do
                local it = list[i]
                keep[it.inst] = true
                local ok = pcall(function()
                    local e = ESP[it.inst] or {}
                    ESP[it.inst] = e
                    local col = RARITY_COLOR[it.r] or RARITY_COLOR.Unknown

                    if not e.hl or e.hl.Parent == nil then
                        local h = Instance.new("Highlight")
                        h.Adornee = it.inst
                        h.FillTransparency = 0.5
                        h.OutlineColor = Color3.new(1, 1, 1)
                        h.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
                        h.Parent = gui
                        e.hl = h
                    end
                    e.hl.FillColor = col

                    if Config.EggInfo then
                        local part = eggAnchorPart(it.inst)
                        if part then
                            if not e.bb or e.bb.Adornee ~= part then
                                if e.bb then e.bb:Destroy() end
                                local bb = Instance.new("BillboardGui")
                                bb.Adornee = part
                                bb.Size = UDim2.fromOffset(220, 40)
                                bb.StudsOffset = Vector3.new(0, 3, 0)
                                bb.AlwaysOnTop = true
                                bb.Parent = gui
                                local lbl = Instance.new("TextLabel")
                                lbl.Size = UDim2.fromScale(1, 1)
                                lbl.BackgroundTransparency = 1
                                lbl.Font = Enum.Font.GothamBold
                                lbl.TextSize = 13
                                lbl.TextStrokeTransparency = 0.3
                                lbl.Parent = bb
                                e.bb, e.label = bb, lbl
                            end
                            local rName = it.r == "Unknown" and "?" or it.r
                            if it.label then rName = rName .. " · " .. it.label end
                            e.label.Text = string.format("%s\n%s · %s  %dм", rName, eggDisplayName(it.inst), it.info.zone or "?", math.floor(it.d))
                            e.label.TextColor3 = col
                        end
                    elseif e.bb then
                        e.bb:Destroy()
                        e.bb, e.label = nil, nil
                    end

                    if Config.EggTracers then
                        if not e.line then
                            local l = Instance.new("Frame")
                            l.AnchorPoint = Vector2.new(0.5, 0.5)
                            l.BorderSizePixel = 0
                            l.Parent = gui
                            e.line = l
                        end
                        e.line.BackgroundColor3 = col
                        e.pos = it.pos
                    elseif e.line then
                        e.line:Destroy()
                        e.line = nil
                    end
                end)
                if not ok then destroyESP(it.inst) end
            end
            for inst in pairs(ESP) do
                if not keep[inst] then destroyESP(inst) end
            end
        end
        task.wait(0.4)
    end
    clearESP()
end)

local function updateTracers()
    local from = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y)
    for _, e in pairs(ESP) do
        if e.line and e.pos then
            local sp, on = Camera:WorldToViewportPoint(e.pos)
            if on then
                local to = Vector2.new(sp.X, sp.Y)
                local d = to - from
                e.line.Visible = true
                e.line.Size = UDim2.fromOffset(d.Magnitude, 1.5)
                e.line.Position = UDim2.fromOffset((from.X + to.X) / 2, (from.Y + to.Y) / 2)
                e.line.Rotation = math.deg(math.atan2(d.Y, d.X))
            else
                e.line.Visible = false
            end
        end
    end
end

bind(RunService.RenderStepped, function()
    Camera = Workspace.CurrentCamera or Camera
    if Config.EggESP and Config.EggTracers then pcall(updateTracers) end
end)

------------------------------------------------------------
-- ДАМП СТРУКТУРЫ ИГРЫ
------------------------------------------------------------
local function describe(inst)
    local s = inst.Name .. " [" .. inst.ClassName .. "]"
    if inst:IsA("ValueBase") then s = s .. " = " .. tostring(inst.Value) end
    local parts = {}
    for k, v in pairs(inst:GetAttributes()) do parts[#parts + 1] = k .. "=" .. tostring(v) end
    if #parts > 0 then s = s .. " {" .. table.concat(parts, ", ") .. "}" end
    return s
end

local function tree(root, maxDepth, cap, lines, depth, prefix)
    for _, c in ipairs(root:GetChildren()) do
        if #lines >= cap then
            lines[#lines + 1] = prefix .. "... (обрезано)"
            return
        end
        lines[#lines + 1] = prefix .. describe(c)
        if depth < maxDepth then tree(c, maxDepth, cap, lines, depth + 1, prefix .. "  ") end
    end
end

local function makeDump()
    local report = { "CFE DUMP  PlaceId=" .. tostring(game.PlaceId) .. "  " .. os.date("%Y-%m-%d %H:%M:%S") }
    report[#report + 1] = "Экзекьютор: " .. tostring((identifyexecutor and identifyexecutor()) or "unknown")

    local function section(title, root, depth, cap)
        report[#report + 1] = "\n===== " .. title .. " ====="
        if not root then report[#report + 1] = "(нет)" return end
        local lines = {}
        pcall(tree, root, depth, cap, lines, 1, "")
        for _, l in ipairs(lines) do report[#report + 1] = l end
    end

    section("Workspace (глубина 2)", Workspace, 2, 400)
    section("ReplicatedStorage (глубина 3)", ReplicatedStorage, 3, 400)
    section("Мой LocalPlayer", LP, 3, 200)

    report[#report + 1] = "\n===== ЗОНЫ (найденные) ====="
    for _, z in ipairs(Zones) do
        report[#report + 1] = string.format("%s  (%.0f, %.0f, %.0f)", z.name, z.pos.X, z.pos.Y, z.pos.Z)
    end

    report[#report + 1] = "\n===== ЯЙЦА В МИРЕ ====="
    local n = 0
    for inst in pairs(Eggs) do
        n += 1
        if n <= 150 then
            local r, label, approx = eggRarity(inst)
            local pos = eggPos(inst)
            report[#report + 1] = string.format("%s | %s%s%s | %s",
                inst:GetFullName(), r, label and (":" .. label) or "", approx and "~" or "",
                pos and string.format("(%.0f, %.0f, %.0f)", pos.X, pos.Y, pos.Z) or "?")
        end
    end
    report[#report + 1] = "всего: " .. n

    report[#report + 1] = "\n===== РЕМОУТЫ ====="
    local rc = 0
    for i, d in ipairs(game:GetDescendants()) do
        if i % 3000 == 0 then task.wait() end
        if d:IsA("RemoteEvent") or d:IsA("RemoteFunction") or d:IsA("UnreliableRemoteEvent") then
            rc += 1
            if rc <= 250 then report[#report + 1] = d.ClassName .. "  " .. d:GetFullName() end
        end
    end
    report[#report + 1] = "всего ремоутов: " .. rc

    -- расширенный дамп для точной подгонки ESP яиц (редкости, подписи, модули данных)
    report[#report + 1] = "\n===== SpawnedEggs (глубина 4, с атрибутами) ====="
    local se = Workspace:FindFirstChild("SpawnedEggs")
    if se then
        local lines = {}
        pcall(tree, se, 4, 500, lines, 1, "")
        for _, l in ipairs(lines) do report[#report + 1] = l end
    else
        report[#report + 1] = "(нет Workspace.SpawnedEggs)"
    end

    report[#report + 1] = "\n===== BillboardGui в PlayerGui (подписи яиц) ====="
    local pgx = LP:FindFirstChildOfClass("PlayerGui")
    if pgx then
        for _, b in ipairs(pgx:GetChildren()) do
            if b:IsA("BillboardGui") then
                local ad = b.Adornee
                local texts = {}
                for _, d in ipairs(b:GetDescendants()) do
                    if d:IsA("TextLabel") then texts[#texts + 1] = d.Name .. "='" .. d.Text .. "'" end
                end
                report[#report + 1] = "adornee=" .. (ad and ad:GetFullName() or "nil") .. " | " .. table.concat(texts, "; ")
            end
        end
    end

    report[#report + 1] = "\n===== GameConfiguration (значения) ====="
    local gc = child(ReplicatedStorage, "src", "GameConfiguration")
    if gc then
        local lines = {}
        pcall(tree, gc, 4, 300, lines, 1, "")
        for _, l in ipairs(lines) do report[#report + 1] = l end
    end

    report[#report + 1] = "\n===== МОДУЛИ ДАННЫХ (rarityStyle, zones, eggHandler) ====="
    local function ser(v, depth)
        local t = typeof(v)
        if t == "table" then
            if depth > 3 then return "{...}" end
            local parts, n = {}, 0
            for k, val in pairs(v) do
                n += 1
                if n > 40 then parts[#parts + 1] = "..." break end
                parts[#parts + 1] = tostring(k) .. "=" .. ser(val, depth + 1)
            end
            return "{" .. table.concat(parts, ", ") .. "}"
        elseif t == "string" then
            return '"' .. v .. '"'
        end
        return tostring(v)
    end
    for _, mname in ipairs({ "rarityStyle", "zones", "eggHandler" }) do
        local found
        for _, m in ipairs(ReplicatedStorage:GetDescendants()) do
            if m:IsA("ModuleScript") and m.Name == mname then found = m break end
        end
        if found then
            local ok, res = pcall(require, found)
            local s = ok and ser(res, 0) or ("require упал: " .. tostring(res))
            report[#report + 1] = mname .. " = " .. s:sub(1, 3500)
        else
            report[#report + 1] = mname .. ": не найден"
        end
    end

    local text = table.concat(report, "\n")
    local saved = false
    if writefile then saved = pcall(writefile, "CFE_dump.txt", text) end
    local copied = false
    if setclipboard then copied = pcall(setclipboard, text) end
    if not saved and not copied then
        for i = 1, #text, 3500 do print(text:sub(i, i + 3499)) end
    end
    return saved, copied, #text
end


------------------------------------------------------------
-- МЕНЮ: адаптер над GUI-библиотеками (Obsidian → Rayfield → встроенное окно)
-- Принудительно выбрать: getgenv().CFE_GUI = "obsidian" | "rayfield" | "builtin" (до запуска скрипта)
------------------------------------------------------------
local function tryLoad(url)
    local ok, res = pcall(function() return loadstring(game:HttpGet(url))() end)
    if ok and res then return res end
    warn("[CFE] не загрузилось: " .. url .. " — " .. tostring(res))
    return nil
end

-- ===== бэкенд 1: Obsidian =====
local function backendObsidian()
    local Library = tryLoad("https://raw.githubusercontent.com/deividcomsono/Obsidian/main/Library.lua")
    if type(Library) ~= "table" then return nil end
    local Window = Library:CreateWindow({
        Title = "Climb for Eggs",
        Footer = "v1.2",
        NotifySide = "Right",
        ShowCustomCursor = false,
    })
    local B = { name = "Obsidian" }
    local n = 0
    local function newId(prefix)
        n += 1
        return prefix .. n
    end

    function B.tab(name)
        local tab = Window:AddTab(name)
        return { box = tab:AddLeftGroupbox(name) }
    end
    function B.section(t, text)
        t.box:AddLabel("— " .. text .. " —")
    end
    function B.toggle(t, text, key, cb)
        t.box:AddToggle(newId("tg"), {
            Text = text,
            Default = Config[key],
            Callback = function(v)
                Config[key] = v
                if cb then cb(v) end
            end,
        })
    end
    function B.slider(t, text, key, min, max, inc)
        t.box:AddSlider(newId("sl"), {
            Text = text,
            Default = Config[key],
            Min = min,
            Max = max,
            Rounding = inc < 1 and 2 or 0,
            Callback = function(v) Config[key] = v end,
        })
    end
    function B.input(t, text, placeholder, cb)
        t.box:AddInput(newId("in"), {
            Text = text,
            Default = "",
            Placeholder = placeholder or "",
            Finished = true,
            Callback = function(v) cb(v) end,
        })
    end
    function B.button(t, text, fn)
        t.box:AddButton({ Text = text, Func = fn })
    end
    function B.label(t, text)
        local l = t.box:AddLabel(text)
        return function(s) pcall(function() l:SetText(s) end) end
    end
    function B.dropdown(t, text, options, current, cb)
        local id = newId("dd")
        t.box:AddDropdown(id, {
            Text = text,
            Values = options,
            Default = table.find(options, current) or 1,
            Multi = false,
            Callback = function(v) cb(v) end,
        })
        return {
            refresh = function(list) pcall(function() Library.Options[id]:SetValues(list) end) end,
            set = function(v) pcall(function() Library.Options[id]:SetValue(v) end) end,
        }
    end
    function B.notify(title, text)
        local ok = pcall(function() Library:Notify({ Title = title, Description = text, Time = 5 }) end)
        if not ok then pcall(function() Library:Notify(title .. ": " .. text, 5) end) end
    end
    function B.destroy()
        pcall(function() Library:Unload() end)
    end
    return B
end

-- ===== бэкенд 2: Rayfield (два адреса на случай, если один заблокирован) =====
local function backendRayfield()
    local Rayfield = tryLoad("https://sirius.menu/rayfield")
        or tryLoad("https://raw.githubusercontent.com/SiriusSoftwareLtd/Rayfield/main/source.lua")
    if type(Rayfield) ~= "table" then return nil end
    local Window = Rayfield:CreateWindow({
        Name = "Climb for Eggs v1.2",
        LoadingTitle = "Climb for Eggs",
        LoadingSubtitle = "загрузка...",
        ConfigurationSaving = { Enabled = false },
        KeySystem = false,
        DisableRayfieldPrompts = true,
        DisableBuildWarnings = true,
    })
    local B = { name = "Rayfield" }

    function B.tab(name) return Window:CreateTab(name) end
    function B.section(t, text) t:CreateSection(text) end
    function B.toggle(t, text, key, cb)
        t:CreateToggle({
            Name = text,
            CurrentValue = Config[key],
            Callback = function(v)
                Config[key] = v
                if cb then cb(v) end
            end,
        })
    end
    function B.slider(t, text, key, min, max, inc)
        t:CreateSlider({
            Name = text,
            Range = { min, max },
            Increment = inc,
            CurrentValue = Config[key],
            Callback = function(v) Config[key] = v end,
        })
    end
    function B.input(t, text, placeholder, cb)
        t:CreateInput({
            Name = text,
            PlaceholderText = placeholder or "",
            RemoveTextAfterFocusLost = false,
            Callback = cb,
        })
    end
    function B.button(t, text, fn) t:CreateButton({ Name = text, Callback = fn }) end
    function B.label(t, text)
        local l = t:CreateLabel(text)
        return function(s) pcall(function() l:Set(s) end) end
    end
    function B.dropdown(t, text, options, current, cb)
        local d = t:CreateDropdown({
            Name = text,
            Options = options,
            CurrentOption = { current },
            MultipleOptions = false,
            Callback = function(o) cb(type(o) == "table" and o[1] or o) end,
        })
        return {
            refresh = function(list) pcall(function() d:Refresh(list) end) end,
            set = function(v) pcall(function() d:Set({ v }) end) end,
        }
    end
    function B.notify(title, text)
        pcall(function() Rayfield:Notify({ Title = title, Content = text, Duration = 5 }) end)
    end
    function B.destroy()
        pcall(function() Rayfield:Destroy() end)
    end
    return B
end

-- ===== бэкенд 3: встроенное окно (работает без интернета и чужих библиотек) =====
local function backendBuiltin()
    local W, H = 340, 480
    local B = { name = "builtin" }

    local main = Instance.new("Frame")
    main.Size = UDim2.fromOffset(W, H)
    main.Position = UDim2.new(0, 20, 0.5, -H / 2)
    main.BackgroundColor3 = Color3.fromRGB(24, 24, 30)
    main.BorderSizePixel = 0
    main.Parent = gui
    Instance.new("UICorner", main).CornerRadius = UDim.new(0, 8)

    local title = Instance.new("TextLabel")
    title.Size = UDim2.new(1, 0, 0, 32)
    title.BackgroundColor3 = Color3.fromRGB(40, 40, 52)
    title.BorderSizePixel = 0
    title.Text = "  Climb for Eggs v1.2"
    title.TextColor3 = Color3.new(1, 1, 1)
    title.Font = Enum.Font.GothamBold
    title.TextSize = 15
    title.TextXAlignment = Enum.TextXAlignment.Left
    title.Parent = main
    Instance.new("UICorner", title).CornerRadius = UDim.new(0, 8)

    local collapse = Instance.new("TextButton")
    collapse.Size = UDim2.fromOffset(32, 32)
    collapse.Position = UDim2.new(1, -32, 0, 0)
    collapse.BackgroundTransparency = 1
    collapse.Text = "–"
    collapse.TextColor3 = Color3.new(1, 1, 1)
    collapse.Font = Enum.Font.GothamBold
    collapse.TextSize = 18
    collapse.Parent = title

    local tabBar = Instance.new("Frame")
    tabBar.Position = UDim2.fromOffset(5, 35)
    tabBar.Size = UDim2.new(1, -10, 0, 26)
    tabBar.BackgroundTransparency = 1
    tabBar.Parent = main
    local tabLayout = Instance.new("UIListLayout", tabBar)
    tabLayout.FillDirection = Enum.FillDirection.Horizontal
    tabLayout.Padding = UDim.new(0, 4)

    local pages = Instance.new("Frame")
    pages.Position = UDim2.fromOffset(0, 64)
    pages.Size = UDim2.new(1, 0, 1, -64)
    pages.BackgroundTransparency = 1
    pages.ClipsDescendants = true
    pages.Parent = main

    bind(collapse.MouseButton1Click, function()
        local open = not pages.Visible
        pages.Visible = open
        tabBar.Visible = open
        main.Size = open and UDim2.fromOffset(W, H) or UDim2.fromOffset(W, 32)
    end)

    -- перетаскивание за заголовок
    local dragging, dragStart, startPos
    bind(title.InputBegan, function(i)
        if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then
            dragging, dragStart, startPos = true, i.Position, main.Position
        end
    end)
    bind(UIS.InputChanged, function(i)
        if dragging and (i.UserInputType == Enum.UserInputType.MouseMovement or i.UserInputType == Enum.UserInputType.Touch) then
            local d = i.Position - dragStart
            main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)
        end
    end)
    bind(UIS.InputEnded, function(i)
        if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then
            dragging = false
        end
    end)
    bind(UIS.InputBegan, function(i, gp)
        if not gp and i.KeyCode == Enum.KeyCode.RightShift then main.Visible = not main.Visible end
    end)

    -- всплывающая подсказка (вместо уведомлений)
    local toast = Instance.new("TextLabel")
    toast.Size = UDim2.fromOffset(340, 28)
    toast.Position = UDim2.new(0.5, -170, 0, 40)
    toast.BackgroundColor3 = Color3.fromRGB(30, 30, 40)
    toast.BorderSizePixel = 0
    toast.TextColor3 = Color3.new(1, 1, 1)
    toast.Font = Enum.Font.Gotham
    toast.TextSize = 13
    toast.Visible = false
    toast.Parent = gui
    Instance.new("UICorner", toast).CornerRadius = UDim.new(0, 6)
    local toastToken = 0

    -- выпадающий список (общий для всех дропдаунов)
    local popup = Instance.new("ScrollingFrame")
    popup.Position = UDim2.fromOffset(10, 70)
    popup.Size = UDim2.new(1, -20, 0, 260)
    popup.BackgroundColor3 = Color3.fromRGB(18, 18, 24)
    popup.BorderSizePixel = 0
    popup.ScrollBarThickness = 4
    popup.AutomaticCanvasSize = Enum.AutomaticSize.Y
    popup.CanvasSize = UDim2.new()
    popup.ZIndex = 20
    popup.Visible = false
    popup.Parent = main
    Instance.new("UICorner", popup).CornerRadius = UDim.new(0, 6)
    local popLayout = Instance.new("UIListLayout", popup)
    popLayout.Padding = UDim.new(0, 2)

    local function openPopup(options, onPick)
        for _, c in ipairs(popup:GetChildren()) do
            if c:IsA("TextButton") then c:Destroy() end
        end
        for _, opt in ipairs(options) do
            local b = Instance.new("TextButton")
            b.Size = UDim2.new(1, -6, 0, 24)
            b.BackgroundColor3 = Color3.fromRGB(38, 38, 46)
            b.BorderSizePixel = 0
            b.Text = tostring(opt)
            b.TextColor3 = Color3.new(1, 1, 1)
            b.Font = Enum.Font.Gotham
            b.TextSize = 12
            b.TextTruncate = Enum.TextTruncate.AtEnd
            b.ZIndex = 21
            b.Parent = popup
            bind(b.MouseButton1Click, function()
                popup.Visible = false
                onPick(opt)
            end)
        end
        popup.Visible = true
    end

    local tabs, tabButtons = {}, {}
    local function showTab(page)
        popup.Visible = false
        for _, p in ipairs(tabs) do p.Visible = (p == page) end
        for p, b in pairs(tabButtons) do
            b.BackgroundColor3 = (p == page) and Color3.fromRGB(70, 70, 120) or Color3.fromRGB(38, 38, 46)
        end
    end

    local function newRow(page)
        local f = Instance.new("Frame")
        f.Size = UDim2.new(1, -10, 0, 28)
        f.BackgroundColor3 = Color3.fromRGB(38, 38, 46)
        f.BorderSizePixel = 0
        f.Parent = page
        Instance.new("UICorner", f).CornerRadius = UDim.new(0, 6)
        return f
    end

    local function rowLabel(row, text)
        local lbl = Instance.new("TextLabel")
        lbl.Size = UDim2.new(0.5, 0, 1, 0)
        lbl.BackgroundTransparency = 1
        lbl.Text = "  " .. text
        lbl.TextColor3 = Color3.new(1, 1, 1)
        lbl.Font = Enum.Font.Gotham
        lbl.TextSize = 13
        lbl.TextXAlignment = Enum.TextXAlignment.Left
        lbl.TextTruncate = Enum.TextTruncate.AtEnd
        lbl.Parent = row
        return lbl
    end

    local function rowBox(row, text)
        local box = Instance.new("TextBox")
        box.Position = UDim2.new(0.5, 0, 0, 3)
        box.Size = UDim2.new(0.5, -6, 1, -6)
        box.BackgroundColor3 = Color3.fromRGB(20, 20, 26)
        box.BorderSizePixel = 0
        box.Text = text
        box.ClearTextOnFocus = false
        box.TextColor3 = Color3.new(1, 1, 1)
        box.Font = Enum.Font.Gotham
        box.TextSize = 12
        box.Parent = row
        Instance.new("UICorner", box).CornerRadius = UDim.new(0, 4)
        return box
    end

    function B.tab(name)
        local page = Instance.new("ScrollingFrame")
        page.Size = UDim2.fromScale(1, 1)
        page.BackgroundTransparency = 1
        page.BorderSizePixel = 0
        page.ScrollBarThickness = 4
        page.AutomaticCanvasSize = Enum.AutomaticSize.Y
        page.CanvasSize = UDim2.new()
        page.Visible = false
        page.Parent = pages
        local l = Instance.new("UIListLayout", page)
        l.Padding = UDim.new(0, 4)
        l.HorizontalAlignment = Enum.HorizontalAlignment.Center
        local pd = Instance.new("UIPadding", page)
        pd.PaddingTop = UDim.new(0, 2)
        pd.PaddingBottom = UDim.new(0, 6)

        local b = Instance.new("TextButton")
        b.Size = UDim2.new(0, 72, 1, 0)
        b.Text = name
        b.Font = Enum.Font.GothamBold
        b.TextSize = 12
        b.TextColor3 = Color3.new(1, 1, 1)
        b.BorderSizePixel = 0
        b.Parent = tabBar
        Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)
        bind(b.MouseButton1Click, function() showTab(page) end)

        table.insert(tabs, page)
        tabButtons[page] = b
        if #tabs == 1 then showTab(page) else b.BackgroundColor3 = Color3.fromRGB(38, 38, 46) end
        return page
    end

    function B.section(page, text)
        local l = Instance.new("TextLabel")
        l.Size = UDim2.new(1, -10, 0, 20)
        l.BackgroundTransparency = 1
        l.Text = "— " .. text .. " —"
        l.TextColor3 = Color3.fromRGB(150, 150, 190)
        l.Font = Enum.Font.GothamBold
        l.TextSize = 12
        l.Parent = page
    end

    function B.toggle(page, text, key, cb)
        local row = newRow(page)
        local btn = Instance.new("TextButton")
        btn.Size = UDim2.fromScale(1, 1)
        btn.BackgroundTransparency = 1
        btn.TextColor3 = Color3.new(1, 1, 1)
        btn.Font = Enum.Font.Gotham
        btn.TextSize = 14
        btn.TextXAlignment = Enum.TextXAlignment.Left
        btn.Parent = row
        local function refresh()
            btn.Text = "  " .. text .. ": " .. (Config[key] and "ВКЛ" or "выкл")
            row.BackgroundColor3 = Config[key] and Color3.fromRGB(46, 110, 70) or Color3.fromRGB(38, 38, 46)
        end
        bind(btn.MouseButton1Click, function()
            Config[key] = not Config[key]
            refresh()
            if cb then pcall(cb, Config[key]) end
        end)
        refresh()
    end

    -- слайдер во встроенном окне — числовое поле с ограничением диапазона
    function B.slider(page, text, key, min, max, inc)
        local row = newRow(page)
        rowLabel(row, text)
        local box = rowBox(row, tostring(Config[key]))
        bind(box.FocusLost, function()
            local v = tonumber(box.Text)
            if v then Config[key] = math.clamp(v, min, max) end
            box.Text = tostring(Config[key])
        end)
    end

    function B.input(page, text, placeholder, cb)
        local row = newRow(page)
        rowLabel(row, text)
        local box = rowBox(row, "")
        box.PlaceholderText = placeholder or ""
        bind(box.FocusLost, function() pcall(cb, box.Text) end)
    end

    function B.button(page, text, fn)
        local row = newRow(page)
        local btn = Instance.new("TextButton")
        btn.Size = UDim2.fromScale(1, 1)
        btn.BackgroundTransparency = 1
        btn.Text = text
        btn.TextColor3 = Color3.new(1, 1, 1)
        btn.Font = Enum.Font.Gotham
        btn.TextSize = 14
        btn.Parent = row
        bind(btn.MouseButton1Click, function() pcall(fn) end)
    end

    function B.label(page, text)
        local l = Instance.new("TextLabel")
        l.Size = UDim2.new(1, -10, 0, 34)
        l.BackgroundTransparency = 1
        l.Text = text
        l.TextColor3 = Color3.fromRGB(200, 200, 220)
        l.Font = Enum.Font.Gotham
        l.TextSize = 12
        l.TextWrapped = true
        l.Parent = page
        return function(s) l.Text = s end
    end

    function B.dropdown(page, text, options, current, cb)
        local row = newRow(page)
        rowLabel(row, text)
        local list = options
        local btn = Instance.new("TextButton")
        btn.Position = UDim2.new(0.5, 0, 0, 3)
        btn.Size = UDim2.new(0.5, -6, 1, -6)
        btn.BackgroundColor3 = Color3.fromRGB(20, 20, 26)
        btn.BorderSizePixel = 0
        btn.Text = tostring(current)
        btn.TextColor3 = Color3.new(1, 1, 1)
        btn.Font = Enum.Font.Gotham
        btn.TextSize = 12
        btn.TextTruncate = Enum.TextTruncate.AtEnd
        btn.Parent = row
        Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 4)
        bind(btn.MouseButton1Click, function()
            openPopup(list, function(opt)
                btn.Text = tostring(opt)
                pcall(cb, opt)
            end)
        end)
        return {
            refresh = function(newList) list = newList end,
            set = function(v) btn.Text = tostring(v) end,
        }
    end

    function B.notify(titleText, text)
        toastToken += 1
        local mine = toastToken
        toast.Text = titleText .. ": " .. text
        toast.Visible = true
        task.delay(4, function()
            if toastToken == mine then toast.Visible = false end
        end)
    end

    function B.destroy()
        pcall(function() main:Destroy() end)
        pcall(function() toast:Destroy() end)
    end
    return B
end

-- выбираем первый заработавший бэкенд
local backends = { obsidian = backendObsidian, rayfield = backendRayfield, builtin = backendBuiltin }
local order = { "obsidian", "rayfield", "builtin" }
if type(genv.CFE_GUI) == "string" then order = { genv.CFE_GUI:lower(), "builtin" } end

local UI
for _, key in ipairs(order) do
    local f = backends[key]
    if f then
        local ok, res = pcall(f)
        if ok and res then
            UI = res
            break
        end
        warn("[CFE] GUI «" .. key .. "» не завёлся: " .. tostring(res))
    end
end
if not UI then
    warn("[CFE] ни один GUI не запустился")
    return
end
warn("[CFE] GUI: " .. UI.name)

local function notify(title, text) UI.notify(title, text) end

-- кнопки «вверх/вниз» для полёта на телефоне (на ПК не показываются)
local flyPad = Instance.new("Frame")
flyPad.Size = UDim2.fromOffset(110, 120)
flyPad.Position = UDim2.new(1, -130, 0.5, -60)
flyPad.BackgroundTransparency = 1
flyPad.Visible = false
flyPad.Parent = gui

local function holdButton(text, y, setter)
    local b = Instance.new("TextButton")
    b.Position = UDim2.fromOffset(0, y)
    b.Size = UDim2.fromOffset(110, 54)
    b.BackgroundColor3 = Color3.fromRGB(40, 40, 60)
    b.BackgroundTransparency = 0.2
    b.BorderSizePixel = 0
    b.Text = text
    b.TextColor3 = Color3.new(1, 1, 1)
    b.Font = Enum.Font.GothamBold
    b.TextSize = 16
    b.Parent = flyPad
    Instance.new("UICorner", b).CornerRadius = UDim.new(0, 8)
    bind(b.InputBegan, function(i)
        if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then setter(true) end
    end)
    bind(b.InputEnded, function(i)
        if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then setter(false) end
    end)
end
holdButton("▲ вверх", 0, function(v) upHeld = v end)
holdButton("▼ вниз", 66, function(v) downHeld = v end)

-- ===== Движение =====
local MoveTab = UI.tab("Движение")
UI.section(MoveTab, "Полёт")
UI.toggle(MoveTab, "Fly", "Fly", function(on)
    if not on then stopFly() end
    flyPad.Visible = on and UIS.TouchEnabled
end)
UI.slider(MoveTab, "Скорость полёта", "FlySpeed", 10, 400, 5)
UI.toggle(MoveTab, "Noclip", "Noclip", function(on)
    if not on then setNoclip(false) end
end)
UI.label(MoveTab, "ПК: Space — вверх, Ctrl/Shift — вниз. Вперёд летишь туда, куда смотрит камера. На телефоне появятся кнопки вверх/вниз.")
UI.section(MoveTab, "Телепорт")
UI.slider(MoveTab, "Скорость ТП (ст/с)", "TpSpeed", 20, 3000, 10)
UI.toggle(MoveTab, "Мгновенный ТП", "TpInstant")
UI.button(MoveTab, "Сохранить позицию (база)", function()
    local r = getRoot()
    if r then
        SavedPos = r.Position
        notify("Позиция", "сохранена")
    end
end)
UI.button(MoveTab, "ТП на сохранённую позицию", function()
    if SavedPos then teleportTo(SavedPos) else notify("Позиция", "сначала сохрани позицию") end
end)
UI.button(MoveTab, "Стоп (отменить телепорт)", function() tpToken += 1 end)

-- ===== Яйца =====
local EggTab = UI.tab("Яйца")
UI.toggle(EggTab, "ESP яиц", "EggESP")
UI.toggle(EggTab, "Подписи (редкость/дистанция)", "EggInfo")
UI.toggle(EggTab, "Трейсеры", "EggTracers")
UI.dropdown(EggTab, "Показывать от", MIN_OPTIONS, Config.EggMin, function(v) Config.EggMin = v end)
UI.toggle(EggTab, "Показывать яйца с неизвестной редкостью", "EggShowUnknown")
UI.slider(EggTab, "Макс. дистанция (стад)", "EggMaxDist", 100, 20000, 100)
local setEggInfo = UI.label(EggTab, "Яиц найдено: 0")
UI.label(EggTab, "Яйца берутся из Workspace.SpawnedEggs. Редкость читается из атрибутов или из подписи над яйцом в игре; если не нашлась, показывается «?».")
UI.button(EggTab, "ТП к ближайшему яйцу выбранной редкости", function()
    local root = getRoot()
    if not root then return end
    local th = MIN_THRESHOLD[Config.EggMin] or 0
    local best, bestD = nil, math.huge
    for inst in pairs(Eggs) do
        if inst.Parent then
            local r, label = eggRarity(inst)
            local pos = eggPos(inst)
            if pos and eggPasses(r, label) then
                local d = (pos - root.Position).Magnitude
                if d < bestD then best, bestD = pos, d end
            end
        end
    end
    if best then teleportTo(best) else notify("Яйца", "подходящих яиц нет") end
end)

task.spawn(function()
    while Config.Alive do
        setEggInfo("Яиц найдено: " .. eggCount .. (scanDone and "" or " (скан идёт...)"))
        task.wait(1)
    end
end)

-- ===== Зоны =====
local ZoneTab = UI.tab("Зоны")
local setZoneInfo = UI.label(ZoneTab, zoneInfoText)
local selectedZone = nil
local zoneNames = {}
local zoneDrop

local function zoneByName(name)
    for _, z in ipairs(Zones) do
        if z.name == name then return z end
    end
    return nil
end

local function refreshZones()
    pcall(scanZones)
    zoneNames = {}
    for _, z in ipairs(Zones) do table.insert(zoneNames, z.name) end
    if #zoneNames == 0 then zoneNames = { "—" } end
    zoneDrop.refresh(zoneNames)
    selectedZone = zoneNames[1] ~= "—" and zoneNames[1] or nil
    zoneDrop.set(zoneNames[1])
    setZoneInfo(zoneInfoText)
end

UI.button(ZoneTab, "Найти зоны", refreshZones)
zoneDrop = UI.dropdown(ZoneTab, "Зона", { "—" }, "—", function(v)
    selectedZone = (v ~= "—") and v or nil
end)
UI.button(ZoneTab, "ТП в выбранную зону", function()
    local z = selectedZone and zoneByName(selectedZone)
    if z then teleportTo(z.pos) else notify("Зоны", "сначала найди зоны и выбери одну") end
end)
UI.button(ZoneTab, "★ ТП в последнюю зону", function()
    local z
    for i = #Zones, 1, -1 do
        if not Zones[i].event then z = Zones[i] break end
    end
    if z then
        notify("Зоны", "лечу в " .. z.name)
        teleportTo(z.pos)
    else
        notify("Зоны", "зоны не найдены, нажми «Найти зоны»")
    end
end)
UI.button(ZoneTab, "ТП на самую высокую точку карты", function()
    notify("Зоны", "ищу самую высокую точку...")
    task.spawn(function()
        local p = highestPoint()
        if p then teleportTo(p) else notify("Зоны", "не нашёл подходящих деталей") end
    end)
end)

-- ===== Дебаг =====
local DbgTab = UI.tab("Дебаг")
UI.label(DbgTab, "Если зоны или яйца ведут себя странно — сделай дамп и скинь мне файл CFE_dump.txt или текст из буфера.")
UI.button(DbgTab, "Сделать дамп игры (файл + буфер)", function()
    task.spawn(function()
        notify("Дамп", "собираю...")
        pcall(scanZones)
        local ok, saved, copied, size = pcall(makeDump)
        if not ok then
            notify("Дамп", "упал: " .. tostring(saved))
        else
            notify("Дамп готов", string.format("%d симв. Файл: %s, буфер: %s",
                size, saved and "есть" or "нет", copied and "да" or "нет"))
        end
    end)
end)

local function unload()
    Config.Alive = false
    Config.Fly, Config.Noclip = false, false
    tpToken += 1
    stopFly()
    pcall(setNoclip, false)
    for _, c in ipairs(Conns) do pcall(function() c:Disconnect() end) end
    clearESP()
    pcall(function() UI.destroy() end)
    if gui then gui:Destroy() end
    genv.CFE_Unload = nil
end
genv.CFE_Unload = unload
UI.button(DbgTab, "Выгрузить скрипт", unload)

-- первый поиск зон в фоне
task.spawn(function()
    task.wait(1)
    refreshZones()
end)

How to Execute Climb for Eggs! Script – Keyless

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

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

Step 3: Join Experience: Launch Roblox and join Climb for Eggs!.

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

Created By

LunaBlox
LunaBlox
Script Creator
View Author Profile

Roblox Experience

[UPD🎃] Climb for Eggs!
Climb for Eggs!
By 5ccu games
Active Players:267
Play on Roblox

Features & Information

Execute Climb for Eggs! Script – Keyless. Key system required, created by LunaBlox, updated Oct 24, 2026. Tested and working on supported executors.
#keyless

Script Changelog (2)

@QueueSherlockOct 27, 2026

Edited during review before approval

@LunaBloxOct 24, 2026

Create script

Community Comments (0)

No comments yet for this script.

Frequently Asked Questions

How do I execute Climb for Eggs! Script – Keyless in Roblox?

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

Is Climb for Eggs! Script – Keyless keyless or does it require an access key?

Climb for Eggs! Script – Keyless requires an access key. You can retrieve the official key directly using the Get Script Key link provided above.

Is Climb for Eggs! Script – Keyless currently safe and working?

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