+1 Destruction Battlegrounds Script (November 2026)

PUBLISHEDUPDATED
1 Available ScriptFree

Keeping up with the latest drops is tough when everyone else already has God of Stories or Chaos Queen unlocked, so using a +1 Destruction Battlegrounds script gives you a solid way to skip the slow grind.

You basically open packs to grab superpowers, smash up buildings across the city, and fight other players in quick battles while avoiding spawn campers thanks to the handy spawn shield.

Before you jump in to test your new powers and crush the map, grab the current release code from the gifts menu to get started.

+1 Destruction Battlegrounds Script – Hero Power Hub

Hero Power HubFree
-- Destruction Battlegrounds — Hero Power Hub
-- Instant power swapping across 54 superhero abilities, with search

-- Shared guard: prevent duplicate executions, detach the previous instance.
if shared.DestructionHub and type(shared.DestructionHub.detach) == "function" then
	shared.DestructionHub.detach()
end

if setthreadidentity then
	pcall(setthreadidentity, 8)
end

local DestructionBattlegrounds = {}

-- ═══════════════════════════════ services ═══════════════════════════════
local playersService     = game:GetService("Players")
local replicatedStorage  = game:GetService("ReplicatedStorage")
local userInputService   = game:GetService("UserInputService")
local tweenService       = game:GetService("TweenService")
local coreGui            = nil
pcall(function() coreGui = game:GetService("CoreGui") end)

-- ═══════════════════════════════ data ═══════════════════════════════════
local ALL_HEROES = {
	"Aatrox", "Ahri", "AntMan", "Archer", "Batman", "Bolt", "ChaosQueen", "Clone",
	"DemonKing", "DragonRings", "DrNoob", "Esper", "FireIce", "FlameOn", "Frieren",
	"Frost", "Gauntlet", "GhostRider", "GodOfTime", "Gojo", "Hush", "IronSuit",
	"Kaiju", "Lantern", "MechaAce", "Omnitrix", "OnePunch", "Optimus", "PumpkinBomber",
	"Reaper", "Sand", "Shadow", "ShieldHero", "Slime", "SoulReaper", "Stretchy",
	"Sukuna", "SunDancer", "Super", "SuperSaiyan", "Swarm", "Symbiote", "Telekinesis",
	"Thor", "Titan", "Vader", "Vampire", "Viltrumite", "Vines", "WebSlinger",
	"WildCard", "Witch", "Wizard"
}

local CATEGORY_MAP = {
	["All"] = ALL_HEROES,
	["Meta"] = {
		"Gojo", "Sukuna", "OnePunch", "SuperSaiyan", "Thor", "Titan",
		"Viltrumite", "Kaiju", "GodOfTime", "GhostRider", "Omnitrix", "Frieren"
	},
	["Anime"] = {
		"Gojo", "Sukuna", "OnePunch", "SuperSaiyan", "Frieren", "DemonKing",
		"SoulReaper", "GodOfTime", "Aatrox", "Ahri"
	},
	["Comics"] = {
		"Thor", "Vader", "Viltrumite", "Batman", "Bolt", "AntMan",
		"Lantern", "IronSuit", "GhostRider", "WebSlinger", "Symbiote", "Optimus"
	},
	["Magic"] = {
		"FireIce", "FlameOn", "Frost", "Sand", "Shadow", "Telekinesis",
		"Witch", "Wizard", "SunDancer", "Vines", "ChaosQueen", "DragonRings"
	},
	["Brawlers"] = {
		"Kaiju", "Titan", "Vampire", "Slime", "Swarm", "Stretchy",
		"Hush", "DrNoob", "ShieldHero", "MechaAce", "PumpkinBomber", "Clone",
		"WildCard", "Super", "Archer", "Gauntlet"
	}
}

