Reset variables when a day ends

Twine Version: 2.3.5
Story Format: Sugarcube 2

Well i have this widget below:
​--------------------------------------------------------------------------------------------------------------------------
/*

Date & Time Printing Widget Definitions

*/

/* Prints the current date ("{weekday} {month} {day}, {year}"). */

<<widget “date”>>\

<<print String.format("{0} {1} {2}, {3}",

GameDays[$gameDate.getDay()],

GameMonths[$gameDate.getMonth()],

$gameDate.getDate(),

$gameDate.getFullYear()

)>>\

<>

/* Prints the current time (12H). */

<<widget “time12hr”>>\

<<if $gameDate.getHours() eq 0>>\

12\

<<elseif $gameDate.getHours() gt 12>>\

<<print $gameDate.getHours() - 12>>\

<>\

<<print $gameDate.getHours()>>\

<>:\

<<if $gameDate.getMinutes() lt 10>>0<><<print $gameDate.getMinutes()>> \

<<if $gameDate.getHours() gte 12>>PM<>AM<>\

<>

/* Prints the current time (24H). */

<<widget “time24hr”>>\

<<if $gameDate.getHours() lt 10>>0<><<print $gameDate.getHours()>>:\

<<if $gameDate.getMinutes() lt 10>>0<><<print $gameDate.getMinutes()>>\

<>

/* Prints the current date and time (12H). */

<<widget “datetime”>><> <> (<>)<>

​--------------------------------------------------------------------------------------------------------------------------

And i want to reset a bunch of variable every time an day end.
My purpose is to player don´t eat more or use an specific item more than one or two times in a day.

For example breakfast. I created a variable $breakfast. So, the player eat, get energy restored and are unable to eat again from now on. I able to handle this with if is false and if is true.

But i want to that variable and other variables like that one reset whether the player sleeps or not.
So at the start of every day (00:00), variables like $breakfast resets.

Im learning alot reading documentation and questions in forums, but that specific question i can´t find anywhere. Help please?

Hi there!

First, if you need to paste code from Twine, make sure to put it inside a Preformatted text (shortcut: Ctrl + Shift + C) block so it appears correctly on the page.

I’m not exactly sure how you are passing time in your game, if you have a widget dedicated to it or if every action in the game just adds a few hours to the gameDate, but what I did in mine was something like this:

<<set _dateOld to $gameDate.toDateString()>>
	-- Action happens and time passes
<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	--Reset variables here
<</if>>

So, whenever time passes, I check if the date string has changed, if it did it means it is a new day and you can do whatever you need to do inside the if.

In my case it was easy because I had a centralized method for passing time in my game, but if you have actions that change time in several different passages you might need to create a widget to do this check whenever you perform an action that will update the gameTime.

Hope this helps you, and let me know if you have any questions! Good luck!

1 Like

Hello Hacd!

Thank you before anything else about trying to help me.
Below an passage of my game to serve as example on what i will try to clarify next.

<img src="Shm Resourses\your house\kitchen2.png" alt="" width="600px" height="500px">

<<link[[Your room|Your room]]>><<addmins 2>><</link>>
<<link[[Living room|Living room]]>><<addmins 2>><</link>>
<<link[[Bathroom|Shower]]>><<addmins 2>><</link>>
<<link[[Stepmother room|Stepmother room]]>><<addmins 2>><</link>>

<<link[[Go outside|Stone lane neighborhood]]>><<addmins 5>><</link>>

<<if $gameDate.getHours() gte 6 and $gameDate.getHours() lt 10 and $breakfastr is false>>
<<link[[Have a Breakfast|Breakfast]]>><<addmins 30>><</link>>
<<elseif $gameDate.getHours() gte 6 and $gameDate.getHours() lt 10 and $breakfastr is true>>
You've eaten your breakfast today and you're stuffed.
<<else>>
You can only have breakfast between 6:01 to 09:59.
<</if>>

<<if $gameDate.getHours() gte 8 and $gameDate.getHours() lt 9>>
Your stepmother <<link[[Lara|Lara Kitchen]]>><</link>> is here
<<else>>
<</if>>

“I’m not exactly sure how you are passing time in your game, if you have a widget dedicated to it or if every action in the game just adds a few hours to the gameDate”

I have an widget that easly add minutes, hours and even days. This widget was the widget i posted before. You can see in the code for example: <<addmins 2>> That will add 2 minutes in the game.

Also i know to how to target the specific day and hour like in the code example like below:

<<if $gameDate.getHours() gte 8 and $gameDate.getHours() lt 9>>

And if was a day to target i can put something like:

<<if GameDays[$gameDate.getDay()] is "Mon">> Open
<<elseif GameDays[$gameDate.getDay()] neq "Mon">> Closed
<</if>>

But the main question is about that line:

<<if $gameDate.getHours() gte 6 and $gameDate.getHours() lt 10 and $breakfastr is false>>
<<link[[Have a Breakfast|Breakfast]]>><<addmins 30>><</link>>
<<elseif $gameDate.getHours() gte 6 and $gameDate.getHours() lt 10 and $breakfastr is true>>
You've eaten your breakfast today and you're stuffed.
<<else>>
You can only have breakfast between 6:01 to 09:59.
<</if>>

So, in my Storyini special passage i set the variable $breakfastr to false. This means the player did not eat the breakfast so far.

Then, when he click to have a breakfast he will go to another passage that add all benefits that include this action and in this passage the $breakfastr is set to true.
Then he is unable to perform that action anymore. Works =)

But now, i can’t figure how i will target or say to twine that one day has end in this specific widget that i have, and when day ends, the variable $breakfastr is reset to false to the player so he can have breakfast again.

