local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") local LocalPlayer = Players.LocalPlayer local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local HRP = Character:WaitForChild("HumanoidRootPart") local MAX_BLOCKS = 100 local DETECT_RADIUS = 30 local WANDER_RADIUS = 50 local INTERACT_DIST = 5 local spawnableParts = {} for _, obj in ipairs(Workspace:GetDescendants()) do if obj:IsA("BasePart") and obj.CanCollide and not obj:IsDescendantOf(Character) then table.insert(spawnableParts, obj) end end local function randomPointOnPart(part) local s = part.Size * 0.5 local offset = Vector3.new( math.random(-s.X, s.X), math.random(-s.Y, s.Y), math.random(-s.Z, s.Z) ) return part.Position + offset end local wanderers = {} local function spawnWanderer(atPlayerPosition) local spawnPos if atPlayerPosition and math.random() < 0.5 then spawnPos = HRP.Position + Vector3.new(0,2,0) else local part = spawnableParts[math.random(1,#spawnableParts)] spawnPos = randomPointOnPart(part) end local model = Instance.new("Model", Workspace) model.Name = "Wanderer" model:SetAttribute("Interacting", false) local root = Instance.new("Part", model) root.Name = "HumanoidRootPart" root.Size = Vector3.new(1,1,1) root.CFrame = CFrame.new(spawnPos) root.Anchored = false root.CanCollide = true local humanoid = Instance.new("Humanoid", model) humanoid.WalkSpeed = 20 humanoid.JumpPower = 0 model.PrimaryPart = root humanoid.Died:Connect(function() model:Destroy() task.delay(1, function() if #wanderers < MAX_BLOCKS then spawnWanderer(true) end end) end) table.insert(wanderers, model) end task.spawn(function() while true do if #wanderers < MAX_BLOCKS then spawnWanderer() end task.wait(0.2) end end) task.spawn(function() while true do for i = #wanderers, 1, -1 do local w = wanderers[i] if not w.Parent or not w.PrimaryPart or not w:FindFirstChildOfClass("Humanoid") then table.remove(wanderers, i) else local root = w.PrimaryPart local hum = w:FindFirstChildOfClass("Humanoid") local dist = (root.Position - HRP.Position).Magnitude if dist < DETECT_RADIUS then root.CFrame = CFrame.new(root.Position, HRP.Position) hum:MoveTo(HRP.Position + Vector3.new( math.random(-5,5), 0, math.random(-5,5) )) else local wanderTarget = root.Position + Vector3.new( math.random(-WANDER_RADIUS,WANDER_RADIUS), 0, math.random(-WANDER_RADIUS,WANDER_RADIUS) ) hum:MoveTo(wanderTarget) end for _, other in ipairs(wanderers) do if other ~= w and not w:GetAttribute("Interacting") and other.PrimaryPart and not other:GetAttribute("Interacting") then local od = (root.Position - other.PrimaryPart.Position).Magnitude if od < INTERACT_DIST then w:SetAttribute("Interacting", true) other:SetAttribute("Interacting", true) task.spawn(function() root.CFrame = CFrame.new(root.Position, other.PrimaryPart.Position) other.PrimaryPart.CFrame = CFrame.new( other.PrimaryPart.Position, root.Position ) task.wait(5) w:SetAttribute("Interacting", false) other:SetAttribute("Interacting", false) end) end end end end end task.wait(1) end end)