local DEFAULT_ACCENTS = {
	Gojo = Color3.fromRGB(60, 180, 255),
	Sukuna = Color3.fromRGB(240, 45, 65),
	OnePunch = Color3.fromRGB(255, 205, 40),
	SuperSaiyan = Color3.fromRGB(255, 225, 60),
	Thor = Color3.fromRGB(120, 210, 255),
	Titan = Color3.fromRGB(180, 90, 50),
	Vader = Color3.fromRGB(220, 20, 20),
	Viltrumite = Color3.fromRGB(230, 230, 230),
	Kaiju = Color3.fromRGB(50, 160, 210),
	GodOfTime = Color3.fromRGB(140, 240, 190),
	GhostRider = Color3.fromRGB(255, 110, 25),
	Omnitrix = Color3.fromRGB(60, 235, 90),
	Frieren = Color3.fromRGB(190, 220, 255),
	Batman = Color3.fromRGB(90, 95, 110),
	IronSuit = Color3.fromRGB(225, 60, 60),
	WebSlinger = Color3.fromRGB(225, 45, 55),
	Symbiote = Color3.fromRGB(45, 45, 55),
	DemonKing = Color3.fromRGB(160, 30, 190),
	Aatrox = Color3.fromRGB(195, 40, 40),
	Ahri = Color3.fromRGB(255, 130, 190),
	Frost = Color3.fromRGB(100, 210, 255),
	FireIce = Color3.fromRGB(255, 120, 70),
	FlameOn = Color3.fromRGB(255, 95, 25),
	Shadow = Color3.fromRGB(75, 45, 110),
	ChaosQueen = Color3.fromRGB(225, 20, 45)
}

-- ═══════════════════════════════ state ══════════════════════════════════
local localPlayer      = playersService.LocalPlayer
local connections      = {}
local guiRoot          = nil
local activeHero       = localPlayer:GetAttribute("PowerOverride")
	or localPlayer:GetAttribute("EquippedPower")
	or "Gojo"
local activeCategory   = "All"
local currentSearch    = ""
local powersConfig     = nil

pcall(function()
	powersConfig = require(replicatedStorage:WaitForChild("PowersConfig", 5))
end)

-- ═══════════════════════════════ theme ══════════════════════════════════
local Theme = {
	backdrop     = Color3.fromRGB(12, 13, 17),
	surface      = Color3.fromRGB(19, 21, 27),
	surfaceAlt   = Color3.fromRGB(25, 28, 36),
	surfaceHover = Color3.fromRGB(33, 37, 47),
	border       = Color3.fromRGB(43, 48, 60),
	borderSoft   = Color3.fromRGB(34, 38, 48),
	text         = Color3.fromRGB(232, 235, 240),
	textMuted    = Color3.fromRGB(134, 141, 155),
	textFaint    = Color3.fromRGB(92, 99, 113),
	accent       = Color3.fromRGB(226, 158, 62),
	accentDim    = Color3.fromRGB(74, 56, 28),
	danger       = Color3.fromRGB(214, 78, 78),
	fontBold     = Enum.Font.GothamBold,
	fontMedium   = Enum.Font.GothamMedium,
	fontBlack    = Enum.Font.GothamBlack,
}

-- ═══════════════════════════ build helpers ══════════════════════════════
local function create(className, props, parent)
	local inst = Instance.new(className)
	for key, value in pairs(props or {}) do
		inst[key] = value
	end
	if parent then
		inst.Parent = parent
	end
	return inst
end

local function corner(inst, radius)
	return create("UICorner", {
		CornerRadius = UDim.new(0, radius),
		Parent = inst,
	})
end

local function stroke(inst, color, thickness, transparency)
	return create("UIStroke", {
		Color = color or Theme.border,
		Thickness = thickness or 1,
		Transparency = transparency or 0,
		ApplyStrokeMode = Enum.ApplyStrokeMode.Border,
		Parent = inst,
	})
end

local function padding(inst, top, right, bottom, left)
	return create("UIPadding", {
		PaddingTop = UDim.new(0, top),
		PaddingRight = UDim.new(0, right),
		PaddingBottom = UDim.new(0, bottom),
		PaddingLeft = UDim.new(0, left),
		Parent = inst,
	})
