VOXEL DESTRUCT 2 EARLY ACCESS Script (November 2026)

PUBLISHEDUPDATED
1 Available ScriptFree

Keeping up after a new update is tough when everyone else is already smashing buildings to pieces, but grabbing the VOXEL DESTRUCT 2 EARLY ACCESS script makes it way easier to keep pace.

You are dropping into an unfinished paid testing phase where literally everything is fully destructible, from walls and structures down to the terrain itself, plus fire physics let you burn down whatever you want while the indie team builds out the core features.

Since the current script is still in testing, you will want to grab it and test how it runs while you smash up the map.

VOXEL DESTRUCT 2 EARLY ACCESS Script – still in testing & More

still in testing & MoreFree
still in testing
--[[
    V5 FULL SYSTEM
    Auto Aim (FOV → Head) + Fast Triggerbot
    Wall / Team / ForceField / NPC Support + NPC Team Check
    Player ESP + NPC ESP (separate)
    CFrame Speed (fast) | Azure-style Bhop | Spinbot | Fly | InfJump
    Custom Tab GUI
]]

-- SERVICES
local Players             = game:GetService("Players")
local RunService          = game:GetService("RunService")
local UIS                 = game:GetService("UserInputService")
local TweenService        = game:GetService("TweenService")
local VirtualInputManager = game:GetService("VirtualInputManager")
local Lighting            = game:GetService("Lighting")
local Workspace           = game:GetService("Workspace")
local CoreGui             = game:GetService("CoreGui")

local LocalPlayer = Players.LocalPlayer
local Camera      = Workspace.CurrentCamera

-- ===================== SETTINGS =====================
local Settings = {
    -- Aim
    AimEnabled      = false,
    AimMode         = "Silent",
    AimKey          = Enum.KeyCode.Q,
    FOV             = 140,
    Smoothness      = 0.12,
    HitChance       = 100,
    TeamCheck       = true,
    WallCheck       = true,
    ForceFieldCheck = true,
    NPCSupport      = false,
    NPCTeamCheck    = true,          -- NEW: skip friendly NPCs
    AutoAim         = true,
    AutoShoot       = true,
    ShotDelay       = 0.032,
    RageNoFOV       = true,
    RageFullAuto    = true,

    -- ESP
    PlayerESP       = true,
    NPCESP          = false,
    ItemESP         = true,
    ShowNames       = true,
    ShowDistance    = true,
    ShowBoxes       = true,
    ShowHealth      = true,
    MaxDistance     = 2500,

    -- Movement
    SpeedEnabled    = false,
    SpeedValue      = 5.5,            -- CFrame multiplier (higher = faster)
    FlyEnabled      = false,
    FlySpeed        = 60,
    InfiniteJump    = false,
    BunnyHop        = false,
    Spinbot         = false,
    SpinSpeed       = 28,

    -- Visuals
    Headless        = false,
    PurpleSky       = false,
    RedSky          = false,

    Whitelist       = {},
}

-- Internal
local lockedPart     = nil
local lastShot       = 0
local flying         = false
local flyBV, flyBG   = nil, nil
local gui            = nil
local holdingAimKey  = false
local drawingObjects = {}
local itemBillboards = {}

-- ===================== HELPERS =====================
local function isWhitelisted(plr)
    return plr and Settings.Whitelist[plr.Name] == true
end

local function getChar(plr)
    return plr and plr.Character
end

local function getHum(char)
    return char and char:FindFirstChildOfClass("Humanoid")
end