That’s it. Thank you again for your reply and now i know how to (crt+shift+c) =D

Please Gray Elf and Mad Exile, lend me your powers!

All right, since you already have widgets to add time it should be really simple. All you have to do is add that bit of code I posted to your addmins widget and all your other widgets that add hours and days. I imagine it would look something like this:

<<widget addmins>>
<<set _dateOld to $gameDate.toDateString()>>
	
<<set $gameDate to new Date($gameDate.getTime() + $args[0] * 60000)>>

<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	<<set $breakfest to false>>
<</if>>
<</widget>>

I tested this and it seems to work as you want it to, unless I’m missing something.

1 Like

I’m not in home right now. But when i come back, i will test this.

Thank you once again!

As explained excellently by @Hacd, you just need to change the macro(s) associated with the updating of the current value of your project’s Date/Time sub-system so that it/they also conditionally reset your variables as needed.

The only difference I would suggest is to place the variable resetting code within a child Passage and to use the <<include>> macro to execute that passage’s contents as needed.
(untested code follows)
eg. Have a Reset Variables passage.

<<set $breakfest to false>>
<<set $variable to "original value>>

… and include it within the widget like so…

<<widget addmins>>
<<set _dateOld to $gameDate.toDateString()>>
	
<<set $gameDate to new Date($gameDate.getTime() + $args[0] * 60000)>>

<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	<<include "Reset Variables">>
<</if>>
<</widget>>
1 Like

@Greyelf, thank you for showing up. I have learned alot from you and TheMadExile previsious posts.
You guys are fundamental in my learning process so far. You guys illuminate the path to alot of people and this includes me.

But this time i will atribute the solution to @Hacd, even though I’m already using your suggestion of child passage. I would say thanks again to @Hacd but I already said it twice so I believe he understood that I really appreciate the help.

Intuitively I discovered that 60000 means milliseconds. So I adapted the $ args [0] for the amount of mileseconds equivalent to hours and days.

So for everyone who needs a clock that defines the year, month, day, day of the week, hour and minute please consider using the widget below.

This widget still resets variables when a day passes. Just create a child passage and call it with include macro. Logically in this passage you will want to have all the variables changes you want.

The idea of this clock was originally created by TheMadExile, and adapted by Hacd and GreyElf.

/*
	Date & Time Widget Setup
*/
<<set
	window.GameDays to [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
	];
	window.GameMonths to [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	];

	/*
		Below we have to use the multi-parameter version of the Date
		constructor, rather than the date string version, because the
		date string version treats a missing timezone offset as UTC.
		While there are ways to determine players' timezone offsets,
		so they could be added to a date string, it's more convenient
		simply to use the multi-parameter constructor.

		The point of this is so that you can simply initialize the game
		world clock to whatever date and time you wish without having to
		worry about the players' timezone offsets, while still ensuring
		that they all see the same game world dates and times.
	*/
	/* params: year , month(0-based) , day , hour(24H) , minute [, second ] */
	$gameDate to new Date(2020, 3, 17, 8, 15); /* e.g. Mar 17, 2015 03:24 */
>>


/*
	Date & Time Advancement Widget Definitions
*/
/* Adds the specified number of minutes. */
<<widget "addmins">>
<<set _dateOld to $gameDate.toDateString()>>
	
<<set $gameDate to new Date($gameDate.getTime() + $args[0] * 60000)>>

<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	<<include "Reset Variables">>
<</if>>
<</widget>>

/* Adds the specified number of hours. */
<<widget "addhours">>
<<set _dateOld to $gameDate.toDateString()>>
	
<<set $gameDate to new Date($gameDate.getTime() + $args[0] * 3600000)>>

<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	<<include "Reset Variables">>
<</if>>
<</widget>>

/* Adds the specified number of days. */
<<widget "adddays">>
<<set _dateOld to $gameDate.toDateString()>>
	
<<set $gameDate to new Date($gameDate.getTime() + $args[0] * 86400000)>>

<<set _date to $gameDate.toDateString()>>\
<<if _dateOld != _date>>	
	<<include "Reset Variables">>
<</if>>
<</widget>>


/*
	Date & Time Printing Widget Definitions
*/
/* Prints the current date ("{weekday} {month} {day}, {year}"). */
<<widget "date">>\
<<print String.format("{0} {1} {2}, {3}",
	GameDays[$gameDate.getDay()],
	GameMonths[$gameDate.getMonth()],
	$gameDate.getDate(),
	$gameDate.getFullYear()
)>>\
<</widget>>

/* Prints the current time (12H). */
<<widget "time12hr">>\
<<if $gameDate.getHours() eq 0>>\
12\
<<elseif $gameDate.getHours() gt 12>>\
<<print $gameDate.getHours() - 12>>\
<<else>>\
<<print $gameDate.getHours()>>\
<</if>>:\
<<if $gameDate.getMinutes() lt 10>>0<</if>><<print $gameDate.getMinutes()>> \
<<if $gameDate.getHours() gte 12>>PM<<else>>AM<</if>>\
<</widget>>

/* Prints the current time (24H). */
<<widget "time24hr">>\
<<if $gameDate.getHours() lt 10>>0<</if>><<print $gameDate.getHours()>>:\
<<if $gameDate.getMinutes() lt 10>>0<</if>><<print $gameDate.getMinutes()>>\
<</widget>>

/* Prints the current date and time (12H). */
<<widget "datetime">><<date>> <<time12hr>> (<<time24hr>>)<</widget>>

Tested and working flawless. :white_check_mark:

1 Like

And rightly so… (I just snuck in at the end and add my 2 cents after they had done all the hard work! :lol:)

1 Like