end

local function tween(inst, seconds, props)
	tweenService:Create(inst, TweenInfo.new(seconds, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), props):Play()
end

---Safely resolve a UI parent container, avoiding permission blocks.
local function getSafeGuiContainer()
	local container = nil
	if gethui then
		local ok, result = pcall(gethui)
		if ok and result then
			container = result
		end
	end
	if not container then
		container = coreGui
	end
	if not container then
		container = localPlayer:WaitForChild("PlayerGui")
	end
	return container
end

-- ═════════════════════════════ game logic ═══════════════════════════════
local function getHeroAccentColor(heroName)
	if powersConfig and type(powersConfig.POWERS) == "table" and powersConfig.POWERS[heroName] then
		local cfg = powersConfig.POWERS[heroName]
		if cfg.Accent then return cfg.Accent end
		if cfg.Red then return cfg.Red end
		if cfg.Glow then return cfg.Glow end
	end
	return DEFAULT_ACCENTS[heroName] or Color3.fromRGB(226, 158, 62)
end

local function equipHero(heroName)
	if not heroName or heroName == "" then
		return
	end
	activeHero = heroName

	local equipPowerRemote = replicatedStorage:FindFirstChild("EquipPower")
	if equipPowerRemote then
		pcall(function()
			equipPowerRemote:FireServer(heroName)
		end)
	end

	pcall(function()
		localPlayer:SetAttribute("PowerOverride", heroName)
	end)
end

