Best way to debounce?

Is there an easy and efficient way to debounce when using OOP?

I am currently working on a tycoon made using OOP. Whilst I have tried to create an efficient debounce method to ensure that drops do not fire a touched event multiple times when touching upgraders and collectors, if there is a high volume of drops, some ignore the debounce.

Below you can see a clump of drops worth 8 billion, when the upgrader was only supposed to double the original value of 2 billion.

3 Likes

It would be helpful to know the current method you’re using before offering an alternative or a fix. Just to hazard a guess, you probably want to have the debounce on the objects rather than the machine.

3 Likes

Yeah post your code if you want more specific help.

Anyway, probably don’t use “debounces”, it’s an old anti pattern that just sticks around for some reason. Use separate logic that keeps track of what things each drop has already interacted with instead, and use that to prevent double interactions.

5 Likes

Hi, sorry about my inactivity but would using GetTouchingParts() be a viable alternative or region3 possibly?

1 Like

GetTouchingParts, GetPartsInRegion3 and GetPartsInPart / the other spatial querying functions are definitely “viable”, but Touched should work no matter how many parts are in the game. Are you sure Touched is failing to fire and that it’s not your code / debounce stuff that’s the cause? Feel free to post your code and I’ll see if I can spot anything wrong.

1 Like

Here is the debounce function (I know it’s not perfect), however I didn’t mean to say that touched is failing to fire (its that it is firing too many times between the wait’s).

		drop.Touched:Connect(function(hit) -- This may need tweaking if it fires too much and could possibly cause lag
			if hit.Name == "Detector" or hit.Name == "Collider" then -- dont use or
				print("Drop hit detector or collider")
				task.wait(0.1) -- Ignore this it was for testing
				drop:SetAttribute("Debounce", true)
				task.wait(0.2)
				drop:SetAttribute("Debounce", false)
			end
		end)

		Debris:AddItem(drop, 20)

Why are you waiting 0.1s before setting the debounce? Maybe that’s the issue?
Also what’s the part of the code where you actually double the cash?

When “drop” is touched by the Detector or the Collider, after 0.1s turns Debounce attribute to True, after 0.3s turns attribute to false; if the “drop” still touching a Detector or Collider will trigger the function again, caused by mutiple touches.

You could use TouchEnded:Connect() event too, to know where to disable the Debouce attribute.

When hit Detector or Collider, Debounce attribute to true. And when drop.TouchEnded() Debounce attribute to false.

Or consider another approach as ThanksRoBama, as if you are already using OOP, handling the “boost” of the drop in a different way, considering different events to do it

Why do you need to set the debounce to false at all, if you’re just going to destroy the dropper after 20 seconds?

Im not sure why you asking to me :sweat_smile:
Thats the OP’s conveyour belt and drops, idk whats OP’s plan with the drops the debounces etc
I just mentioned that the issue is related with multiple touches that the drop has against the collider and detector thing

1 Like

Hi, that 0.1 was just for testing purposes, sorry I left it in the post. However, I have tried the code without it and the drops can still fire the touched event more than once.

Sorry, the 0.1 was just for testing purposes however the issue still continues after I remove it. I have heard about the TouchEnded event before, but I was told it was unreliable.

i think its because you forgot to check if the debounce attribute was true or not and to make it not run if its true

should be something like

if drop:GetAttribute("Debounce") == false and (hit.Name == "Detector" or hit.Name == "Collider") then

1 Like

If you did set your debounce attribute to true when using Touched event, then whats the difference on not using TouchEnded event?, Im not saying its perfect, Im saying the issue its related with multiple touches from the drop.

1 Like

Whenever the object gets into the upgrader, you could immediately add it to a table and make sure when objects go thru it they arent in the table before adding value to the object.

1 Like

Unfortunately this still does not work completely, although it appears to decrease the amount of drops being multiplied more than once. For now I’ll try to configure a table based system (possibly a module in itself) using region3 or something similar. When I complete I will post it here for anyone to use.

1 Like

if u just want to upgrade the drop once, u can just set the debounce once only

local db = false
item.Touched:Connect(function(hit)
	if hit.Name == "Upgrader" and db == false then
		db = true
		--do stuff
	end
end)
1 Like

Thanks for the idea, but TouchEnded is also buggy. As when there is a high volume of drops it seems like the event fires at random increments and cannot cope with lag.

This would work in my game demonstration however in practice the drop will go through multiple upgraders and then a collector before it is deposited (which all obviously need to debounced as well).

I’ve never been a fan of TouchEnded, preferring instead to use spatial query, but in this case I reckon using two parts with .Touched connected¹ might work? One as an entrance which adds the debounce and one as an exit which clears the debounce. (A backup timer would be good)

If you’re designing a sandbox tycoon game similar to that of Miner’s Haven, checking to see if the part enters another tile’s space could also serve to clear the debounce.

¹: Using your method of .Touched on the money blocks themselves would also work, just another condition to check.

1 Like