Implementing a game clock in Harlowe 3.1.0 (Twine 2.3.5)

Please specify version and format if asking for help, or apply optional tags above:
Twine Version: 2.3.5
Story Format: Harlowe 3.1.0

After finding the current-time macro (which reports the time on the user’s system clock) I wondered how to make a game-clock, which would report the time in-game.

So using some code frankly stolen from @Greyelf, here’s my effort. You can advance the time by any number of hours and minutes on the player traversing a link, or even set the time directly if the player chooses to go to sleep. Much to my surprise, it even rolls back the time advance when the player clicks “undo.”

Harlowe doesn’t allow the user to write functions at time of writing, but you can get the same effect by putting all the code into a passage, and then displaying that passage wherever you want the game-clock to be displayed.

The code below uses Twee notation (& I hope I’m getting it right, I use the GUI.)

:: indicates the name of a passage

:: Start

// Set the initial time you want the game clock to show: e.g. Sat., 11:58 PM
(set: $day to "Sat")
(set: $hrs to 11)
(set: $ampm to "PM")
(set: $mins to 58)
// zero these variables below which are used to advance the time
(set: $inc_ampm to false)
(set: $inc_day to false)
(set: $inc_hrs to 0)
(set: $inc_mins to 0)

"Gosh!" said the Princess it's (display: "game clock") already!"
// we have to use a setter link if we want to advance the clock

(link: "Run upstairs")[(set: $inc_mins to 5)(goto: "Ballroom")]

:: Ballroom

"And now it's (display: "game clock")- Tomorrow!" she says, wiping her brow. "Boy, was that a long staircase."

// The actual game clock passage which does the math
::game clock
{(set: $mins to it + $inc_mins)
(if: $mins > 59)[(set: $mins to it - 60)(set: $inc_hrs to it + 1)]
(set: $hrs to it + $inc_hrs)
(if: $hrs > 11)[
	(set: $hrs to it - 12)
		(if: $ampm is "PM")[
			(set: $inc_day to true)(set: $ampm to "AM")]
		(else:)[(set: $ampm to "PM")]
(if: $inc_day is true)[
	(if: $day is "Sat")[(set: $day to "Sun")]
	(else-if: $day is "Sun")[(set: $day to "Mon")]
	(else-if: $day is "Mon")[(set: $day to "Tue")]
	(else-if: $day is "Tue")[(set: $day to "Wed")]
	(else-if: $day is "Wed")[(set: $day to "Thu")]
	(else-if: $day is "Thu")[(set: $day to "Fri")]
	(else:)[(set: $day to "Sat")]
(if: $hrs is 6 and $ampm is "AM")[(set: $isnight to false)]
(if: $hrs is 7 and $ampm is "PM")[(set: $isnight to true)]

}''$day.,&nbsp;$hrs:(if: $mins < 10)[0]$mins&nbsp;$ampm''
(set: $inc_mins to 0)
(set: $inc_hrs to 0)
(set: $inc_ampm to false)
(set: $inc_day to false) }
<!-- zero out the increment variables so they don't keep advancing the clock --!>

bug in clock code fixed that caused it to always show PM.
Simple day/night cycle added.
(if: $isnight)[this text will only show at night]
(if: not $isnight)[this text will show during the day]
Of course you can use (else:) as well.)

If you want to put this clock in the sidebar, then you need to edit the game’s stylesheet.

Click on the upward pointing arrow in the bottom bar of the Gui, and choose “Edit story stylesheet” from the list. The element you want to tinker with is called “tw-sidebar”

I’m not sure what position: relative actually //does,// (it’s “absolute” in the twine stylesheet,) so this may break the game in some non-obvious way – use at your own risk!

  padding-left: 1em;
  width: 10em;
  position: relative;
  left: -11em;  

As you can see I jiggered with the sidebar width, and also the value of the “left” parameter (notice that the number is //negative.)// I found it was easier to mess around with the sidebar if I temporarily set its background color to something with a really nasty contrast, and then I just jiggered with it until it looked right.

So anyway, use it, hammer on it, improve it, but above all enjoy it. The cool way of faking a function was Greyelf’s, but all the errors and ugliness are mine.

I hope you all stay healthy in this dire Coronavirus time.


Well done.

In the industry we like to call that ‘adapted from’, ‘enhancing’ or ‘extending’. :lol:

But in all seriousness, I place code on the forums & Discord servers for all to use as they will but being recognised as the ‘original’ provider does make me smile. (However as we say down here, “Put the money on the fridge!”)

You are quite correct in saying that, and unfortunately that fact is not likely to change in the foreseeable future. (but I could be wrong, I have been in the past and are likely to be again in the future :smile:)

However, the nice individual known as @Chapel has created a new thingie they like to name Chapel’s Unofficial Custom Macro Framework for Harlowe (a little wordy) that you may want to have a look at.

I thought the notion of using a passage in that way was really clever. I like it when coders make the code sit up and do tricks - IME the power balance is usually on the Tin Idiot’s side. I appreciate it when people take time to share their skills - it’s one of the things I like most about IF. Thanks for the link, I’ll have a look at it.


Thank you very much for this. I registered to say it was exactly what I was looking for.
Two small notes, to avoid having extra line breaks, you should enclose your entire game clock passage in {} curly braces.


:: Game clock
<all of your quite clever code>

:: Some other passage

and that you should initialise $isnight, otherwise if you check for darkness before checking the clock it will cause an error.

Thanks again!

1 Like