-- ═══════════════════════════════ the UI ═════════════════════════════════
local function buildUserInterface()
	local parent = getSafeGuiContainer()

	local screenGui = create("ScreenGui", {
		Name = "HeroPowerHub",
		ResetOnSpawn = false,
		DisplayOrder = 9999,
		ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
		IgnoreGuiInset = true,
	})

	-- ── floating launcher ──────────────────────────────────────────────
	local launcher = create("TextButton", {
		Name = "HubLauncher",
		Size = UDim2.fromOffset(92, 30),
		Position = UDim2.new(0, 18, 0.24, 0),
		BackgroundColor3 = Theme.surface,
		AutoButtonColor = false,
		Text = "HERO HUB",
		Font = Theme.fontBold,
		TextSize = 11,
		TextColor3 = Theme.accent,
		Parent = screenGui,
	})
	corner(launcher, 7)
	local launcherStroke = stroke(launcher, Theme.accentDim, 1, 0.15)

	-- ── drop shadow ────────────────────────────────────────────────────
	local shadow = create("Frame", {
		Name = "Shadow",
		Size = UDim2.fromOffset(560, 430),
		Position = UDim2.new(0.5, -276, 0.5, -211),
		BackgroundColor3 = Color3.new(0, 0, 0),
		BackgroundTransparency = 0.55,
		BorderSizePixel = 0,
		ZIndex = 1,
		Parent = screenGui,
	})
	corner(shadow, 14)

	-- ── main window ────────────────────────────────────────────────────
	local main = create("Frame", {
		Name = "Main",
		Size = UDim2.fromOffset(560, 430),
		Position = UDim2.new(0.5, -280, 0.5, -215),
		BackgroundColor3 = Theme.backdrop,
		BorderSizePixel = 0,
		Active = true,
		Draggable = true,
		Visible = true,
		ZIndex = 2,
		Parent = screenGui,
	})
	corner(main, 12)
	stroke(main, Theme.border, 1, 0)
	local mainScale = create("UIScale", { Scale = 1, Parent = main })

	-- header -----------------------------------------------------------
	local header = create("Frame", {
		Name = "Header",
		Size = UDim2.new(1, 0, 0, 58),
		BackgroundColor3 = Theme.surface,
		BorderSizePixel = 0,
		Active = true,
		Parent = main,
	})
	corner(header, 12)

	create("Frame", {
		Name = "HeaderMask",
		Size = UDim2.new(1, 0, 0, 12),
		Position = UDim2.new(0, 0, 1, -12),
		BackgroundColor3 = Theme.surface,
		BorderSizePixel = 0,
		Parent = header,
	})

	create("Frame", {
		Name = "AccentBar",
		Size = UDim2.new(1, -24, 0, 2),
		Position = UDim2.new(0, 12, 0, 0),
		BackgroundColor3 = Theme.accent,
		BorderSizePixel = 0,
		Parent = header,
	})

	local title = create("TextLabel", {
		Name = "Title",
		Size = UDim2.new(1, -110, 0, 24),
		Position = UDim2.fromOffset(18, 12),
		BackgroundTransparency = 1,
		Font = Theme.fontBlack,
		Text = "HERO POWER HUB",
		TextSize = 15,
		TextColor3 = Theme.text,
		TextXAlignment = Enum.TextXAlignment.Left,
		Parent = header,
	})

	local subtitle = create("TextLabel", {
		Name = "Subtitle",
		Size = UDim2.new(1, -110, 0, 16),
		Position = UDim2.fromOffset(18, 32),
		BackgroundTransparency = 1,
		Font = Theme.fontMedium,
		Text = "Destruction Battlegrounds  ·  " .. #ALL_HEROES .. " abilities",
		TextSize = 11,
		TextColor3 = Theme.textMuted,
		TextXAlignment = Enum.TextXAlignment.Left,
		Parent = header,
	})

	local closeButton = create("TextButton", {
		Name = "Close",
		Size = UDim2.fromOffset(26, 26),
		Position = UDim2.new(1, -38, 0, 16),
		BackgroundColor3 = Theme.surfaceAlt,
		AutoButtonColor = false,
		Font = Theme.fontBold,
		Text = "×",
		TextSize = 16,
		TextColor3 = Theme.textMuted,
		Parent = header,
	})
	corner(closeButton, 6)
	local closeStroke = stroke(closeButton, Theme.borderSoft, 1, 0.4)

	closeButton.MouseEnter:Connect(function()
		tween(closeButton, 0.12, { BackgroundColor3 = Theme.danger, TextColor3 = Color3.new(1, 1, 1) })
		tween(closeStroke, 0.12, { Transparency = 0 })
	end)
	closeButton.MouseLeave:Connect(function()
		tween(closeButton, 0.12, { BackgroundColor3 = Theme.surfaceAlt, TextColor3 = Theme.textMuted })
		tween(closeStroke, 0.12, { Transparency = 0.4 })
	end)

	-- active hero bar --------------------------------------------------
	local statusBar = create("Frame", {
		Name = "StatusBar",
		Size = UDim2.new(1, -32, 0, 38),
		Position = UDim2.fromOffset(16, 68),
		BackgroundColor3 = Theme.surface,
		BorderSizePixel = 0,
		Parent = main,
	})
	corner(statusBar, 8)
	stroke(statusBar, Theme.borderSoft, 1, 0)

	local statusAccent = create("Frame", {
		Name = "StatusAccent",
		Size = UDim2.new(0, 3, 1, -16),
		Position = UDim2.fromOffset(12, 8),
		BackgroundColor3 = getHeroAccentColor(activeHero),
		BorderSizePixel = 0,
		Parent = statusBar,
	})
	corner(statusAccent, 2)

	local statusLabel = create("TextLabel", {
		Name = "StatusLabel",
		Size = UDim2.new(1, -230, 0, 14),
		Position = UDim2.fromOffset(24, 6),
		BackgroundTransparency = 1,
		Font = Theme.fontBold,
		Text = string.upper(activeHero),
		TextSize = 12,
		TextColor3 = Theme.text,
		TextXAlignment = Enum.TextXAlignment.Left,
		Parent = statusBar,
	})

	local statusCaption = create("TextLabel", {
		Name = "StatusCaption",
		Size = UDim2.new(1, -230, 0, 12),
		Position = UDim2.fromOffset(24, 20),
		BackgroundTransparency = 1,
		Font = Theme.fontMedium,
		Text = "CURRENTLY EQUIPPED",
		TextSize = 9,
		TextColor3 = Theme.textFaint,
		TextXAlignment = Enum.TextXAlignment.Left,
		Parent = statusBar,
	})

	local reapplyButton = create("TextButton", {
		Name = "Reapply",
		Size = UDim2.fromOffset(88, 24),
		Position = UDim2.new(1, -100, 0.5, -12),
		BackgroundColor3 = Theme.accentDim,
		AutoButtonColor = false,
		Font = Theme.fontBold,
		Text = "RE-APPLY",
		TextSize = 10,
		TextColor3 = Theme.accent,
		Parent = statusBar,
	})
	corner(reapplyButton, 6)
	local reapplyStroke = stroke(reapplyButton, Theme.accent, 1, 0.55)

	reapplyButton.MouseEnter:Connect(function()
		tween(reapplyButton, 0.12, { BackgroundColor3 = Theme.accent })
		tween(reapplyStroke, 0.12, { Transparency = 0 })
	end)
	reapplyButton.MouseLeave:Connect(function()
		tween(reapplyButton, 0.12, { BackgroundColor3 = Theme.accentDim })
		tween(reapplyStroke, 0.12, { Transparency = 0.55 })
	end)

	reapplyButton.MouseButton1Click:Connect(function()
		equipHero(activeHero)
	end)

	-- search -----------------------------------------------------------
	local searchBar = create("Frame", {
		Name = "SearchBar",
		Size = UDim2.new(1, -32, 0, 34),
		Position = UDim2.fromOffset(16, 114),
		BackgroundColor3 = Theme.surface,
		BorderSizePixel = 0,
		Parent = main,
	})
	corner(searchBar, 8)
	local searchStroke = stroke(searchBar, Theme.borderSoft, 1, 0)

	local glass = create("Frame", {
		Name = "SearchGlass",
		Size = UDim2.fromOffset(9, 9),
		Position = UDim2.fromOffset(14, 11),
		BackgroundTransparency = 1,
		BorderSizePixel = 0,
		Parent = searchBar,
	})
	corner(glass, 9)
	stroke(glass, Theme.textFaint, 1.5, 0)

	create("Frame", {
		Name = "SearchHandle",
		Size = UDim2.fromOffset(5, 1.5),
		Position = UDim2.fromOffset(21, 20),
		Rotation = 45,
		BackgroundColor3 = Theme.textFaint,
		BorderSizePixel = 0,
		Parent = searchBar,
	})

	local searchInput = create("TextBox", {
		Name = "Input",
		Size = UDim2.new(1, -120, 1, 0),
		Position = UDim2.fromOffset(32, 0),
		BackgroundTransparency = 1,
		Font = Theme.fontMedium,
		PlaceholderText = "Search abilities",
		PlaceholderColor3 = Theme.textFaint,
		Text = "",
		TextSize = 12,
		TextColor3 = Theme.text,
		TextXAlignment = Enum.TextXAlignment.Left,
		ClearTextOnFocus = false,
		Parent = searchBar,
	})

	local resultCount = create("TextLabel", {
		Name = "ResultCount",
		Size = UDim2.fromOffset(64, 34),
		Position = UDim2.new(1, -72, 0, 0),
		BackgroundTransparency = 1,
		Font = Theme.fontMedium,
		Text = "",
		TextSize = 10,
		TextColor3 = Theme.textFaint,
		TextXAlignment = Enum.TextXAlignment.Right,
		Parent = searchBar,
	})

	searchInput.Focused:Connect(function()
		tween(searchStroke, 0.15, { Color = Theme.accent, Transparency = 0.25 })
	end)
	searchInput.FocusLost:Connect(function()
		tween(searchStroke, 0.15, { Color = Theme.borderSoft, Transparency = 0 })
	end)

	-- categories -------------------------------------------------------
	local categoryBar = create("ScrollingFrame", {
		Name = "Categories",
		Size = UDim2.new(1, -32, 0, 26),
		Position = UDim2.fromOffset(16, 156),
		BackgroundTransparency = 1,
		BorderSizePixel = 0,
		ScrollBarThickness = 0,
		ScrollingDirection = Enum.ScrollingDirection.X,
		CanvasSize = UDim2.new(0, 0, 0, 0),
		AutomaticCanvasSize = Enum.AutomaticSize.X,
		Parent = main,
	})
	create("UIListLayout", {
		FillDirection = Enum.FillDirection.Horizontal,
		SortOrder = Enum.SortOrder.LayoutOrder,
		Padding = UDim.new(0, 6),
		VerticalAlignment = Enum.VerticalAlignment.Center,
		Parent = categoryBar,
	})

	-- ability grid -----------------------------------------------------
	local grid = create("ScrollingFrame", {
		Name = "Abilities",
		Size = UDim2.new(1, -32, 1, -226),
		Position = UDim2.fromOffset(16, 192),
		BackgroundColor3 = Theme.surface,
		BorderSizePixel = 0,
		ScrollBarThickness = 3,
		ScrollBarImageColor3 = Theme.border,
		CanvasSize = UDim2.new(0, 0, 0, 0),
		AutomaticCanvasSize = Enum.AutomaticSize.Y,
		Parent = main,
	})
	corner(grid, 8)
	stroke(grid, Theme.borderSoft, 1, 0.3)
	padding(grid, 8, 6, 8, 8)

	create("UIGridLayout", {
		CellSize = UDim2.fromOffset(124, 32),
		CellPadding = UDim2.fromOffset(6, 6),
		SortOrder = Enum.SortOrder.LayoutOrder,
		Parent = grid,
	})

	-- footer -----------------------------------------------------------
	local footer = create("TextLabel", {
		Name = "Footer",
		Size = UDim2.new(1, -32, 0, 18),
		Position = UDim2.new(0, 16, 1, -26),
		BackgroundTransparency = 1,
		Font = Theme.fontMedium,
		Text = "Right Shift toggles this window  ·  drag the header to move",
		TextSize = 10,
		TextColor3 = Theme.textFaint,
		TextXAlignment = Enum.TextXAlignment.Left,
		Parent = main,
	})

	-- ═════════════════════════════ behaviour ═══════════════════════════
	local heroButtons = {}
	local categoryButtons = {}

	local function applyHeroVisual(heroName, button, hovered)
		local isSelected = (heroName == activeHero)
		local accent = getHeroAccentColor(heroName)
		local label = button:FindFirstChild("Label")

		if isSelected then
			button.BackgroundColor3 = accent
			if label then
				label.TextColor3 = Theme.backdrop
			end
		else
			button.BackgroundColor3 = hovered and Theme.surfaceHover or Theme.surfaceAlt
			if label then
				label.TextColor3 = Theme.text
			end
		end

		local s = button:FindFirstChildOfClass("UIStroke")
		if s then
			s.Color = isSelected and accent or Theme.borderSoft
			s.Transparency = isSelected and 0 or 0.35
		end

		local marker = button:FindFirstChild("Marker")
		if marker then
			marker.BackgroundColor3 = isSelected and Theme.backdrop or accent
			marker.BackgroundTransparency = isSelected and 0.35 or 0.1
		end
	end

	local function refreshHeroList()
		local query = currentSearch:lower():gsub("%s+", "")
		local pool = CATEGORY_MAP[activeCategory] or ALL_HEROES
		local shown = 0

		for heroName, button in pairs(heroButtons) do
			local matchesCategory = table.find(pool, heroName) ~= nil
			local matchesSearch = (query == "") or (heroName:lower():find(query, 1, true) ~= nil)
			local visible = matchesCategory and matchesSearch
			button.Visible = visible
			if visible then
				shown = shown + 1
				applyHeroVisual(heroName, button, false)
			end
		end

		statusLabel.Text = string.upper(activeHero)
		statusAccent.BackgroundColor3 = getHeroAccentColor(activeHero)
		resultCount.Text = shown .. " / " .. #ALL_HEROES
	end

	-- ============ ability buttons ============
	for order, heroName in ipairs(ALL_HEROES) do
		local button = create("TextButton", {
			Name = "Ability_" .. heroName,
			BackgroundColor3 = Theme.surfaceAlt,
			BorderSizePixel = 0,
			AutoButtonColor = false,
			Text = "",
			LayoutOrder = order,
			Parent = grid,
		})
		corner(button, 6)
		stroke(button, Theme.borderSoft, 1, 0.35)

		local marker = create("Frame", {
			Name = "Marker",
			Size = UDim2.fromOffset(2, 12),
			Position = UDim2.new(0, 7, 0.5, -6),
			BackgroundColor3 = getHeroAccentColor(heroName),
			BorderSizePixel = 0,
			ZIndex = 3,
			Parent = button,
		})
		corner(marker, 2)

		local label = create("TextLabel", {
			Name = "Label",
			Size = UDim2.new(1, -22, 1, 0),
			Position = UDim2.fromOffset(16, 0),
			BackgroundTransparency = 1,
			Font = Theme.fontBold,
			Text = heroName,
			TextSize = 11,
			TextColor3 = Theme.text,
			TextXAlignment = Enum.TextXAlignment.Left,
			TextTruncate = Enum.TextTruncate.AtEnd,
			ZIndex = 2,
			Parent = button,
		})

		button.MouseEnter:Connect(function()
			if heroName ~= activeHero then
				tween(button, 0.12, { BackgroundColor3 = Theme.surfaceHover })
				local s = button:FindFirstChildOfClass("UIStroke")
				if s then tween(s, 0.12, { Transparency = 0.1 }) end
			end
		end)
		button.MouseLeave:Connect(function()
			applyHeroVisual(heroName, button, false)
		end)
		button.MouseButton1Click:Connect(function()
			equipHero(heroName)
			refreshHeroList()
		end)

		heroButtons[heroName] = button
	end

	-- ============ category pills ============
	local categoryOrder = { "All", "Meta", "Anime", "Comics", "Magic", "Brawlers" }

	for order, catName in ipairs(categoryOrder) do
		local pill = create("TextButton", {
			Name = "Tab_" .. catName,
			Size = UDim2.new(0, 0, 1, 0),
			AutomaticSize = Enum.AutomaticSize.X,
			BackgroundColor3 = Theme.surfaceAlt,
			BorderSizePixel = 0,
			AutoButtonColor = false,
			Font = Theme.fontBold,
			Text = string.upper(catName),
			TextSize = 9,
			TextColor3 = Theme.textMuted,
			LayoutOrder = order,
			Parent = categoryBar,
		})
		corner(pill, 6)
		local pillStroke = stroke(pill, Theme.borderSoft, 1, 0)
		padding(pill, 0, 10, 0, 10)

		local function paintPill()
			local selected = (catName == activeCategory)
			pill.BackgroundColor3 = selected and Theme.accent or Theme.surfaceAlt
			pill.TextColor3 = selected and Theme.backdrop or Theme.textMuted
			pillStroke.Transparency = selected and 1 or 0
		end

		pill.MouseEnter:Connect(function()
			if catName ~= activeCategory then
				tween(pill, 0.12, { BackgroundColor3 = Theme.surfaceHover, TextColor3 = Theme.text })
			end
		end)
		pill.MouseLeave:Connect(paintPill)
		pill.MouseButton1Click:Connect(function()
			activeCategory = catName
			for name, otherPill in pairs(categoryButtons) do
				local selected = (name == activeCategory)
				otherPill.BackgroundColor3 = selected and Theme.accent or Theme.surfaceAlt
				otherPill.TextColor3 = selected and Theme.backdrop or Theme.textMuted
				local s = otherPill:FindFirstChildOfClass("UIStroke")
				if s then s.Transparency = selected and 1 or 0 end
			end
			refreshHeroList()
		end)

		categoryButtons[catName] = pill
		paintPill()
	end

	-- ============ input / window ============
	searchInput:GetPropertyChangedSignal("Text"):Connect(function()
		currentSearch = searchInput.Text
		refreshHeroList()
	end)

	local function setWindowVisible(visible)
		if visible == main.Visible then
			return
		end
		if visible then
			main.Visible = true
			shadow.Visible = true
			mainScale.Scale = 0.96
			tween(mainScale, 0.16, { Scale = 1 })
		else
			main.Visible = false
			shadow.Visible = false
		end
	end

	closeButton.MouseButton1Click:Connect(function()
		setWindowVisible(false)
	end)

	-- keep the shadow glued to the window while it is dragged
	main:GetPropertyChangedSignal("Position"):Connect(function()
		shadow.Position = main.Position + UDim2.fromOffset(4, 4)
	end)

	launcher.MouseButton1Click:Connect(function()
		setWindowVisible(not main.Visible)
	end)

	launcher.MouseEnter:Connect(function()
		tween(launcher, 0.12, { BackgroundColor3 = Theme.surfaceAlt, TextColor3 = Theme.text })
		tween(launcherStroke, 0.12, { Transparency = 0 })
	end)
	launcher.MouseLeave:Connect(function()
		tween(launcher, 0.12, { BackgroundColor3 = Theme.surface, TextColor3 = Theme.accent })
		tween(launcherStroke, 0.12, { Transparency = 0.15 })
	end)

	-- expose for the keybind handler
	DestructionBattlegrounds._setWindowVisible = setWindowVisible

	refreshHeroList()
	screenGui.Parent = parent
	guiRoot = screenGui
