-- 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