local function getRoot(char)
    return char and (char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso") or char.PrimaryPart)
end

local function getHead(char)
    return char and (char:FindFirstChild("Head") or getRoot(char))
end

local function isAliveChar(char)
    local hum = getHum(char)
    return char and hum and hum.Health > 0
end

local function hasForceField(char)
    return char and char:FindFirstChildOfClass("ForceField") ~= nil
end

local function isEnemyPlayer(plr)
    if not plr or plr == LocalPlayer then return false end
    if isWhitelisted(plr) then return false end
    if Settings.TeamCheck and plr.Team and LocalPlayer.Team and plr.Team == LocalPlayer.Team then
        return false
    end
    return true
end

-- NPC Team Check (works with most games)
local function isFriendlyNPC(npc)
    if not Settings.NPCTeamCheck then return false end
    if not npc or not LocalPlayer.Team then return false end

    local myTeam = LocalPlayer.Team
    local myTeamName = tostring(myTeam.Name):lower()

    -- Method 1: NPC has a Team object / value
    local teamVal = npc:FindFirstChild("Team") or npc:FindFirstChild("TeamName") or npc:FindFirstChild("team")
    if teamVal then
        if typeof(teamVal) == "Instance" then
            if teamVal:IsA("ObjectValue") and teamVal.Value == myTeam then return true end
            if teamVal:IsA("StringValue") and teamVal.Value:lower() == myTeamName then return true end
            if teamVal:IsA("IntValue") and myTeam and teamVal.Value == myTeam.TeamColor.Number then return true end
        end
    end

    -- Method 2: Attribute
    local attr = npc:GetAttribute("Team") or npc:GetAttribute("TeamName")
    if attr and tostring(attr):lower() == myTeamName then return true end

    -- Method 3: Name contains team name
    local npcName = npc.Name:lower()
    if npcName:find(myTeamName) then return true end

    -- Method 4: Look for StringValue anywhere inside
    for _, v in ipairs(npc:GetDescendants()) do
        if v:IsA("StringValue") and (v.Name:lower():find("team") or v.Name:lower() == "faction") then
            if v.Value:lower() == myTeamName then return true end
        end
    end

    return false
end

local function hasWallCheck(part)
    if not Settings.WallCheck then return true end
    if not part then return false end
    local origin = Camera.CFrame.Position
    local dir    = part.Position - origin
    local params = RaycastParams.new()
    params.FilterType = Enum.RaycastFilterType.Blacklist
    params.FilterDescendantsInstances = {LocalPlayer.Character, Camera}
    params.IgnoreWater = true
    local result = Workspace:Raycast(origin, dir, params)
    return not result or result.Instance:IsDescendantOf(part.Parent)
end

local function getAllTargets(forAim)
    local targets = {}

    -- Real players
    for _, plr in ipairs(Players:GetPlayers()) do
        if isEnemyPlayer(plr) and isAliveChar(getChar(plr)) then
            local char = getChar(plr)
            if not (Settings.ForceFieldCheck and hasForceField(char)) then
                table.insert(targets, {char = char, name = plr.Name, isNPC = false})
            end
        end
    end

    -- NPCs
    local wantNPC = forAim and Settings.NPCSupport or Settings.NPCESP
    if wantNPC then
        for _, obj in ipairs(Workspace:GetDescendants()) do
            if obj:IsA("Model") and obj ~= LocalPlayer.Character then
                local hum = obj:FindFirstChildOfClass("Humanoid")
                if hum and hum.Health > 0 then
                    local isPlayerChar = false
                    for _, plr in ipairs(Players:GetPlayers()) do
                        if plr.Character == obj then
                            isPlayerChar = true
                            break
                        end
                    end
                    if not isPlayerChar then
                        if Settings.ForceFieldCheck and hasForceField(obj) then continue end
                        if isFriendlyNPC(obj) then continue end   -- skip friendly NPCs
                        table.insert(targets, {char = obj, name = obj.Name, isNPC = true})
                    end
                end
            end
        end
    end

    return targets
end

local function getClosestInFOV()
    local closest, best = nil, math.huge
    local mousePos = UIS:GetMouseLocation()
    local useFOV = not (Settings.AimMode == "Rage" and Settings.RageNoFOV)

    for _, target in ipairs(getAllTargets(true)) do
        local part = getHead(target.char)
        if part then
            local screen, onScreen = Camera:WorldToViewportPoint(part.Position)
            local dist

            if useFOV then
                if not onScreen then continue end
                dist = (Vector2.new(screen.X, screen.Y) - mousePos).Magnitude
                if dist > Settings.FOV then continue end
            else
                dist = (part.Position - Camera.CFrame.Position).Magnitude
            end

            if dist < best and hasWallCheck(part) then
                best = dist
                closest = part
            end
        end
    end
    return closest
end

-- ===================== AIM + TRIGGERBOT =====================
local function doAim(part)
    if not part then return end
    if math.random(1, 100) > Settings.HitChance then return end

    local targetCF = CFrame.new(Camera.CFrame.Position, part.Position)
    if Settings.AimMode == "Rage" or Settings.Smoothness <= 0 then
        Camera.CFrame = targetCF
    else
        Camera.CFrame = Camera.CFrame:Lerp(targetCF, 1 - Settings.Smoothness)
    end
end

local function tryTriggerbot()
    if not Settings.AutoShoot then return end
    if not lockedPart then return end
    if not hasWallCheck(lockedPart) then return end
    if Settings.ForceFieldCheck and hasForceField(lockedPart.Parent) then return end

    local now = os.clock()
    if now - lastShot < Settings.ShotDelay then return end
    lastShot = now

    pcall(function()
        VirtualInputManager:SendMouseButtonEvent(0, 0, 0, true, game, 0)
        task.wait(0.01)
        VirtualInputManager:SendMouseButtonEvent(0, 0, 0, false, game, 0)
    end)
end

-- ===================== MOVEMENT =====================
local function applyCFrameSpeed()
    if not Settings.SpeedEnabled then return end
    local char = LocalPlayer.Character
    local root = getRoot(char)
    local hum  = getHum(char)
    if not root or not hum then return end

    local dir = hum.MoveDirection
    if dir.Magnitude > 0 then
        root.CFrame = root.CFrame + (dir * Settings.SpeedValue)
    end
end

-- Azure-style BunnyHop
local function applyBunnyHop()
    if not Settings.BunnyHop then return end
    if not UIS:IsKeyDown(Enum.KeyCode.Space) then return end

    local char = LocalPlayer.Character
    local hum  = getHum(char)
    if not hum then return end

    if hum.FloorMaterial ~= Enum.Material.Air then
        hum.Jump = true
        pcall(function()
            hum:ChangeState(Enum.HumanoidStateType.Jumping)
        end)
    end
end

local function applySpinbot()
    if not Settings.Spinbot then return end
    local root = getRoot(LocalPlayer.Character)
    if root then
        root.CFrame = root.CFrame * CFrame.Angles(0, math.rad(Settings.SpinSpeed), 0)
    end
end

local function startFly()
    stopFly()
    local root = getRoot(LocalPlayer.Character)
    if not root then return end

    flying = true
    flyBV = Instance.new("BodyVelocity")
    flyBV.Name = "V5FlyBV"
    flyBV.MaxForce = Vector3.new(9e9, 9e9, 9e9)
    flyBV.Velocity = Vector3.zero
    flyBV.Parent = root

    flyBG = Instance.new("BodyGyro")
    flyBG.Name = "V5FlyBG"
    flyBG.MaxTorque = Vector3.new(9e9, 9e9, 9e9)
    flyBG.P = 9e4
    flyBG.Parent = root
end

local function stopFly()
    flying = false
    if flyBV then pcall(function() flyBV:Destroy() end) flyBV = nil end
    if flyBG then pcall(function() flyBG:Destroy() end) flyBG = nil end
    local root = getRoot(LocalPlayer.Character)
    if root then
        for _, v in ipairs(root:GetChildren()) do
            if v.Name == "V5FlyBV" or v.Name == "V5FlyBG" then
                pcall(function() v:Destroy() end)
            end
        end
    end
end

local function updateFly()
    if not Settings.FlyEnabled then
        if flying then stopFly() end
        return
    end

    local root = getRoot(LocalPlayer.Character)
    if not root then return end

    if not flyBV or not flyBV.Parent or not flyBG or not flyBG.Parent then
        startFly()
    end

    local camCF = Camera.CFrame
    local move = Vector3.zero
    if UIS:IsKeyDown(Enum.KeyCode.W) then move += camCF.LookVector end
    if UIS:IsKeyDown(Enum.KeyCode.S) then move -= camCF.LookVector end
    if UIS:IsKeyDown(Enum.KeyCode.A) then move -= camCF.RightVector end
    if UIS:IsKeyDown(Enum.KeyCode.D) then move += camCF.RightVector end
    if UIS:IsKeyDown(Enum.KeyCode.Space) then move += Vector3.yAxis end
    if UIS:IsKeyDown(Enum.KeyCode.LeftControl) or UIS:IsKeyDown(Enum.KeyCode.LeftShift) then
        move -= Vector3.yAxis
    end

    if flyBV then
        flyBV.Velocity = move.Magnitude > 0 and move.Unit * Settings.FlySpeed or Vector3.zero
    end
    if flyBG then
        flyBG.CFrame = camCF
    end
end

UIS.JumpRequest:Connect(function()
    if Settings.InfiniteJump then
        local hum = getHum(LocalPlayer.Character)
        if hum then
            hum:ChangeState(Enum.HumanoidStateType.Jumping)
        end
    end
end)

-- ===================== ESP =====================
local function clearDrawings()
    for _, d in pairs(drawingObjects) do
        pcall(function() d:Remove() end)
    end
    drawingObjects = {}
end

local function drawTarget(target)
    local char = target.char
    local root = getRoot(char)
    local hum  = getHum(char)
    if not root or not hum then return end

    local dist = (root.Position - Camera.CFrame.Position).Magnitude
    if dist > Settings.MaxDistance then return end

    local screen, onScreen = Camera:WorldToViewportPoint(root.Position)
    if not onScreen then return end

    local col = target.isNPC and Color3.fromRGB(255, 160, 40) or Color3.fromRGB(255, 255, 255)
    local boxCol = target.isNPC and Color3.fromRGB(255, 140, 0) or Color3.fromRGB(0, 255, 140)

    if Settings.ShowNames or Settings.ShowDistance then
        local t = Drawing.new("Text")
        t.Visible = true
        t.Center = true
        t.Outline = true
        t.Size = 13
        t.Color = col
        t.Position = Vector2.new(screen.X, screen.Y - 38)
        local str = ""
        if Settings.ShowNames then
            str = target.isNPC and ("[NPC] " .. target.name) or target.name
        end
        if Settings.ShowDistance then
            str = str .. string.format(" [%.0f]", dist)
        end
        t.Text = str
        table.insert(drawingObjects, t)
    end

    if Settings.ShowHealth then
        local hp = math.clamp(hum.Health / math.max(hum.MaxHealth, 1), 0, 1)
        local bar = Drawing.new("Line")
        bar.Visible = true
        bar.Thickness = 2
        bar.Color = Color3.fromRGB(255*(1-hp), 255*hp, 40)
        bar.From = Vector2.new(screen.X - 28, screen.Y - 22)
        bar.To   = Vector2.new(screen.X - 28 + 56*hp, screen.Y - 22)
        table.insert(drawingObjects, bar)
    end

    if Settings.ShowBoxes then
        local box = Drawing.new("Square")
        box.Visible = true
        box.Thickness = 1
        box.Filled = false
        box.Color = boxCol
        box.Size = Vector2.new(36, 54)
        box.Position = Vector2.new(screen.X - 18, screen.Y - 27)
        table.insert(drawingObjects, box)
    end
end

local function updateESP()
    clearDrawings()

    if Settings.PlayerESP then
        for _, t in ipairs(getAllTargets(false)) do
            if not t.isNPC then drawTarget(t) end
        end
    end

    if Settings.NPCESP then
        for _, t in ipairs(getAllTargets(false)) do
            if t.isNPC then drawTarget(t) end
        end
    end
end

local weaponList = {
    {name="MP5", keys={"mp5","smg"}},
    {name="Mossberg", keys={"mossberg","shotgun"}},
    {name="P9", keys={"p9","pistol","9mm"}},
    {name="Nambu", keys={"nambu","type14"}},
    {name="Howa", keys={"howa","rifle"}},
}

local function scanItems()
    if not Settings.ItemESP then return end
    for _, obj in ipairs(Workspace:GetDescendants()) do
        if (obj:IsA("Tool") or obj:IsA("Model")) and not itemBillboards[obj] then
            local lower = obj.Name:lower()
            for _, w in ipairs(weaponList) do
                for _, k in ipairs(w.keys) do
                    if lower:find(k) then
                        local part = obj:FindFirstChild("Handle") or obj:FindFirstChildWhichIsA("BasePart")
                        if part then
                            local bb = Instance.new("BillboardGui")
                            bb.Name = "ItemESP"
                            bb.Adornee = part
                            bb.Size = UDim2.new(0, 110, 0, 28)
                            bb.StudsOffset = Vector3.new(0, 2.4, 0)
                            bb.AlwaysOnTop = true
                            bb.Parent = part
                            local lbl = Instance.new("TextLabel")
                            lbl.Size = UDim2.new(1,0,1,0)
                            lbl.BackgroundTransparency = 0.35
                            lbl.BackgroundColor3 = Color3.new(0,0,0)
                            lbl.Text = w.name
                            lbl.TextColor3 = Color3.fromRGB(255, 220, 50)
                            lbl.TextScaled = true
                            lbl.Font = Enum.Font.GothamBold
                            lbl.Parent = bb
                            Instance.new("UICorner", lbl).CornerRadius = UDim.new(0, 4)
                            itemBillboards[obj] = bb
                        end
                        break
                    end
                end
            end
        end
    end
end

-- ===================== VISUALS =====================
local function applyHeadless()
    local char = LocalPlayer.Character
    if not char then return end
    local head = char:FindFirstChild("Head")
    if head then
        head.Transparency = Settings.Headless and 1 or 0
        local face = head:FindFirstChildWhichIsA("Decal")
        if face then face.Transparency = Settings.Headless and 1 or 0 end
    end
end

local function setSky(mode)
    local old = Lighting:FindFirstChild("_V5Sky")
    if old then old:Destroy() end
    if mode == "none" then return end
    local sky = Instance.new("Sky")
    sky.Name = "_V5Sky"
    sky.Parent = Lighting
    if mode == "purple" then
        sky.SkyboxBk = "rbxassetid://570557514"
        sky.SkyboxDn = "rbxassetid://570557775"
        sky.SkyboxFt = "rbxassetid://570557559"
        sky.SkyboxLf = "rbxassetid://570557620"
        sky.SkyboxRt = "rbxassetid://570557672"
        sky.SkyboxUp = "rbxassetid://570557727"
        sky.StarCount = 3000
    elseif mode == "red" then
        sky.SkyboxBk = "rbxassetid://271042516"
        sky.SkyboxDn = "rbxassetid://271077243"
        sky.SkyboxFt = "rbxassetid://271042556"
        sky.SkyboxLf = "rbxassetid://271042310"
        sky.SkyboxRt = "rbxassetid://271042467"
        sky.SkyboxUp = "rbxassetid://271077958"
        sky.StarCount = 0
    end
end

-- ===================== GUI =====================
local function createToggle(parent, text, default, callback)
    local frame = Instance.new("Frame")
    frame.Size = UDim2.new(1, -20, 0, 28)
    frame.BackgroundTransparency = 1
    frame.Parent = parent

    local label = Instance.new("TextLabel")
    label.Size = UDim2.new(0.7, 0, 1, 0)
    label.BackgroundTransparency = 1
    label.Text = text
    label.TextColor3 = Color3.fromRGB(230, 230, 230)
    label.TextXAlignment = Enum.TextXAlignment.Left
    label.Font = Enum.Font.Gotham
    label.TextSize = 13
    label.Parent = frame

    local btn = Instance.new("TextButton")
    btn.Size = UDim2.new(0, 50, 0, 22)
    btn.Position = UDim2.new(1, -55, 0.5, -11)
    btn.BackgroundColor3 = default and Color3.fromRGB(0, 180, 80) or Color3.fromRGB(60, 60, 60)
    btn.Text = default and "ON" or "OFF"
    btn.TextColor3 = Color3.new(1,1,1)
    btn.Font = Enum.Font.GothamBold
    btn.TextSize = 12
    btn.Parent = frame
    Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 4)

    local state = default
    btn.MouseButton1Click:Connect(function()
        state = not state
        btn.Text = state and "ON" or "OFF"
        btn.BackgroundColor3 = state and Color3.fromRGB(0, 180, 80) or Color3.fromRGB(60, 60, 60)
        callback(state)
    end)
    return frame
