2nd Annoying Question; rate limited buttons?

Twine Version: 2.3.16
Story Format: Sugarcube 2.36.1

I am using TwineLab’s custom notify macro to alert the player to specific actions they take, and I am also playing a short alert sound effect. The system looks and feels really nice, however there is a delay in the sound and the amount of times a player can press the button. Obviously I don’t want overlapping audio, so the fact that the audio waits to be played until after the first effect has finished is good, but the delay between audio and click is quite annoying, albeit minor.

I’m wondering if there’s anyway to rate limit how many times a player can click a button. Let me clarify; obviously the user can click it as many times as they want, but I want to make it so that the button will only accept a response every second or so; that way when the item updates, it updates with the notification and sound effect all in relative sync with each other.

I thought about using the <<timed>> macro, but that doesn’t seem to offer what I need it to do. Any suggestions?

Actually, the <<timed>> macro combined with a little jQuery should work fine. Just do something like this:

<span class="disableme"><<button "Disabled for 1 second">>
	<<run $(".disableme button").prop("disabled", true)>>
	/* Other button code goes here. */
	<<timed 1s>>
		<<run $(".disableme button").prop("disabled", false)>>
	<</timed>>
<</button>></span>

That uses the jQuery .prop() method to disable and enable the button. It uses the <span>'s class in order to target those buttons, so if you have multiple buttons like this on the screen at the same time, then they’ll all get disabled or enabled at the same time.

Just replace the button text with the text you want, and the commented line with the code you want the button to run, and you should be good to go.

Enjoy! :slight_smile:

Awesome, thank you so much! I did wind up having to “modify” (see: play around with <<set>> and <<goto>> positioning) it slightly, because I completely forgot to mention that I use the

`passage()`

function to do live updates on stats, which was bypassing the timer function. I wound up using this as the actual end result.

<span class="disableme"><<button "Add 100 gold.">>\
    <<run $(".disableme button").prop("disabled", true)>>\
    <<notify 0.7s>>You added 100 gold!<</notify>>\
    <<if settings.allowEffects>><<audio "success" play>><</if>>\
	<<timed 0.7s>>\
		<<run $(".disableme button").prop("disabled", false)>>\
		<<set $invCurrencyGold to $invCurrencyGold + 100>>\
		<<goto `passage()`>>\
	<</timed>>\
<</button>></span>\

Which works flawlessly for what I need. Appreciate your help HiEv, you’re most knowledgeable!

A few notes:

  • You should probably update $invCurrencyGold immediately within the button, rather than when the <<timed>> macro triggers.
  • There’s usually no need to put “\” at the end of lines within a button, because normally none of that will be displayed.
  • Rather than reloading the passage to update stats, you could put each stat within a <span> with a unique ID, and then use the <<replace>> macro to update the stat immediately.

So the code might look something like:

''Gold:'' <span id="gold">$invCurrencyGold</span> coins

<span class="disableme"><<button "Add 100 gold.">>
	<<run $(".disableme button").prop("disabled", true)>>
	<<notify 0.7s>>You added 100 gold!<</notify>>
	<<set $invCurrencyGold += 100>>
	<<replace "#gold">>$invCurrencyGold<</replace>>
	<<if settings.allowEffects>>
		<<audio "success" play>>
	<</if>>
	<<timed 0.7s>>
		<<run $(".disableme button").prop("disabled", false)>>
	<</timed>>
<</button>></span>\

Hope that helps! :slight_smile:

Ah, I see! That’s a much better solution! Much more clean, and prevents page refreshing which I noticed restarts the music.

Is there anything wrong with me changing it from <<replace "#gold">> to <<replace ".gold">> (and then obviously <span class="gold"> instead of <span id="gold">), so I can change the display class in multiple points instead of needing a unique ID for each display?

If you’re displaying that information in multiple places, then that’s a fine solution.

FYI, just in case anyone reading this isn’t aware: HTML element IDs should be unique on the page, while multiple HTML elements can have the same class at the same time.