Timer that resets itself?

What I wanted is a timer that, after it finishes, it resets itself.

For example, lets say you get food every 60 seconds. Then you run a script to eat it. After you eat, I want more food to arrive in 60 seconds.

The problem seems to be that the event repeats itself multiple times without me finishing the script to 'eat it'. So you get multiple eating scripts.


  1. Are you making a Gamebook or a Text Adventure?

  2. Are you using the desktop version of Quest or the online version?

  3. Do you really want to use a 60 second timer, or would it be better if triggered on the following turn?

  4. Can you post the bit of code you have, to make it easier for us to help you in this specific instance?



Small bug. If you eat the food, leave the room, and return it will spawn food immediately. Then 60 seconds after the eating, it will print "The waiter brings more food" again even if there's food there.

Small bug.

I must have changed some code after you copied it to test it. I can't get it to do that.

All the code posted is updated now.

Also, I updated my example to only wait 5 seconds rather than 60 for sanity's sake during testing.

Looks valid. I'm probably just confused.

Although I think it's odd that you can get food sooner by leaving and coming back.
I'd probably do something like:

<timer name="foodtimer">
    if (game.pov.parent = diner and not food.visible) {
      food.visible = true
      food.parent = diner
      msg ("The waiter brings you some {notfirst:more }{object:food}.")
    DisableTimer (this)

<object name="diner">
    if (GetBoolean (foodtimer, "enabled")) {
      msg ("As you return, the waiter calls that your food will be ready in a moment.")
    else if (not food.visible) {
      msg ("You ask for food, and the waiter takes your order.")
      EnableTimer (foodtimer)

  <object name="food">
    <eat type="script">
      msg ("Yum!")
      msg ("the waiter bustles over, clears away your plate, and says “I'll bring you more in a minute.”")
      this.visible = false
      EnableTimer (foodtimer)

Using a single timer rather than SetTimeout can be useful, because you can use EnableTimer to start it again, and it will always trigger 60 seconds after the last time it was enabled

Although I think it's odd that you can get food sooner by leaving and coming back.

Oh. Ha ha!

I guess it's an all you can eat joint? They bring you a plate as soon as you walk in, then check on you once a minute. :)


I was going to test it again after I updated Arch Linux, but something in the update broke my Quest install under WINE.

...and the web editor is not my friend; so, I don't play with it.

If this code is messed up, or if you need any other help, or if this code isn't really what you wanted, just say the word. Someone will fix you up!

Actually… I think there might still be a bug there, but it's a little less obvious.

Eat food, go out, go in (food is spawned), eat food (again). More food arrives 60 seconds after the first time you ate, which may be just a couple of seconds after you finished the other one depending on the player's typing speed.

I suppose this could be realistic… maybe you got a different waiter the second time, and each of them looks to see if you have food every minute, without realising that someone else is serving you in between. It depends what you want to happen.

But I think that rather than checking the existence of the food before spawning it, I would rather check for a running timer.

To do this with SetTimeout you would need to set an ID, so that you can use GetTimer to check if it currently exists. Or, as in my code, you could have a timer that always exists and just set or check its enabled flag.

I was aiming for:

10 enter diner
20 if food is not visible, waiter brings food
30 if food is eaten in diner, waiter brings more in 5 seconds
40 if food is eaten outside of diner, nothing happens
50 re-enter diner with no food, goto 10 (metaphorically)
60 re-enter diner with food, goto 30 (metaphorically)

So, I put the trigger for the timer on the eat verb on the food, which will end up calling a function, which should only bring food if the player is in the diner and there is no food.

I'll test it thoroughly after I figure out what the update to Arch changed that broke Quest under WINE.

Seems logical. But I think your line 50 should either be:

50 re-enter diner with no food and timer isn't running, goto 10 (metaphorically)


50 re-enter diner with no food, stop timer and goto 10 (metaphorically)

You're testing if there is food on the table, but not if the waiter is currently away getting you some.

Also, I should point out that your food.eaten_once is a little unnecessary complexity, unless you're doing something else with it. All you're doing is changing a message the first time it's printed, which there is already a text processor directive for. ({once: or {notfirst:, which you can use either or both of)

Oh! I see what you're saying about the main bug.

I have my timer on 5 seconds for testing, and I can't go out and back into to the diner within that time frame. That's why I couldn't recreate it.

Well, Quest opens in my Arch install now, but the screen is black.

Since my code is buggy, and I can't fix it right now, I'm removing it from the earlier posts.


I was using food.eaten_once to clear it out after leaving the diner. It seemed it shouldn't say "more" food the first time you get food during each visit.

Also, I just now looked at this on a desktop browser. I didn't even see the code you posted until just now, mrangel. Ha ha. Had I seen that, I'd have left this one be. :)

Thank you everyone for your help. Somehow I managed to fix the script by just putting a disable timer in the beginning of the script and then putting a 'enable timer' at the end of the script. (Theres a couple messages separated by 'wait for a key press', and in the last one is where the enable timer is)

Still learning but getting a bt better.

Log in to post a reply.