I7: Hourly clock chimes

I’m trying to make a clock that starts chiming on the hour and continues chiming once per turn for (hours part of the time of day) turns. This seems like it should be a simple task, but for some reason I’m having a lot of trouble getting it right. Here’s what I have currently:

[code]Chiming is a truth-state that varies. Chiming is usually false.

Every turn while chiming is true:
if the location is not indoors, say “‘BONG!’”;

The Tolling Bell is a recurring scene. The Tolling Bell begins when the minutes part of the time of day is 0. The Tolling Bell ends when chiming is false.

When the Tolling Bell begins:
if the location is not indoors, say “You hear the tolling of a distant bell. ‘BONG!’”;
[the first bong gets its own message, both so it can be more specific and because my every turn while chiming is true rule won’t take effect until the next turn]
let x be the remainder after dividing hours part of the time of day by 12;
if x is 0, now x is 12;
if x is not 1:
now chiming is true;
the clock stops chiming in x minus 2 turns from now;

At the time when the clock stops chiming:
now chiming is false.
[/code]

This seems to work as long as it’s not 1:00 or 2:00. At 1:00, I don’t want any more bongs after the initial one, so I’m not setting chiming to true. Unfortunately this seems to be causing the scene to end and then immediately start again in an infinite loop. I think the problem is stemming from the order that activities are processed.

In an ideal world, the code that I would like to work would be just:

[code]The Tolling Bell is a scene. The Tolling Bell begins when the minutes part of the time of day is 0. The Tolling Bell ends when the clock stops chiming.

Every turn during the Tolling Bell:
if the location is not indoors, say “BONG!”;

When the Tolling Bell begins:
now chiming is true;
if the location is not indoors, say “You hear the tolling of a distant bell. ‘BONG!’”;
let x be the remainder after dividing hours part of the time of day by 12;
if x is 0, now x is 12;
the clock stops chiming in x minus 1 turns from now;[/code]

But stopping 0 turns from now apparently doesn’t make it happen immediately, and Inform doesn’t accept “the clock stops chiming” as a condition for ending the scene, which is why I’m using the chiming truth-state, which is introducing problems because of the delay between toggling it and deciding whether to say “bong.”

I suspect there’s a much better way of doing this, but surprisingly I couldn’t find an example of this sort of thing in the documentation. Help!

Here’s a simple way to do it without using scenes (you need to add checks for being outdoors and so on):

[code]To decide which number is the 12-hour part of (X - a time):
if the hours part of X is 0 or the hours part of X is 12:
decide on 12;
decide on the remainder after dividing hours part of X by 12.

Every turn when the minutes part of time of day is less than the 12-hour part of time of day:
if minutes part of time of day is 0:
say “You hear the tolling of a distant bell. [run paragraph on]”;
say “‘BONG!’”.[/code]

That appears to be exactly what I need, and a lot neater than the way I was trying to do it. Thanks!

I’ve run into that infinite-loop problem with recurring scenes before. I think it almost qualifies as a bug - when would anyone want a recurring scene to start on the same turn that it ended?

In this case, however, it can be avoided. Having a variable that does nothing but tell whether a scene should be happening is a red flag for me, and indeed, you don’t need it here:

[code]Chimes is a number that varies.

Every turn during The Tolling Bell:
decrement chimes;
if the location is not indoors and chimes is at least 1, say “BONG!”

The Tolling Bell is a recurring scene. The Tolling Bell begins when the minutes part of the time of day is 0. The Tolling Bell ends when chimes is 0.

When The Tolling Bell begins:
now chimes is the remainder after dividing the hours part of the time of day by 12;
if chimes is 0, now chimes is 12;
If the location is not indoors, say “You hear the tolling of a distant bell. BONG!”
[/code]

Of course you still don’t need scenes, because the chimes variable tells you all you need to know:

[code]Chimes is a number that varies.

Every turn when chimes is at least 1:
if the location is not indoors, say “BONG!”;
decrement chimes;

Every turn when the minutes part of the time of day is 0:
now chimes is the remainder after dividing the hours part of the time of day by 12;
if chimes is 0, now chimes is 12;
if the location is not indoors, say “You hear the tolling of a distant bell. BONG!”;
decrement chimes;[/code]

The timing of this is slightly different if the game begins precisely on the hour, though - Scene changes happen before the banner text, and every turn rules happen after the player’s actions are complete.

I agree. I did try counting the number of chimes in an earlier attempt, but it annoyed me to have to use a global variable. I figured if I’m going to do that, I’d rather use a boolean and save a few bytes. That may be a ridiculous thing to worry about in this day and age, but old habits die hard. :stuck_out_tongue:

Booleans (“truth states”) and integers are the same size in I7. Sorry. :slight_smile:

and “whether The Tolling Bell is happening” is in effect a global variable anyway.

But if you really hate global variables, why not make chimes a property of the clock object? Or of The Tolling Bell scene? Or of the room where the tolling takes place?