end

local function createGUI()
    if gui then gui:Destroy() end
    gui = Instance.new("ScreenGui")
    gui.Name = "V5System"
    gui.ResetOnSpawn = false
    gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
    pcall(function() gui.Parent = CoreGui end)
    if not gui.Parent then gui.Parent = LocalPlayer:WaitForChild("PlayerGui") end

    local main = Instance.new("Frame")
    main.Name = "Main"
    main.Size = UDim2.new(0, 350, 0, 460)
    main.Position = UDim2.new(0.5, -175, 0.5, -230)
    main.BackgroundColor3 = Color3.fromRGB(22, 22, 28)
    main.BorderSizePixel = 0
    main.Active = true
    main.Draggable = true
    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(30, 30, 40)
    title.Text = "V5 SYSTEM"
    title.TextColor3 = Color3.fromRGB(0, 220, 140)
    title.Font = Enum.Font.GothamBold
    title.TextSize = 16
    title.Parent = main
    Instance.new("UICorner", title).CornerRadius = UDim.new(0, 8)

    local tabFrame = Instance.new("Frame")
    tabFrame.Size = UDim2.new(1, -16, 0, 30)
    tabFrame.Position = UDim2.new(0, 8, 0, 38)
    tabFrame.BackgroundTransparency = 1
    tabFrame.Parent = main

    local tabs = {"Aim", "ESP", "Move", "Visual"}
    local pages = {}

    local function showPage(name)
        for n, p in pairs(pages) do
            p.Visible = (n == name)
        end
    end

    for i, name in ipairs(tabs) do
        local b = Instance.new("TextButton")
        b.Size = UDim2.new(0.25, -4, 1, 0)
        b.Position = UDim2.new((i-1)*0.25, 2, 0, 0)
        b.BackgroundColor3 = Color3.fromRGB(40, 40, 55)
        b.Text = name
        b.TextColor3 = Color3.new(1,1,1)
        b.Font = Enum.Font.GothamBold
        b.TextSize = 13
        b.Parent = tabFrame
        Instance.new("UICorner", b).CornerRadius = UDim.new(0, 4)
        b.MouseButton1Click:Connect(function() showPage(name) end)
    end

    local content = Instance.new("Frame")
    content.Size = UDim2.new(1, -16, 1, -80)
    content.Position = UDim2.new(0, 8, 0, 72)
    content.BackgroundTransparency = 1
    content.Parent = main

    -- AIM PAGE
    local aimPage = Instance.new("ScrollingFrame")
    aimPage.Size = UDim2.new(1, 0, 1, 0)
    aimPage.BackgroundTransparency = 1
    aimPage.ScrollBarThickness = 3
    aimPage.CanvasSize = UDim2.new(0, 0, 0, 460)
    aimPage.Parent = content
    pages["Aim"] = aimPage
    Instance.new("UIListLayout", aimPage).Padding = UDim.new(0, 4)

    createToggle(aimPage, "Aim Enabled", Settings.AimEnabled, function(v) Settings.AimEnabled = v end)
    createToggle(aimPage, "Auto Aim (FOV → Head)", Settings.AutoAim, function(v) Settings.AutoAim = v end)
    createToggle(aimPage, "Triggerbot", Settings.AutoShoot, function(v) Settings.AutoShoot = v end)
    createToggle(aimPage, "Team Check", Settings.TeamCheck, function(v) Settings.TeamCheck = v end)
    createToggle(aimPage, "Wall Check", Settings.WallCheck, function(v) Settings.WallCheck = v end)
    createToggle(aimPage, "ForceField Check", Settings.ForceFieldCheck, function(v) Settings.ForceFieldCheck = v end)
    createToggle(aimPage, "NPC Support (Aim)", Settings.NPCSupport, function(v) Settings.NPCSupport = v end)
    createToggle(aimPage, "NPC Team Check", Settings.NPCTeamCheck, function(v) Settings.NPCTeamCheck = v end)
    createToggle(aimPage, "Rage No FOV", Settings.RageNoFOV, function(v) Settings.RageNoFOV = v end)
    createToggle(aimPage, "Rage Full Auto", Settings.RageFullAuto, function(v) Settings.RageFullAuto = v end)

    local modeFrame = Instance.new("Frame")
    modeFrame.Size = UDim2.new(1, -10, 0, 30)
    modeFrame.BackgroundTransparency = 1
    modeFrame.Parent = aimPage
    local modes = {"Silent", "Legit", "Rage"}
    for i, m in ipairs(modes) do
        local b = Instance.new("TextButton")
        b.Size = UDim2.new(0.33, -4, 1, 0)
        b.Position = UDim2.new((i-1)*0.33, 2, 0, 0)
        b.BackgroundColor3 = Settings.AimMode == m and Color3.fromRGB(0, 160, 100) or Color3.fromRGB(50, 50, 65)
        b.Text = m
        b.TextColor3 = Color3.new(1,1,1)
        b.Font = Enum.Font.GothamBold
        b.TextSize = 12
        b.Parent = modeFrame
        Instance.new("UICorner", b).CornerRadius = UDim.new(0, 4)
        b.MouseButton1Click:Connect(function()
            Settings.AimMode = m
            for _, c in ipairs(modeFrame:GetChildren()) do
                if c:IsA("TextButton") then
                    c.BackgroundColor3 = c.Text == m and Color3.fromRGB(0, 160, 100) or Color3.fromRGB(50, 50, 65)
                end
            end
        end)
    end

    -- ESP PAGE
    local espPage = Instance.new("ScrollingFrame")
    espPage.Size = UDim2.new(1, 0, 1, 0)
    espPage.BackgroundTransparency = 1
    espPage.Visible = false
    espPage.CanvasSize = UDim2.new(0, 0, 0, 260)
    espPage.Parent = content
    pages["ESP"] = espPage
    Instance.new("UIListLayout", espPage).Padding = UDim.new(0, 4)

    createToggle(espPage, "Player ESP", Settings.PlayerESP, function(v) Settings.PlayerESP = v end)
    createToggle(espPage, "NPC ESP", Settings.NPCESP, function(v) Settings.NPCESP = v end)
    createToggle(espPage, "Item ESP", Settings.ItemESP, function(v) Settings.ItemESP = v end)
    createToggle(espPage, "Names", Settings.ShowNames, function(v) Settings.ShowNames = v end)
    createToggle(espPage, "Distance", Settings.ShowDistance, function(v) Settings.ShowDistance = v end)
    createToggle(espPage, "Boxes", Settings.ShowBoxes, function(v) Settings.ShowBoxes = v end)
    createToggle(espPage, "Health Bar", Settings.ShowHealth, function(v) Settings.ShowHealth = v end)

    -- MOVE PAGE
    local movePage = Instance.new("ScrollingFrame")
    movePage.Size = UDim2.new(1, 0, 1, 0)
    movePage.BackgroundTransparency = 1
    movePage.Visible = false
    movePage.CanvasSize = UDim2.new(0, 0, 0, 260)
    movePage.Parent = content
    pages["Move"] = movePage
    Instance.new("UIListLayout", movePage).Padding = UDim.new(0, 4)

    createToggle(movePage, "CFrame Speed (Fast)", Settings.SpeedEnabled, function(v)
        Settings.SpeedEnabled = v
    end)
    createToggle(movePage, "Fly", Settings.FlyEnabled, function(v)
        Settings.FlyEnabled = v
        if v then startFly() else stopFly() end
    end)
    createToggle(movePage, "Bunny Hop (Azure)", Settings.BunnyHop, function(v)
        Settings.BunnyHop = v
    end)
    createToggle(movePage, "Infinite Jump", Settings.InfiniteJump, function(v)
        Settings.InfiniteJump = v
    end)
    createToggle(movePage, "Spinbot", Settings.Spinbot, function(v)
        Settings.Spinbot = v
    end)

    -- VISUAL PAGE
    local visPage = Instance.new("ScrollingFrame")
    visPage.Size = UDim2.new(1, 0, 1, 0)
    visPage.BackgroundTransparency = 1
    visPage.Visible = false
    visPage.CanvasSize = UDim2.new(0, 0, 0, 180)
    visPage.Parent = content
    pages["Visual"] = visPage
    Instance.new("UIListLayout", visPage).Padding = UDim.new(0, 4)

    createToggle(visPage, "Headless", Settings.Headless, function(v)
        Settings.Headless = v
        applyHeadless()
    end)
    createToggle(visPage, "Purple Sky", Settings.PurpleSky, function(v)
        Settings.PurpleSky = v
        Settings.RedSky = false
        setSky(v and "purple" or "none")
    end)
    createToggle(visPage, "Red Sky", Settings.RedSky, function(v)
        Settings.RedSky = v
        Settings.PurpleSky = false
        setSky(v and "red" or "none")
    end)

    showPage("Aim")
