How can I make this system more optimized?

I have a system of attracting coins to the player, which I realized using RunService and it works fine, but as soon as the map will lie 700 + simultaneous objects Heartbeat begins to fall.

And that’s why I have a question, can i do something like this system without loops, because I saw in other games with a similar system drops no such lags in a large number of objects

function Handler:collect()
	self.Connections['distance']:Disconnect()
	local part : BasePart = self.Part
	local charprimary = VARIABLES.player.Character.PrimaryPart
	local cleanup = LinearVelocity(part, charprimary)
	local Time = 0
	part:SetAttribute('PickUp', true)
	self.Connections['distance'] = SERVICES.RunService.Heartbeat:Connect(function(deltaTime: number) 

		local distance = Distance(
			part.Position,
			VARIABLES.player.Character.PrimaryPart.Position
		)

		if distance <= 1 then
			cleanup()
			self:destroy()
		end
		
		Time += deltaTime
		
		if Time >= 5 then
			cleanup()
			self.Connections['distance']:Disconnect()
			self:start()
		end
	end)
end

function Handler:start()
	--if not dropCache.checkCache() then
	--	self:destroy()
	--	return
	--end
	local part : BasePart = self.Part
	self.Connections = {

	}

	self.Connections['distance'] = SERVICES.RunService.Stepped:Connect(function(deltaTime: number) 
		local data = SERVICES.HttpService:JSONDecode(VARIABLES.player:GetAttribute('PlayerData'))
		local distanceTocollect = data.Upgrades.DistanceToCollectDrops

		local distance = Distance(
			part.Position,
			VARIABLES.player.Character.PrimaryPart.Position
		)

		if distance <= distanceTocollect then
			self:collect()
		end
	end)
	
	self.untilDestroyThread = task.delay(60, self.destroy, self)
end

You can create a hitbox around the coin, which when touched collects it

1 Like

You could use a LinearVelocity contraint. Also, every coin does not have their own seperate script, right? That would create copius amounts of lag

Okay thanks I will try to do it. Yes you are right all coins are handled by 1 module script

This is where you offload the work to the player if possible. Have the client render and run tasks on the visible coins their side and do a request to pick up the coin. On a larger map, this will make a difference as you can use CollectionService to only do operations on loaded parts.

All the client does is check the distances and that’s it. In addition, the coins are removed within a minute if the player has not picked them up

You should use WorldRoot for getting which coins are close to the player. This will be slower than your current method with a low amount of coins on the map, but using GetPartBoundsInRadius wont get laggier as more coins are added

Instead of detecting the distance from every coin, WorldRoot allows you to get the coins in a region

1 Like