Crippling lag issue

The function below is called every time a projectile is shot/created in the server and has been causing lag that gets worse with each projectile until the game crashes. The issue only happens when I create a test server, and I have already commented out much of the code.
If anyone can help explain this issue or help optimize my code I would be very grateful!

local characters = game.Players
local rayparams = RaycastParams.new()
rayparams.FilterDescendantsInstances = {characters}
print(damager)
local projectile = bullet:Clone()
projectile.CanQuery = false
projectile.Material = Enum.Material.Neon
projectile.Transparency = .5
projectile.Parent = game.Workspace
projectile.Size = Vector3.new(.1,.1,1)
projectile.CFrame = aestheticCFrame
projectile.Anchored = true
projectile.CanCollide = false

local projectileStartVector = projectile.Position
local MovementLoop
local hitCheck = false

local previousRayCFrame
local rayCFrame = realCFrame

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {damager}

local distance = (destination - realCFrame.Position).Magnitude
local time = distance / velocity

local distance2 = (destination - aestheticCFrame.Position).Magnitude
local velocity2 = distance2 / time
MovementLoop = game:GetService("RunService").Heartbeat:Connect(function()

	
	--[[]]
	previousRayCFrame = rayCFrame
	print(rayCFrame.Position - previousRayCFrame.Position)
	projectile.CFrame *= CFrame.new(0, 0, -velocity2 )
	rayCFrame *= CFrame.new(0,0, -velocity)

	--local collisionCheck = workspace:Raycast(previousRayCFrame.Position, rayCFrame.Position - previousRayCFrame.Position, raycastParams)


--	if collisionCheck and hitCheck == false  then
		
	--	hitCheck = true
		--local objectHit = collisionCheck.Instance
		--local plrHit = game.Players:GetPlayerFromCharacter(objectHit.Parent)
		
		--[[
		if plrHit ~= nil then
			if plrHit.UserId ~= damager.UserId then
				hitCheck = true -- if this is not disabled, lag machine fix later
				projectile:Destroy()
				MovementLoop:Disconnect()
				plrDictionary[plrHit.UserId]:Damage( plrDictionary[plrHit.UserId], 5 ,plrDictionary[damager.UserId], false)
				mainModule.HitEffect(collisionCheck.Position , collisionCheck.Normal)
			else
				print("hit yurself")
			end
		else
			hitCheck = true -- if this is not disabled, lag machine fix later
			projectile:Destroy()
			MovementLoop:Disconnect()

			mainModule.HitEffect(collisionCheck.Position , collisionCheck.Normal)
		end
		
		--]]
		
	--end

	if (projectile.Position - projectileStartVector).Magnitude >= 100 then
		projectile:Destroy()
		MovementLoop:Disconnect()
		hitCheck = true
	end
	
	
end)

end

I fixed the issue by changing the server from none to localserver. Does anyone know why this is?

The problem with that is that the projectile will only be visible on the client’s side, not to everyone in the server.

Ideally you would want to have the visual effects of the weapon being handled on the client. By constantly creating server-sided effects you’re putting a lot of strain in the server.

You want your network to more or less follow this route:

  1. Client sends input to use weapon, sends request to server

  2. Server receives request and fires a remote to all clients

  3. Clients receive request and creates the projectiles visual effects

How much delay would be caused? And how would I make it exploit proof?

Why would this be? If the script is being run in the server, would all clients not see the change?

The latency would ultimately depend on each clients connection to the server, but should theoretically be minimal.

As for making this exploit proof: there isn’t really much that would be exploitable from using this implementation. The worse I can see happening is clients being able to change the color/size of their projectiles but if done properly, this would only be client sided.