end

-- ===================== MAIN LOOP =====================
local function mainLoop()
    -- Aim
    if Settings.AimEnabled and (holdingAimKey or Settings.AimMode == "Rage" or Settings.AutoAim) then
        lockedPart = getClosestInFOV()
        if lockedPart then
            doAim(lockedPart)
            tryTriggerbot()
        else
            lockedPart = nil
        end
    else
        lockedPart = nil
    end

    -- Movement
    applyCFrameSpeed()
    applyBunnyHop()
    applySpinbot()
    if Settings.FlyEnabled then updateFly() end

    -- ESP
    updateESP()
end

UIS.InputBegan:Connect(function(input, gpe)
    if gpe then return end
    if input.KeyCode == Settings.AimKey then
        holdingAimKey = true
    end
end)

UIS.InputEnded:Connect(function(input)
    if input.KeyCode == Settings.AimKey then
        holdingAimKey = false
    end
end)

LocalPlayer.CharacterAdded:Connect(function()
    task.wait(0.4)
    applyHeadless()
    stopFly()
    if Settings.FlyEnabled then
        task.wait(0.15)
        startFly()
    end
end)

createGUI()
scanItems()
task.spawn(function()
    while task.wait(2) do
        scanItems()
    end
end)

RunService.RenderStepped:Connect(mainLoop)

