Everything is working fine when you play solo on studio but when you upload the game onto Roblox and try it the start starts lagging or something but only when there are two NPCs, the first one works completely fine until there are more than two NPCs.
https://gyazo.com/ede126aa799d1342ecf7e1098087affc
Modulescript:
local AI = {} AI.__index = AI local PhysicsService = game:GetService("PhysicsService") local playerCollisionGroupName = "NPCs" local PhysicsService = game:GetService("PhysicsService") local playerCollisionGroupName = "Players" PhysicsService:CreateCollisionGroup(playerCollisionGroupName) PhysicsService:CollisionGroupSetCollidable(playerCollisionGroupName, playerCollisionGroupName, false) local Points = {} local Last10Points = {} local function setCollisionGroupRecursive(object) if object:IsA("BasePart") then PhysicsService:SetPartCollisionGroup(object, playerCollisionGroupName) end for _, child in ipairs(object:GetChildren()) do setCollisionGroupRecursive(child) end end local function Tablecontains(table, element) for i,v in pairs(table) do if table == element then return true end end return false end local function CreatePool(player) local AssetsGuest = game.ReplicatedStorage.AssetsGuest local IslandGuest = AssetsGuest.IslandGuest:Clone() IslandGuest.Parent = workspace.LocalDump IslandGuest.Name = "Bob" setCollisionGroupRecursive(IslandGuest) local SpawnPositions = workspace.Map.Tiles local Index = math.random(1, #SpawnPositions:GetChildren()) local ChosenPoint = SpawnPositions:GetChildren()[Index] IslandGuest:SetPrimaryPartCFrame(CFrame.new(ChosenPoint.PrimaryPart.Position) + Vector3.new(0, 5, 0)) return IslandGuest end local WaitForMoveToFinished do local RunService = game:GetService("RunService") function WaitForMoveToFinished(self, position, timeout) local initTime = tick() timeout = timeout or 1e3 local position2D = Vector3.new(position.X, self.RootPart.Position.Y, position.Z) while ((self.RootPart.Position - position2D).magnitude > 2.5 and tick() - initTime < timeout) do RunService.Heartbeat:Wait() end end end function AI:CreatePath() local PathFindingService = game:GetService("PathfindingService") local Path = PathFindingService:FindPathAsync(self.StartTile.Position, self.TargetDestination.Position) local Waypoints = Path:GetWaypoints() for i = 2, #Waypoints do local lastWaypoint = Waypoints[i - 1] local currentWaypoint = Waypoints[i] local segment = Instance.new("LineHandleAdornment") local lastPosition = lastWaypoint.Position + Vector3.new(0, 0.5, 0) - self.StartTile.Position local currentPosition = currentWaypoint.Position + Vector3.new(0, 0.5, 0) - self.StartTile.Position local toCurrent = currentPosition - lastPosition local distance = toCurrent.Magnitude return currentWaypoint.Position end end function AI:GetTarget() if #Last10Points >= 10 then Last10Points = {} end local Index = math.random(1, #Points) repeat Index = math.random(1, #Points) wait() until not Tablecontains(Last10Points, Points[Index]) local Point = Points[Index] self.TargetDestination = Point self.StartTile = self.RootPart if (self.TargetDestination.Position - self.RootPart.Position).magnitude > 40 then return self.TargetDestination, Index else repeat Index = math.random(1, #Points) wait() print("waiting") until not Tablecontains(Last10Points, Points[Index]) print("seccond man choise duuuddee") local Point = Points[Index] self.TargetDestination = Point self.StartTile = self.RootPart return self.TargetDestination, Index end end function AI:New(player) local self = { Model = CreatePool(player), -- Name = Name, RootPart = nil, Humanoid = nil, StartTile = nil, LastTarget = nil, TargetDestination = nil, TimeElapsed = tick(), TimeUntilDestination = 0, STATE_OCCUPIED = 0, STATE_QUEUED = 0, STATE_WANDERING = 0, STATE_IDLE = 0, } setmetatable(self, AI) for i,v in pairs(workspace:GetDescendants()) do if v.Name == "Path" then if not Tablecontains(Points, v.PrimaryPart) then table.insert(Points, v.PrimaryPart) end end end self.RootPart = self.Model:FindFirstChild("HumanoidRootPart") self.Humanoid = self.Model:FindFirstChild("Humanoid") return self end function AI:Roam() local STATE_OCCUPIED = self.STATE_OCCUPIED local STATE_QUEUED = self.STATE_QUEUED local STATE_WANDERING = self.STATE_WANDERING local STATE_IDLE = self.STATE_IDLE local reachedPoint = true while (true) do if STATE_OCCUPIED == 0 and STATE_QUEUED == 0 and STATE_WANDERING == 0 then STATE_WANDERING = 1 local Target, Index if (reachedPoint) then Target, Index = self:GetTarget() reachedPoint = false end local Position = self:CreatePath() if not Position then repeat wait() Position = self:CreatePath() until Position end self.Humanoid:MoveTo(Position) --self.Humanoid.MoveToFinished:Wait() WaitForMoveToFinished(self, Position, 2) if (self.RootPart.Position - self.TargetDestination.Position).magnitude < 10 then reachedPoint = true table.insert(Last10Points, Points[Index]) end STATE_WANDERING = 0 if STATE_OCCUPIED == 0 and STATE_QUEUED == 0 and STATE_WANDERING == 0 then STATE_IDLE = 1 end end wait(0) end end return AI