Making stealth game for fun

accidentally posted this in the wrong category :sob:

anyway so im trying to make a stealth game for fun (if you played the game entry point im trying to make it like that)

anyway i have this script (local) located in the character

local r = game:GetService("RunService")
local npc = workspace.StarterCharacter
local char = game:GetService("Players").LocalPlayer.Character

function checkLineOfSight(startPosition, endPosition)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {char}

	local result = workspace:Raycast(startPosition, endPosition - startPosition, raycastParams)

	return result == nil
end

r.RenderStepped:Connect(function()
	local npctc = (char.Head.Position - npc.Head.Position).Unit
	local npcl = npc.Head.CFrame.LookVector

	local dP = npctc:Dot(npcl)

	if dP > 0.5 and checkLineOfSight(npc.Head.Position, char.Head.Position) then
		print("In field of view and visible")
	else
		print("Out of field of view or obstructed")
	end
end)

which works perfectly, when im in the NPC’s view it prints out in fov and when im not it prints out the other thing

now the problem is that this is a local script and its gonna be really annoying getting all the NPC’s, making them detect the player. and its gonna be really easy to exploit

so if anyone has an idea how to structure this it would be great