--================================================== -- ZERO G CHAOTIC ATTRACTOR MARBLE -- Re-exec safe, fully unloadable, state resilient --================================================== --========== IF OLD VERSION EXISTS, DESTROY IT ========== if type(_G.ZeroGBounceController) == "table" and _G.ZeroGBounceController.Unload then pcall(function() _G.ZeroGBounceController.Unload() end) end --========== SERVICES ========== local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local Camera = workspace.CurrentCamera local player = Players.LocalPlayer if not player then return end --========== CONFIG ========== local SIZE = 6 local SPEED_MULTIPLIER = 120 local BOUNCE_FORCE = 150 local CHAOS_SPIN = 25 -- Gravity local GRAV = 0 -- 🧲 Attraction Settings local ATTRACTION_FORCE = 0 -- strength of pull local ATTRACTION_INTERVAL = 999999 -- seconds between nudges --========== CONTROLLER OBJECT ========== local Controller = {} Controller.Enabled = true Controller.Connections = {} Controller.CharConnections = {} Controller.OriginalGravity = workspace.Gravity Controller.OriginalCameraSubject = Camera.CameraSubject Controller.OriginalCollisions = {} _G.ZeroGBounceController = Controller --========== CLEAN RESTORE ========== function Controller.Unload() if not Controller.Enabled then return end Controller.Enabled = false -- Disconnect everything for _,c in pairs(Controller.Connections) do pcall(function() c:Disconnect() end) end for _,c in pairs(Controller.CharConnections) do pcall(function() c:Disconnect() end) end Controller.Connections = {} Controller.CharConnections = {} -- Restore gravity workspace.Gravity = Controller.OriginalGravity -- Restore camera pcall(function() Camera.CameraSubject = Controller.OriginalCameraSubject end) -- Restore collisions for part,state in pairs(Controller.OriginalCollisions) do if part and part.Parent then pcall(function() part.CanCollide = state end) end end Controller.OriginalCollisions = {} -- Restore humanoid state if player.Character then local hum = player.Character:FindFirstChildOfClass("Humanoid") if hum then pcall(function() hum.PlatformStand = false end) end end _G.ZeroGBounceController = nil end --========== APPLY EFFECT ========== local function ApplyToCharacter(character) if not Controller.Enabled then return end local humanoid = character:WaitForChild("Humanoid") local ball = character:WaitForChild("HumanoidRootPart") workspace.Gravity = GRAV -- Save and disable collisions for _,v in ipairs(character:GetDescendants()) do if v:IsA("BasePart") then if Controller.OriginalCollisions[v] == nil then Controller.OriginalCollisions[v] = v.CanCollide end v.CanCollide = false end end -- Marble transform ball.Shape = Enum.PartType.Ball ball.Size = Vector3.new(SIZE,SIZE,SIZE) ball.CanCollide = true humanoid.PlatformStand = true ball.CustomPhysicalProperties = PhysicalProperties.new(1,0,1,0,1) ball.Velocity = Vector3.new( math.random(-100,100), math.random(-100,100), math.random(-100,100) ) Camera.CameraSubject = ball --========== STATE REAPPLY ========== if Controller.CharConnections.StateChanged then Controller.CharConnections.StateChanged:Disconnect() end Controller.CharConnections.StateChanged = humanoid.StateChanged:Connect(function() if Controller.Enabled then humanoid.PlatformStand = true end end) --========== MOVEMENT + ATTRACTION LOOP ========== local lastAttract = 0 if Controller.Connections.Render then Controller.Connections.Render:Disconnect() end Controller.Connections.Render = RunService.RenderStepped:Connect(function(delta) if not Controller.Enabled then return end if UserInputService:GetFocusedTextBox() then return end -- Movement if UserInputService:IsKeyDown(Enum.KeyCode.W) then ball.Velocity += Camera.CFrame.LookVector * SPEED_MULTIPLIER * delta end if UserInputService:IsKeyDown(Enum.KeyCode.S) then ball.Velocity -= Camera.CFrame.LookVector * SPEED_MULTIPLIER * delta end if UserInputService:IsKeyDown(Enum.KeyCode.A) then ball.Velocity -= Camera.CFrame.RightVector * SPEED_MULTIPLIER * delta end if UserInputService:IsKeyDown(Enum.KeyCode.D) then ball.Velocity += Camera.CFrame.RightVector * SPEED_MULTIPLIER * delta end -- Chaos spin ball.RotVelocity += Vector3.new( math.random(-CHAOS_SPIN,CHAOS_SPIN), math.random(-CHAOS_SPIN,CHAOS_SPIN), math.random(-CHAOS_SPIN,CHAOS_SPIN) ) * delta -- Attraction timing lastAttract += delta if lastAttract >= ATTRACTION_INTERVAL then lastAttract = 0 local nearestRoot = nil local nearestDist = math.huge for _,other in ipairs(Players:GetPlayers()) do if other ~= player and other.Character then local root = other.Character:FindFirstChild("HumanoidRootPart") local hum = other.Character:FindFirstChildOfClass("Humanoid") if root and hum and hum.Health > 0 then local dist = (root.Position - ball.Position).Magnitude if dist < nearestDist then nearestDist = dist nearestRoot = root end end end end if nearestRoot then local direction = (nearestRoot.Position - ball.Position).Unit ball.Velocity += direction * ATTRACTION_FORCE end end end) -- Jump boost if Controller.Connections.Jump then Controller.Connections.Jump:Disconnect() end Controller.Connections.Jump = UserInputService.JumpRequest:Connect(function() if Controller.Enabled then ball.Velocity += Camera.CFrame.LookVector * BOUNCE_FORCE end end) end --========== CHARACTER HANDLING ========== Controller.CharConnections.CharacterAdded = player.CharacterAdded:Connect(function(char) task.wait(0.2) ApplyToCharacter(char) end) if player.Character then ApplyToCharacter(player.Character) end --========== UNLOAD KEY ========== Controller.Connections.UnloadKey = UserInputService.InputBegan:Connect(function(input,gpe) if gpe then return end if input.KeyCode == Enum.KeyCode.M then Controller.Unload() end end)