local function Q()local Q=workspace.CurrentCamera local R=Q.CFrame.p local Y=Q.CFrame.lookVector local n=(Constants.FOV_FUDGE_FACTOR*rad((Q.FieldOfView*Q.ViewportSize.x)/Q.ViewportSize.y))/2.0 for Q,R in pairs(dynamicInstances)do local Y=Q.source.WorldPosition local n=Q.drain.WorldPosition-Y if n.magnitude<.001 then n=Vector3.new(0,0,-0.001)end Q.length=n.magnitude Q.cframe=Util.makeOrientation(Y,n)Q.part.CFrame=Q.cframe Q.part.Emitter.CFrame=CFrame.new(Q.length/2,0,0)Q.part.Emitter.PointLight.Range=Q.length end for Q,x in pairs(arcInstances)do local D=Q.cframe.p-R local s=Q.cframe*vec3(Q.length,0,0)-R if acos(dot(D.unit,Y))>n and acos(dot(s.unit,Y))>n then if Q.visible then Q.visible=false Q.segmentsFolder.Parent=nil end elseif not Q.visible then Q.visible=true Q.segmentsFolder.Parent=MainFolder end Q.distance=(D.magnitude+s.magnitude)/2 end for Q,R in pairs(arcInstances)do if Q.visible then if Q.changed then Q.part.CFrame=Q.cframe Q.part.Emitter.CFrame=CFrame.new(Q.length/2,0,0)Q.part.Emitter.PointLight.Range=Q.length Q.changed=false end if Q.distance<Constants.MAX_DISTANCE then Q.arcRenderAmount=Q.arcRenderAmount+min(Q.numArcs/3,Constants.ARCS_PER_UPDATE*min(1,throttleDistanceModifier/Q.distance))updateArc(Q)end end end frameCount=frameCount+1 local x=tick()-frameTick if x>Constants.AUTO_THROTTLE_FRAME_INTERVAL then autoThrottleRatio=max(0,min(1,autoThrottleRatio+Constants.AUTO_THROTTLE_INCREMENT*(frameCount/x-Constants.AUTO_THROTTLE_TARGET)))segmentPerArc=floor((Constants.SEGMENT_PER_ARC_MIN+difSegmentsPerArc*autoThrottleRatio)+.5)throttleDistanceModifier=Constants.THROTTLE_DISTANCE_MODIFIER_MIN+difDistanceModifier*autoThrottleRatio frameCount=0 frameTick=tick()end end local function R()if numInstances<=0 then if heartbeatConnection then heartbeatConnection:Disconnect()heartbeatConnection=nil end else if not heartbeatConnection then heartbeatConnection=RunService.Heartbeat:Connect(Q)end end end

local function onHeartbeat()
	-- Cache camera-related values and references
	local camera = workspace.CurrentCamera
	local camPos = camera.CFrame.p
	local look = camera.CFrame.lookVector

	local fov = Constants.FOV_FUDGE_FACTOR * rad(camera.FieldOfView * camera.ViewportSize.x / camera.ViewportSize.y) / 2.0

	for v, _ in pairs(dynamicInstances) do
		local source = v.source.WorldPosition
		local axis = v.drain.WorldPosition - source
		if axis.magnitude < 0.001 then
			axis = Vector3.new(0, 0, -0.001)
		end
		v.length = axis.magnitude
		v.cframe = Util.makeOrientation(source, axis)
		v.part.CFrame = v.cframe
		v.part.Emitter.CFrame = CFrame.new(v.length/2, 0, 0)
		v.part.Emitter.PointLight.Range = v.length
	end

	-- Check if objects are on/off-screen
	for v, _ in pairs(arcInstances) do
		local camToSource = v.cframe.p - camPos
		local camToDrain = v.cframe * vec3(v.length, 0, 0) - camPos

		-- Check if on-screen:
		if acos(dot(camToSource.unit, look)) > fov and acos(dot(camToDrain.unit, look)) > fov then
			-- Else, make visible and reparent, if not already done
			-- Not on-screen, turn invisible and unparent if not already
			if v.visible then
				v.visible = false
				v.segmentsFolder.Parent = nil
			end
		elseif not v.visible then
			v.visible = true
			v.segmentsFolder.Parent = MainFolder
		end

		-- Set average distance to camera for throttling purposes
		v.distance = (camToSource.magnitude + camToDrain.magnitude) / 2
	end

	-- Check if objects should be updated and do so
	for v, _ in pairs(arcInstances) do
		-- Only update enabled and visible objects
		if v.visible then
			-- Update CFrame/Size of instances if object values were changed
			if v.changed then
				v.part.CFrame = v.cframe
				v.part.Emitter.CFrame = CFrame.new(v.length/2, 0, 0)
				v.part.Emitter.PointLight.Range = v.length
				v.changed = false
			end

			-- Update amount of arcs that can be rendered in this step (can be real, not just integer)
			if v.distance < Constants.MAX_DISTANCE then
				v.arcRenderAmount = v.arcRenderAmount + min(
					v.numArcs / 3,
					Constants.ARCS_PER_UPDATE * min(1, throttleDistanceModifier / v.distance)
				)
				updateArc(v)
			end
		end
	end

	-- Increase frame count
	frameCount = frameCount + 1

	-- Calculate time since last throttling check
	local deltaTime = tick() - frameTick

	-- Check if auto-throttling window has passed
	if deltaTime > Constants.AUTO_THROTTLE_FRAME_INTERVAL then
		-- Update auto-throttling ratio based on observed FPS w.r.t. target FPS
		autoThrottleRatio = max(0, min(1, autoThrottleRatio + Constants.AUTO_THROTTLE_INCREMENT
				* (frameCount / deltaTime - Constants.AUTO_THROTTLE_TARGET)))

		-- Update variables dependent on auto-throttling rate
		segmentPerArc = floor(Constants.SEGMENT_PER_ARC_MIN + (difSegmentsPerArc * autoThrottleRatio) + 0.5)
		throttleDistanceModifier = Constants.THROTTLE_DISTANCE_MODIFIER_MIN
			+ (difDistanceModifier * autoThrottleRatio)

		-- Reset tracking variables
		frameCount = 0
		frameTick = tick()
	end
end

local function updateConnection()
	if numInstances <= 0 then
		if heartbeatConnection then
			heartbeatConnection:Disconnect()
			heartbeatConnection = nil
		end
	else
		if not heartbeatConnection then
			heartbeatConnection = RunService.Heartbeat:Connect(onHeartbeat)
		end
	end
end
