Consider this source code:
[code]Soundstage is a room.
The time of day is 9:00 AM.
When play begins: change the right hand status line to “[time of day]”.
Instead of singing:
say “You begin a song that will last for three minutes.”;
the song ends in three minutes from now.
At the time when the song ends:
say “You finish singing.”
At 9:05 AM:
say “The spotlight comes on.”
Test me with “z/z/sing/z/z/z”.[/code]
The last two rules both fire on the same turn, yielding this:
z
Time passes.
The spotlight comes on.
You finish singing.
How does Inform determine which one fires first? Is there any way to make the spotlight rule fire second?
Experimenting a bit, if we replace the “At 9:05 AM:” rule with this:
[code]When play begins:
the lights come on in five minutes from now.
At the time when the lights come on:
say “The spotlight comes on.”[/code]
the “lights come on” event still fires before the “song ends” rule. Is it that the event that is scheduled first fires first? Answer: no;
[code]At 9:04 AM:
the lights come on in one minute from now.
At the time when the lights come on:
say “The spotlight comes on.”[/code]
still has the lights come on first.
So, is there any way to control this, or any rhyme or reason to the scheduling?
eu1
(eu)
April 29, 2014, 12:22pm
2
A timed event is a rule stored in the |TimedEventsTable|, an I6 table array: zero entries in this table are ignored, and the sequence is significant only if more than one event goes off at the same moment, in which case earlier entries go off first. Each rule in the table has a corresponding timer value in |TimedEventTimesTable|. If this is negative, it represents a number of turns to go before the event happens – or properly speaking, the number of times the timed events rule is invoked. Otherwise the timer value must be a valid time of day at which the event happens (note that valid times are all non-negative integers). We allow a bracket of 30 minutes after the event time proper; this is designed to cope with situations in which the user sets some timed events, then advances the clock by hand (or uses a long step time, say in which each turn equates to 20 minutes).
Because an event is struck out of the table just before it is fired, it will not continue to go off the rest of the half-hour. Moreover, because the striking out happens {\it before} rather than after the rule fires, a rule can re-time itself to go off again later, somewhat like the snooze feature on an alarm clock, without the risk of it going off again immediately in the same use of the timed events rule: there is guaranteed to be a blank slot in the timer array at or before the current position because we have just blanked one.
Events are added to these tables at compile time in source code order, at runtime by finding the first matching or open slot and filling it.
So, in your first example, the 9:05 rule is added to slot 1 at compile time, then the finish singing rule is added in slot 2.
Likewise, in your second example, the spotlight rule is added to slot 1 at runtime, then the singing rule ends up in slot 2.
In your third example, the 9:04 rule occupies slot 1, the singing rule gets slot 2, the 9:04 rule fires, opening slot 1, and then the spotlight rule reclaims slot 1.
It would not be hard for an I6 coder to write an extension to manage this behavior; I would do it, but I’m tight on time until this weekend.
Thanks! In the meantime, maybe I’ll use an Every turn rule for the event that’s supposed to fire first, or just leave them in a slightly wrong order (it’s not that big a deal).
The extension “Phrases for Adaptive Pacing” might have some bits you could play with to put things in order.