local Players = game:GetService("Players") local RunService = game:GetService("RunService") local SoundService = game:GetService("SoundService") local UserInputService = game:GetService("UserInputService") local TweenService = game:GetService("TweenService") local LocalPlayer = Players.LocalPlayer local PlayerGui = LocalPlayer:WaitForChild("PlayerGui") local Camera = workspace.CurrentCamera -- ============================================================ -- CLEAR OLD UI -- ============================================================ if PlayerGui:FindFirstChild("SuperRingPartsGUI") then PlayerGui.SuperRingPartsGUI:Destroy() end -- ============================================================ -- NETWORK -- ============================================================ if not getgenv().Network then getgenv().Network = { BaseParts = {}, Velocity = Vector3.new(14.4626, 14.4626, 14.4626) } Network.RetainPart = function(p) if p:IsA("BasePart") and p:IsDescendantOf(workspace) then table.insert(Network.BaseParts, p) p.CustomPhysicalProperties = PhysicalProperties.new(0, 0, 0, 0, 0) p.CanCollide = false end end RunService.Heartbeat:Connect(function() sethiddenproperty(LocalPlayer, "SimulationRadius", math.huge) for _, p in ipairs(Network.BaseParts) do if p:IsDescendantOf(workspace) then p.Velocity = Network.Velocity end end end) end -- ============================================================ -- SOUND -- ============================================================ local function play(id) local s = Instance.new("Sound", SoundService) s.SoundId = "rbxassetid://" .. id s:Play() s.Ended:Once(function() s:Destroy() end) end play("2865227271") -- ============================================================ -- STATE -- ============================================================ local PlayerState = {} local OrbitRadius = {} local PlayerMode = {} local parts = {} local selfActive = false local selfMode = "Orbit" local selfRadius = 50 local MODES = {"Orbit", "Circle", "Grid", "Spiral", "Vortex", "Scatter"} -- Selection state local selectedPlayer = nil -- player currently selected in-world local selectionBox = nil -- SelectionBox instance local selectionAdornee = nil -- the model being adorned local worldMenuGui = nil -- BillboardGui for in-world menu -- ============================================================ -- PART COLLECTION -- ============================================================ local function valid(p) return p:IsA("BasePart") and not p.Anchored and not p:IsDescendantOf(LocalPlayer.Character) end for _, d in ipairs(workspace:GetDescendants()) do if valid(d) then table.insert(parts, d) end end workspace.DescendantAdded:Connect(function(p) if valid(p) then table.insert(parts, p) end end) -- ============================================================ -- ARRANGEMENT MATH -- ============================================================ local scatterMap = {} local function getScatterOffset(part) if not scatterMap[part] then scatterMap[part] = Vector3.new( math.random(-1,1)*math.random(10,60), math.random(0,30), math.random(-1,1)*math.random(10,60) ) end return scatterMap[part] end local function getTargetPos(mode, center, radius, index, total, part) if mode == "Orbit" then local pos = part.Position local angle = math.atan2(pos.Z-center.Z, pos.X-center.X) + 0.02 return Vector3.new(center.X+math.cos(angle)*radius, center.Y, center.Z+math.sin(angle)*radius) elseif mode == "Circle" then local angle = (index/total)*math.pi*2 return Vector3.new(center.X+math.cos(angle)*radius, center.Y, center.Z+math.sin(angle)*radius) elseif mode == "Grid" then local cols = math.ceil(math.sqrt(total)) local row = math.floor((index-1)/cols) local col = (index-1)%cols local spacing = radius/cols*2 return Vector3.new(center.X+(col-cols/2)*spacing, center.Y, center.Z+(row-cols/2)*spacing) elseif mode == "Spiral" then local t = (index/total)*math.pi*6 local r = (index/total)*radius return Vector3.new(center.X+math.cos(t)*r, center.Y+(index/total)*20, center.Z+math.sin(t)*r) elseif mode == "Vortex" then local pos = part.Position local angle = math.atan2(pos.Z-center.Z, pos.X-center.X)+0.05 local dist = math.max(5,(Vector3.new(pos.X,center.Y,pos.Z)-center).Magnitude-2) return Vector3.new(center.X+math.cos(angle)*dist, center.Y, center.Z+math.sin(angle)*dist) elseif mode == "Scatter" then return center + getScatterOffset(part) end return center end local function applyArrangement(mode, center, radius, partList) local total = #partList for i, part in ipairs(partList) do local target = getTargetPos(mode, center, radius, i, total, part) local vel = (target - part.Position).Unit * 1200 if vel == vel then part.Velocity = vel end end end local function flingPartsAt(target) local total = #parts for i, part in ipairs(parts) do local angle = (i/total)*math.pi*2 local spread = Vector3.new(math.cos(angle), math.random()*2, math.sin(angle)) * math.random(600,1800) part.Velocity = (target - part.Position).Unit * 2400 + spread end end -- ============================================================ -- 2014 RETRO PALETTE -- ============================================================ local C_BG = Color3.fromRGB(30, 30, 30) -- dark grey bg local C_PANEL = Color3.fromRGB(45, 45, 45) -- panel local C_BORDER = Color3.fromRGB(80, 80, 80) -- border local C_TITLEBAR = Color3.fromRGB(0, 100, 170) -- classic Roblox blue titlebar local C_BTN = Color3.fromRGB(55, 55, 55) -- button bg local C_BTN_HOV = Color3.fromRGB(75, 75, 75) local C_GREEN = Color3.fromRGB(0, 170, 0) local C_RED = Color3.fromRGB(200, 40, 40) local C_YELLOW = Color3.fromRGB(220, 180, 0) local C_TEXT = Color3.fromRGB(230, 230, 230) local C_MUTED = Color3.fromRGB(160, 160, 160) local C_WHITE = Color3.fromRGB(255, 255, 255) local FONT = Enum.Font.Legacy -- pixelated 2014 font local FONT_MONO = Enum.Font.RobotoMono -- ============================================================ -- GUI ROOT -- ============================================================ local gui = Instance.new("ScreenGui", PlayerGui) gui.Name = "SuperRingPartsGUI" gui.ResetOnSpawn = false gui.DisplayOrder = 10 local function retro(parent, size, pos, bg, borderCol) local f = Instance.new("Frame", parent) f.Size = size f.Position = pos f.BackgroundColor3 = bg or C_BG f.BorderSizePixel = 2 f.BorderColor3 = borderCol or C_BORDER return f end local function retroBtn(parent, size, pos, text, col) local b = Instance.new("TextButton", parent) b.Size = size b.Position = pos b.Text = text b.Font = FONT b.TextSize = 14 b.TextColor3 = C_WHITE b.BackgroundColor3 = col or C_BTN b.BorderSizePixel = 2 b.BorderColor3 = C_BORDER b.AutoButtonColor = true return b end local function retroLabel(parent, size, pos, text, sz, col, align) local l = Instance.new("TextLabel", parent) l.Size = size l.Position = pos l.Text = text l.Font = FONT l.TextSize = sz or 14 l.TextColor3 = col or C_TEXT l.BackgroundTransparency = 1 l.TextXAlignment = align or Enum.TextXAlignment.Left return l end -- ============================================================ -- MAIN WINDOW -- ============================================================ local main = retro(gui, UDim2.new(0, 280, 0, 460), UDim2.new(0, 8, 0.5, -230), C_BG, C_BORDER ) -- Title bar (classic blue) local titleBar = retro(main, UDim2.new(1, 0, 0, 22), UDim2.new(0,0,0,0), C_TITLEBAR, C_BORDER ) retroLabel(titleBar, UDim2.new(1,-26,1,0), UDim2.new(0,4,0,0), "Ring Parts v9", 13, C_WHITE ) -- Minimize button (classic X style) local minBtn = retroBtn(titleBar, UDim2.new(0,20,0,20), UDim2.new(1,-22,0,1), "—", Color3.fromRGB(80,80,80)) local collapsed = retro(gui, UDim2.new(0,90,0,22), UDim2.new(0,8,1,-30), C_TITLEBAR, C_BORDER) retroLabel(collapsed, UDim2.new(1,-20,1,0), UDim2.new(0,4,0,0), "Ring Parts", 13, C_WHITE) local colExpand = retroBtn(collapsed, UDim2.new(0,20,0,20), UDim2.new(1,-22,0,1), "+", Color3.fromRGB(80,80,80)) collapsed.Visible = false do local dragging, dragStart, startPos titleBar.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging=true; dragStart=i.Position; startPos=main.Position end end) titleBar.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging=false end end) UserInputService.InputChanged:Connect(function(i) if dragging and i.UserInputType==Enum.UserInputType.MouseMovement 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) end minBtn.MouseButton1Click:Connect(function() main.Visible=false; collapsed.Visible=true end) colExpand.MouseButton1Click:Connect(function() main.Visible=true; collapsed.Visible=false end) -- Content area starts below titlebar local Y = 28 -- current y cursor inside main -- ============================================================ -- SECTION: MODE -- ============================================================ -- Divider label local function sectionLabel(text, y) local div = Instance.new("Frame", main) div.Size = UDim2.new(1,-8,0,1) div.Position = UDim2.new(0,4,0,y) div.BackgroundColor3 = C_BORDER div.BorderSizePixel = 0 retroLabel(main, UDim2.new(1,-8,0,14), UDim2.new(0,4,0,y+2), "[ "..text.." ]", 12, C_MUTED) return y+16 end Y = sectionLabel("ARRANGEMENT MODE", Y) local modeFrame = Instance.new("Frame", main) modeFrame.Size = UDim2.new(1,-8,0,58) modeFrame.Position = UDim2.new(0,4,0,Y) modeFrame.BackgroundTransparency = 1 local modeGrid = Instance.new("UIGridLayout", modeFrame) modeGrid.CellSize = UDim2.new(0,80,0,24) modeGrid.CellPadding = UDim2.new(0,3,0,3) local modeButtons = {} local selectedMode = "Orbit" local function setMode(mode) selectedMode = mode; selfMode = mode for plr, state in pairs(PlayerState) do if state=="Active" then PlayerMode[plr]=mode end end for _, b in pairs(modeButtons) do local active = b.Name==mode b.BackgroundColor3 = active and C_TITLEBAR or C_BTN b.TextColor3 = active and C_WHITE or C_MUTED b.BorderColor3 = active and C_WHITE or C_BORDER end end for _, mode in ipairs(MODES) do local b = retroBtn(modeFrame, UDim2.new(0,80,0,24), UDim2.new(0,0,0,0), mode, C_BTN) b.Name = mode; b.TextSize = 12 b.MouseButton1Click:Connect(function() setMode(mode) end) modeButtons[mode] = b end setMode("Orbit") Y = Y + 64 -- ============================================================ -- SECTION: RADIUS -- ============================================================ Y = sectionLabel("RADIUS", Y) local currentRadius = 50 local radiusRow = Instance.new("Frame", main) radiusRow.Size = UDim2.new(1,-8,0,26) radiusRow.Position = UDim2.new(0,4,0,Y) radiusRow.BackgroundTransparency = 1 local decBtn = retroBtn(radiusRow, UDim2.new(0,28,1,0), UDim2.new(0,0,0,0), "-", C_BTN) local incBtn = retroBtn(radiusRow, UDim2.new(0,28,1,0), UDim2.new(1,-28,0,0), "+", C_BTN) local radLbl = retroLabel(radiusRow, UDim2.new(1,-64,1,0), UDim2.new(0,32,0,0), "Radius: 50", 13, C_TEXT, Enum.TextXAlignment.Center) radLbl.BackgroundColor3 = C_PANEL; radLbl.BackgroundTransparency = 0 radLbl.BorderSizePixel = 1; radLbl.BorderColor3 = C_BORDER incBtn.MouseButton1Click:Connect(function() currentRadius+=5; selfRadius=currentRadius; radLbl.Text="Radius: "..currentRadius end) decBtn.MouseButton1Click:Connect(function() currentRadius=math.max(5,currentRadius-5); selfRadius=currentRadius; radLbl.Text="Radius: "..currentRadius end) Y = Y + 32 -- ============================================================ -- SECTION: SELF -- ============================================================ Y = sectionLabel("SELF TOGGLE", Y) local selfBtn = retroBtn(main, UDim2.new(1,-8,0,26), UDim2.new(0,4,0,Y), "[OFF] Apply to Myself", C_BTN) selfBtn.TextSize = 13 selfBtn.MouseButton1Click:Connect(function() selfActive = not selfActive if selfActive then selfBtn.Text="[ON] Apply to Myself" selfBtn.BackgroundColor3=C_GREEN else selfBtn.Text="[OFF] Apply to Myself" selfBtn.BackgroundColor3=C_BTN end end) Y = Y + 32 -- ============================================================ -- SECTION: PLAYER LIST -- ============================================================ Y = sectionLabel("PLAYERS", Y) local searchBox = Instance.new("TextBox", main) searchBox.Size = UDim2.new(1,-8,0,22) searchBox.Position = UDim2.new(0,4,0,Y) searchBox.PlaceholderText = "Search..." searchBox.Text = "" searchBox.Font = FONT searchBox.TextSize = 13 searchBox.BackgroundColor3 = C_PANEL searchBox.TextColor3 = C_TEXT searchBox.PlaceholderColor3 = C_MUTED searchBox.BorderSizePixel = 2 searchBox.BorderColor3 = C_BORDER Y = Y + 26 local playerList = Instance.new("ScrollingFrame", main) playerList.Size = UDim2.new(1,-8,0,140) playerList.Position = UDim2.new(0,4,0,Y) playerList.BackgroundColor3 = C_PANEL playerList.BorderSizePixel = 2 playerList.BorderColor3 = C_BORDER playerList.ScrollBarThickness = 6 playerList.ScrollBarImageColor3 = C_BORDER playerList.CanvasSize = UDim2.new(0,0,0,0) local listLayout = Instance.new("UIListLayout", playerList) listLayout.Padding = UDim.new(0,2) local plrButtons = {} local function buildPlayerList(filter) for _, b in pairs(plrButtons) do b:Destroy() end table.clear(plrButtons) for _, plr in ipairs(Players:GetPlayers()) do if plr ~= LocalPlayer then local nm = (plr.DisplayName.." "..plr.Name):lower() if filter and filter~="" and not nm:find(filter:lower()) then continue end PlayerState[plr] = PlayerState[plr] or "Idle" PlayerMode[plr] = PlayerMode[plr] or selectedMode local b = retroBtn(playerList, UDim2.new(1,-4,0,28), UDim2.new(0,2,0,0), plr.DisplayName.." ("..plr.Name..")", C_BTN) b.TextSize = 12 local function updateBtn() local active = PlayerState[plr]=="Active" b.BackgroundColor3 = active and C_GREEN or C_BTN b.TextColor3 = active and C_WHITE or C_MUTED b.Text = (active and "[ON] " or "[OFF] ")..plr.DisplayName.." ("..plr.Name..")" end updateBtn() b.MouseButton1Click:Connect(function() if PlayerState[plr]=="Active" then PlayerState[plr]="Idle" else PlayerState[plr]="Active" PlayerMode[plr]=selectedMode OrbitRadius[plr]=currentRadius end updateBtn() end) table.insert(plrButtons, b) end end playerList.CanvasSize = UDim2.new(0,0,0,listLayout.AbsoluteContentSize.Y+4) end searchBox:GetPropertyChangedSignal("Text"):Connect(function() buildPlayerList(searchBox.Text) end) Players.PlayerAdded:Connect(function() buildPlayerList(searchBox.Text) end) Players.PlayerRemoving:Connect(function(plr) PlayerState[plr]=nil; OrbitRadius[plr]=nil; PlayerMode[plr]=nil buildPlayerList(searchBox.Text) end) buildPlayerList() -- ============================================================ -- IN-WORLD SELECTION SYSTEM -- Click a player's character → green SelectionBox + floating menu -- Click again → red flash + fade out -- ============================================================ local function clearSelection() if selectionBox then selectionBox:Destroy(); selectionBox=nil end if worldMenuGui then worldMenuGui:Destroy(); worldMenuGui=nil end selectedPlayer = nil; selectionAdornee = nil end local function makeWorldMenu(plr, model) if worldMenuGui then worldMenuGui:Destroy() end local bg = Instance.new("BillboardGui", workspace) bg.Name = "RingPartsWorldMenu" bg.Adornee = model:FindFirstChild("HumanoidRootPart") or model.PrimaryPart or model bg.Size = UDim2.new(0, 140, 0, 80) bg.StudsOffset = Vector3.new(0, 3.5, 0) bg.AlwaysOnTop = true bg.MaxDistance = 200 -- Retro panel local panel = retro(bg, UDim2.new(1,0,1,0), UDim2.new(0,0,0,0), C_BG, C_GREEN) retroLabel(panel, UDim2.new(1,0,0,16), UDim2.new(0,0,0,0), plr.DisplayName, 13, C_WHITE, Enum.TextXAlignment.Center) -- FLING button local flingBtn = retroBtn(panel, UDim2.new(1,-8,0,24), UDim2.new(0,4,0,18), ">> FLING PARTS <<", C_RED) flingBtn.TextSize = 12 flingBtn.MouseButton1Click:Connect(function() local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then flingPartsAt(hrp.Position) -- Flash confirmation flingBtn.Text = "!! LAUNCHED !!" flingBtn.BackgroundColor3 = C_YELLOW task.delay(0.8, function() if flingBtn and flingBtn.Parent then flingBtn.Text = ">> FLING PARTS <<" flingBtn.BackgroundColor3 = C_RED end end) end end) -- ORBIT THIS PLAYER button local orbitBtn = retroBtn(panel, UDim2.new(1,-8,0,24), UDim2.new(0,4,0,46), "[ORBIT] Activate", C_TITLEBAR) orbitBtn.TextSize = 12 local function updateOrbitBtn() local active = PlayerState[plr]=="Active" orbitBtn.Text = active and "[ORBIT] Deactivate" or "[ORBIT] Activate" orbitBtn.BackgroundColor3 = active and C_GREEN or C_TITLEBAR end updateOrbitBtn() orbitBtn.MouseButton1Click:Connect(function() if PlayerState[plr]=="Active" then PlayerState[plr]="Idle" else PlayerState[plr]="Active" PlayerMode[plr]=selectedMode OrbitRadius[plr]=currentRadius end updateOrbitBtn() buildPlayerList(searchBox.Text) end) worldMenuGui = bg end local function selectPlayer(plr) local model = plr.Character if not model then return end -- If clicking the already-selected player → red flash then deselect if selectedPlayer == plr then -- Turn red if selectionBox then selectionBox.Color3 = C_RED selectionBox.SurfaceColor3 = C_RED -- Fade out local tw = TweenService:Create(selectionBox, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {LineThickness = 0, SurfaceTransparency = 1} ) tw:Play() tw.Completed:Connect(function() clearSelection() end) end if worldMenuGui then local tw = TweenService:Create(worldMenuGui, TweenInfo.new(0.4, Enum.EasingStyle.Linear), {} ) -- Tween the frame transparency manually local panel = worldMenuGui:FindFirstChildWhichIsA("Frame") if panel then TweenService:Create(panel, TweenInfo.new(0.4), {BackgroundTransparency=1}):Play() for _, c in ipairs(panel:GetDescendants()) do if c:IsA("TextLabel") or c:IsA("TextButton") then TweenService:Create(c, TweenInfo.new(0.4), {TextTransparency=1, BackgroundTransparency=1}):Play() end end end task.delay(0.5, function() if worldMenuGui then worldMenuGui:Destroy(); worldMenuGui=nil end end) end selectedPlayer = nil return end -- New selection clearSelection() selectedPlayer = plr selectionAdornee = model -- Green SelectionBox local sb = Instance.new("SelectionBox", workspace) sb.Adornee = model sb.Color3 = C_GREEN sb.SurfaceColor3 = C_GREEN sb.SurfaceTransparency = 0.85 sb.LineThickness = 0.08 selectionBox = sb makeWorldMenu(plr, model) end -- Clear selection if selected player's character is removed Players.PlayerRemoving:Connect(function(plr) if selectedPlayer==plr then clearSelection() end end) -- ============================================================ -- MOUSE CLICK DETECTION — click on any player character -- ============================================================ local mouse = LocalPlayer:GetMouse() mouse.Button1Down:Connect(function() -- Don't intercept GUI clicks local guiObjects = PlayerGui:GetGuiObjectsAtPosition(mouse.X, mouse.Y) if #guiObjects > 0 then return end local target = mouse.Target if not target then clearSelection(); return end -- Find which player owns this part for _, plr in ipairs(Players:GetPlayers()) do if plr ~= LocalPlayer and plr.Character and target:IsDescendantOf(plr.Character) then selectPlayer(plr) return end end -- Clicked empty space — deselect clearSelection() end) -- Update SelectionBox if character respawns Players.PlayerAdded:Connect(function(plr) plr.CharacterAdded:Connect(function(char) if selectedPlayer==plr then task.wait(0.1) selectPlayer(plr) end end) end) for _, plr in ipairs(Players:GetPlayers()) do plr.CharacterAdded:Connect(function() if selectedPlayer==plr then task.wait(0.1) selectPlayer(plr) end end) end -- ============================================================ -- MAIN LOOP -- ============================================================ RunService.Heartbeat:Connect(function() if selfActive then local hrp = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") if hrp then applyArrangement(selfMode, hrp.Position, selfRadius, parts) end end for plr, state in pairs(PlayerState) do if state=="Active" then local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then applyArrangement(PlayerMode[plr] or selectedMode, hrp.Position, OrbitRadius[plr] or currentRadius, parts) end end end end)