Best way to make Safe Spawn system?

My shooter game uses a safe spawn system, where it would find a spawn that is farthest from all enemies of a player. Although it currently works, I find it to be a big load of work for the server, and am currently looking for better, smoother ways.

Current Code:

local function GetBestSpawn(Player)
	if not Arena.SpawnFolder then return Vector3.new(0,100,0) end
	
	local Av = Arena.SpawnFolder:GetChildren()
	
	--get players who are ingame
	local IngamePlrs = {}
	for _,v in pairs(workspace.Characters:GetChildren()) do
		if Players:GetPlayerFromCharacter(v) then
			table.insert(IngamePlrs, v)
		end
	end
	
	--filter to dangerous players only (players who can kill you)
	local Teaming = Arena.TeamMode
	local Danger = {} --getting only the dangerous charmodels in here
	for _,en in pairs(IngamePlrs) do
		local plren = Players:GetPlayerFromCharacter(en)
		if plren then
			
			if Teaming then
				if plren.Team ~= Player.Team then
					table.insert(Danger, en)
				end
			else
				table.insert(Danger, en)
			end
			
		end
	end
	
	--Get closest dangerous person for every spawn
	local ClosestPoints = {}
	for _,sp in pairs(Av) do
		local closest
		
		for _,plr in pairs(Danger) do
			if plr.PrimaryPart then
				
				local Position = plr:GetPrimaryPartCFrame().p
				
				local Distance = (sp.Position - Position).magnitude
				
				if not closest then
					closest = Distance
				elseif Distance < closest then
					closest = Distance
				end
			end
		end
		
		if not closest then
			closest = 1000
		end
		
		ClosestPoints[sp] = closest
	end
	
	--pick the one that is the farthest
        --interesting mechanic to avoid spawn-kill is to get 3 of the farthest and get one at random
	local sortable = {}

	local chosen
	
	for sp, dist in pairs(ClosestPoints) do
		table.insert(sortable, {Point = sp, Distance = dist})
	end
	
	local m = 3
	if #sortable < m then m = #sortable end
	
	table.sort(sortable, function(a, b)
		return a.Distance > b.Distance
	end)
	
	chosen = sortable[math.random(1,m)]
	
	if not chosen then return Vector3.new(0,100,0) end
	
	return chosen.Point.Position
end

The code works, it’s just that i’m looking for a better way to do this, since this tends to lag sometimes. Any help is appreciated!

3 Likes