end

-- ═════════════════════════════ lifecycle ═══════════════════════════════
local function initializeHeartbeat()
	local respawnConnection = localPlayer.CharacterAdded:Connect(function()
		if activeHero and activeHero ~= "" then
			task.wait(0.35)
			equipHero(activeHero)
		end
	end)
	table.insert(connections, respawnConnection)

	local keyConnection = userInputService.InputBegan:Connect(function(input, gameProcessed)
		if gameProcessed then
			return
		end
		if input.KeyCode == Enum.KeyCode.RightShift then
			local toggle = DestructionBattlegrounds._setWindowVisible
			if toggle then
				local main = guiRoot and guiRoot:FindFirstChild("Main")
				if main then
					toggle(not main.Visible)
				end
			end
		end
	end)
	table.insert(connections, keyConnection)
end

function DestructionBattlegrounds.detach()
	for _, connection in ipairs(connections) do
		if typeof(connection) == "RBXScriptConnection" and connection.Connected then
			connection:Disconnect()
		end
	end
	table.clear(connections)

	DestructionBattlegrounds._setWindowVisible = nil

	if guiRoot then
		guiRoot:Destroy()
		guiRoot = nil
	end
end

local function initializeScript()
	buildUserInterface()
	initializeHeartbeat()
end

local function onInitializeError(err)
	warn("Failed to initialize HeroPowerHub:")
	warn(tostring(err))
	warn(debug.traceback())
	DestructionBattlegrounds.detach()
end

xpcall(initializeScript, onInitializeError)

shared.DestructionHub = DestructionBattlegrounds
return DestructionBattlegrounds
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.

+1 Destruction Battlegrounds 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 +1 Destruction Battlegrounds script?

A +1 Destruction Battlegrounds script is third-party Lua code intended to run alongside the Roblox game through a compatible script executor.

What features does this +1 Destruction Battlegrounds script include?

Different scripts contain different code and features. Check the script menu after it loads to see everything it offers.

How do you use the +1 Destruction Battlegrounds 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 +1 Destruction Battlegrounds 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 +1 Destruction Battlegrounds 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