print("V5 loaded | NPC Team Check + CFrame Speed + Azure Bhop + Spinbot")
Executor compatibility changes over time. Check current reports before testing.

Copy the code above into a compatible Roblox script executor if you choose to test it.

VOXEL DESTRUCT 2 EARLY ACCESS Script Status

✓AvailabilityFree
$Price$0
◫CompatibilityDesktop & Mobile
★SafetyVerified

Roblox and game updates can affect compatibility, so the script’s status should be treated as temporary rather than guaranteed.

Frequently Asked Questions

What is a VOXEL DESTRUCT 2 EARLY ACCESS script?

A VOXEL DESTRUCT 2 EARLY ACCESS script is third-party Lua code intended to run alongside the Roblox game through a compatible script executor.

What features does this VOXEL DESTRUCT 2 EARLY ACCESS script include?

Different scripts contain different code. This version includes: still in testing.

How do you use the VOXEL DESTRUCT 2 EARLY ACCESS script?

Pick a compatible executor such as Hydrogen, MacSploit, AWP.GG, Delta, Fluxus, Codex, launch Roblox and join the game, copy the complete Lua code from the script card above, paste it into the executor’s editor, and click Run or Execute. Compatibility changes over time, so a name here doesn’t guarantee current support.

Can a VOXEL DESTRUCT 2 EARLY ACCESS script get your Roblox account banned?

Yes. Third-party scripts can violate Roblox rules and may put an account at risk. Only use code from a source you trust, never enter your Roblox password into a script or executor, and test on an alternate account first.

Does the VOXEL DESTRUCT 2 EARLY ACCESS script work on mobile?

Check whether both the executor and the script support your device and the current Roblox version. Mobile executor support does not guarantee that every script will work.

Check out our Roblox Scripts hub and Roblox Games Directory for more.

Leave a Comment