Help with adding months into a day/time cycle

Twine Version: 2.6.2

So I’m sorry for making so many questions on this topic, but I’m really stumped. My posts below were my previous posts (and have context for the variables and constants)
https://intfiction.org/t/help-with-day-time-cycle/66043?u=tennshii
https://intfiction.org/t/help-with-resetting-weekdays-for-day-time-cycle/66053?u=tennshii
I have the day/time cycle nearly complete, I just wanted to add a working month roll-over system that also increases the year by one. However I get the following error when I move to a passage that uses my <add-time> widget.

Error: <<add-time>>: errors within widget code (Error: cannot find a closing tag for macro <<if>>; Error: child tag <</if>> was found outside of a call to its parent macro <<if>>)

It’s skipping going through all the times of day, going from Morning to Noon to the next day. It also doesn’t properly switch months (I set $gameMonth = 0 and $monthDay = 31 but the next day shows January 32th instead of February 1st). Below is my code in my time cycle widget and StoryInit in that order:

/* Changes the time of day by one */
/* Use <<add-time>> multiple times to pass more time for the same passage */
<<widget "add-time">>

	<<set $gameTime += 1>>

	/* If it is midnight, execute following function */
	<<if setup.time[$gameTime] == "Midnight">>

		/* If it is Saturday, the day will roll-over to Sunday */
		<<if setup.dateDay[$gameDay] == "Saturday">>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay = 0>>
/* month code start */
						<<if setup.dateMonth[$gameMonth] == "December">>

							<<if $monthDay = 31>>

								<<set $gameMonth = 0>>

								<<set $gameYear += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "January" or "March" or "May" or "July" or "August" or "October">>

							<<if $monthDay = 31>>

								<<set $gameMonth += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "April" or "June" or "September" or "November">>

							<<if $monthDay = 30>>

								<<set $monthDay = 0>>

								<<set $gameMonth += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "February">>

							<<if ($gameYear/4) = 0>>

								<<if $monthDay = 29>>

									<<set $monthDay = 0>>

									<<set $gameMonth += 1>>

								<</if>>

							<</if>>

							<<if ($gameYear/4) != 0>>

								<<if $monthDay = 28>>

									<<set $monthDay = 0>>

									<<set $gameMonth += 1>>

								<</if>>

							<</if>>
/* month code end */
						<</if>>

						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		/* If the day is not Saturday, the day will continue forward */
		<<else>>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay += 1>>
/* month code start */
						<<if setup.dateMonth[$gameMonth] == "December">>

							<<if $monthDay = 31>>

								<<set $gameMonth = 0>>

								<<set $gameYear += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "January" or "March" or "May" or "July" or "August" or "October">>

							<<if $monthDay = 31>>

								<<set $gameMonth += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "April" or "June" or "September" or "November">>

							<<if $monthDay = 30>>

								<<set $monthDay = 0>>

								<<set $gameMonth += 1>>

							<</if>>

						<<elseif setup.dateMonth[$gameMonth] == "February">>

							<<if ($gameYear/4) = 0>>

								<<if $monthDay = 29>>

									<<set $monthDay = 0>>

									<<set $gameMonth += 1>>

								<</if>>

							<</if>>

							<<if ($gameYear/4) != 0>>

								<<if $monthDay = 28>>

									<<set $monthDay = 0>>

									<<set $gameMonth += 1>>

								<</if>>

							<</if>>
/* month code end */
						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		<</if>>

	<</if>>

<</widget>>
/* Constants */
// Total number of days the player has played
<<set $totalDays = 1>>

// The current month +1
<<set $gameMonth = 0>>

// The current day of the month
<<set $monthDay = 31>>

// Tracks what day it is (eg. 0 is Sunday)
<<set $gameDay = 0>>

// Tracks the time of day
<<set $gameTime = 1>>

// Player's wake up time
<<set $playerAlarm = 1>>

// The current year
<<set $gameYear = 2023>>

// School days passed
<<set $schoolDays = 0>>

/* Game Date */
// Determines what the current month is
<<set setup.dateMonth = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]>>

// Determines what day it is
<<set setup.dateDay = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]>>

// Determines the time of the day
<<set setup.time = ["Dawn", "Morning", "Noon", "Afternoon", "Evening", "Night", "Midnight"]>>

I would offer a simpler (I think) solution, with a double array and a unique variable $day.

In StoryInit passage :

<<set $year to [0,31,59,90,120,151,181,212,243,273,304,334,365]>>
<<set $monthlabel to ["January","February","March","April","May","June","July","August","September","October","November","December"]>>

In another passage with the “widget” tag, a widget to calculate the date :

<<widget "date">><<for _i to 0 ; _i <= 12 ; _i++>><<if $day <= $year[_i]>><<set $month to $monthlabel[_i-1]>><<set $monthday to $day - $year[_i-1]>><<break>><</if>><</for>>
$monthday $month<</widget>>

You can test in a passage where the date has to evolve :

<<set $day to 330>>
<<date>>

<<link "Pass one day">><<append "#date">><<if $day == $year[12]>><<set $day to 1>><<else>><<set $day++>><</if>><<date>><</append>><</link>>
<span  id="date">Date</span>

Would I put this apart from my current working version of the day/time cycle? Or would I have to incorporate that within what I have? Or do you recommend I redo this entirely?

/* Changes the time of day by one */
/* Use <<add-time>> multiple times to pass more time for the same passage */
<<widget "add-time">>

	<<set $gameTime += 1>>

	/* If it is midnight, execute following function */
	<<if setup.time[$gameTime] == "Midnight">>

		/* If it is Saturday, the day will roll-over to Sunday */
		<<if setup.dateDay[$gameDay] == "Saturday">>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay = 0>>

						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		/* If the day is not Saturday, the day will continue forward */
		<<else>>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay += 1>>

						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		<</if>>

	<</if>>

<</widget>>

That makes a lot of sense to have an array of values that go up when the months go up as well. I didn’t think of that.

I don’t quite understand how <<for>> functions work in twine, could you explain how it works and why you set each variables as what?

I have a couple more questions, but I don’t want to overload the reply with a ton of my lack of understanding.

I suppose your current code defines when the day ends and the next day begins. At this point you could simply use this <<date>> widget and remove all further code regarding the change of the date.
However my code does not support the day of the week (though it can be managed through the modulo % operator, you might want to keep or adapt that part of your current code).

The <<for>><</for>> macro creates a loop of instructions. A loop proceeds as many times as necessary for a specific counter to reach the goal value (in my example 12) from its starting value (in my example 0). It’s usual to name the counter _i, though by no means mandatory.

Inside the loop, the code checks the number of the day, if it’s 365, the day will reset to one, if not, it will increase by 1.
Then the loop will match the number of the day (within the year) with an array of values, each value corresponding to the number of the day (within the year) representing the end of the month. End of January is 31, end of Februray 59, etc.
As soon as the number of the day is lesser or equal than the number of the last day of a month, I know I’ve found the month I’m in. The widget proceed to determine the number of the day within the month and the label of the month, then it uses the <<break>> macro, which stops the loop. If I didn’t have done this, the macro would have always returned december, because whatever the number it would have ended has lesser or equal than 365.

If you encounter a problem, it can be helpful if you go through your code line by line to see what’s going on at which stage.

Try to make sure that you understand what each line is doing.

Refer to the Sugarcube documentation if you’re not sure what’s happening or what the correct syntax is: SugarCube v2 Documentation

Some issues:

1)

You have several if conditions like this:

As I’ve already mentioned (albeit in the reverse context) in a previous post, the single equals sign is an assignment operator which is used to assign a value to a variable, as in “<<set $totalDays = 1>>”.

In if conditions, you need an equality comparison operator, such as the double equals sign == or triple equals === (the latter for strict equality), so for example:

<<if $monthDay == 31>>

Or you can use Sugarcube’s “eq” or “is”:

<<if $monthDay eq 31>>

It might be helpful to review the documentation on the if macro: SugarCube v2 Documentation

2)

You have several conditions like this:

That won’t work as intended.

If you write it like that, it won’t be interpreted as checking for alternative values of setup.dateMonth[$gameMonth]. Each expression separated by “or” will be evaluated separately, and any non-0/non-false value will be counted as true. So, “March” by itself will be counted as true (similarly for, say, 1 or “blabla”), and so the condition as a whole is true.

For your purposes, you need to put the full comparison expressions between each “or”:

<<elseif setup.dateMonth[$gameMonth] == "January" or setup.dateMonth[$gameMonth] == "March" or setup.dateMonth[$gameMonth] == "May" [... and so on]>>

Compare the examples in the documentation on the if macro: SugarCube v2 Documentation

3)

The error message gives a hint what’s wrong. One way to troubleshoot this is to copy the code into a text editor and go through (and delete) each matching pair of <<if ...>> and <</if>> lines. You’ll find a remaining <<if>> without a matching closing tag, namely the block starting in the lower half with the second occurrence of <<if setup.dateMonth[$gameMonth] == "December">>.

By the way, since the month roll-over check happens on any daily roll-over, whether it’s Saturday-to-Sunday or any other day, it would make sense to pull it out of the conditional checking for whether it’s Saturday.

Having a duplicate chunk of code in both an if block and the alternative else block is usually a sign that you can pull that code out of the conditional structure, since it’s meant to happen regardless of which alternative is executed.
Putting it in a single place simplifies the code and also avoids errors and inconsistencies which could happen if you later change one of the chunks, but forget to change its copy.

4)

The month is probably not increased because of the comparison issue noted under point 1. (Although normally, Twine will give an error message about things like that: “assignment operator found within <<if>> clause”.)

Additionally, looking at the January block versus the block concerning April etc., you’re not resetting the $monthDay to 0 in the January block.

Side remark:

Those are variables, not constants. They change during the game.

1 Like

Gotcha. From the previous time I made this mistake I made the incorrect assumption that boiled down to “if I’m using an <<if>> statement that uses a <<setup>> should use the double equals and if not it should use a single equal sign”.

I see. That makes things a little bit more of a hassle to put in but that explains some things.

Yeah… I went back and counted all my <<if>> statements and subtracted them by how many <</if>> statements I had. It wasn’t fun having to recount because I got distracted.

Yeah, I realized that halfway through and decided to copy and paste it into both daily roll-overs.

After I finished (and now that I have to go back to fix everything), I realize how great it would be the section of code for month was only in one spot and not two. My issue is that I can’t look at what I have to find a way to make it more efficient without breaking something else (or redoing it, and I know if I have to redo it, I’ll come back here asking for help).

Yep, I found the part where this was happening and fixed it accordingly.

That’s true. I don’t know why I named them constants… might have been because my logic was: “oh they start off like this” but I forgot that they would change later.

Update on fixes: I got everything to be working as intended, except the little details in my StoryCaption. Basically, I added a little thing (I don’t know what you call it) at the end of the day of the month (eg. 1 becomes 1st, 2 becomes 2nd, etc.) and 21, 22, 23, and 31 shows as 21th, 22th, 23th, 31th. Based on point 2, the same logic should apply to indexes, so I can probably fix that pretty easily.

But thanks again for the help and thank you to @souppilouliouma for the help as well. Hopefully I don’t come back for awhile since I don’t really want to keep bugging the community for my lack of knowledge.

Edit: I lied. The system I have in place to give February an extra day on leap years doesn’t work either. Below is what I have for it, and I’m unsure how to use the modulus operator in this situation.

							<<elseif setup.dateMonth[$gameMonth] == "February">>

								<<if ($gameYear %= 4) == 0>>

									<<if $monthDay > 29>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

								<<if ($gameYear %= 4) != 0>>

									<<if $monthDay > 28>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

What’s happening is that the $gameYear variable breaks, and it becomes zero. But I’m not sure why that happens because I haven’t changed what it was, I only checked it in the <<if>> statement.

Edit: I lied again. What I thought would fix it doesn’t work. Everything is fine, except for 21, 22, 23, and 31; it shows as 21st 21th, 22nd 22th, 23rd 23th, and 31st 31th respectively.

<<if $monthDay == "1" or $monthDay == "21" or $monthDay == "31">>

	''$monthDay''''st,''

<</if>>

<<if $monthDay == "2" or $monthDay == "22">>

	''$monthDay''''nd,''

<</if>>

<<if $monthDay == "3" or $monthDay == "23">>

	''$monthDay''''rd,''

<</if>>

<<if $monthDay >= "4" && ($monthDay !== "21" or $monthDay !== "22" or $monthDay !== "23" or $monthDay !== "31")>>

	''$monthDay''''th,''

<</if>>

It’s easy to overlook, but you do change it, in fact. In the lines…

and

… you use the remainder assignment operator %=, so this is shorthand for $gameYear = $gameYear % 4, the same way that $bla += 1 is shorthand for $bla = $bla + 1.

From the Sugarcube documentation:

Divides the current value on the left-hand side of the operator by the value on the right-hand side and assigns the remainder to the left-hand side.

See also Remainder assignment (%=) - JavaScript | MDN.

You just want the normal remainder operator % there, so:

<<if ($gameYear % 4) == 0>>

… which you could also shorten to

<<if !($gameYear % 4)>>

(0 evaluates to false, so when the remainder is 0 and we negate 0 by !(...), it evaluates to true; otherwise to false.)

Also, side remark: Depending on the range of years you want to cover, it’s good to be aware that there are exceptions to the rule that every 4-divisible year is a leap year. The rule is:

Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are.

1)

You have a mix of testing for equivalence or “loose” equality (==) and for strict (in)equality (!==):

and

I wouldn’t mix those unless you know exactly what you’re doing. Pick the approach that works best for your use case and stick with that (either == and !=, or === and !==).

Here’s more background info: Equality comparisons and sameness - JavaScript | MDN

2)

You compare numbers to strings:

This can work when testing for loose equality (reasons given at the link above), but it’s not a good idea unless there’s a compelling reason to do so (which is presumably not the case here).

Just compare to the number as usual:

<<if $monthDay == 1 ...>>
3)

You have a disjunction (a chain of ors) in the parentheses there:

For a disjunction to be true, it’s enough if one disjunct (one of the expressions) is true.

So, for example, if it’s the 21st, then it will be true that $monthDay is not equal to the 22nd, and that would already be enough to make the disjunction in the parentheses true (not to mention that it’s also neither the 23rd nor the 31st, and the fact that even $monthDay !== "21" will be true because the number 21 is not strictly equal to the string “21”).

So you need to consider the logic of the situation. You want to represent that it’s not the case that (any of A or B or C) obtains: !(day==21 or day==22 or day==23 or day==31), or equivalently, that it is the case that not-A and not-B and not-C obtain: day!=21 and day!=22 and day!=23 and day!=31.
Compare De Morgan's laws - Wikipedia.

But you can make it even easier. You distinguish four cases in your code: you need to append -st, or -nd, or rd, or for all other days -th. Those are mutually exclusive. So you could just use an if ... elseif ... else structure, where the else branch catches all other possibilities without needing to make them explicit.

So you could just put all of the conditions into one structure:

<<if $monthDay == 1 or $monthDay == 21 or $monthDay == 31>>
	''$monthDay''''st,''
<<elseif $monthDay == 2 or $monthDay == 22>>
	''$monthDay''''nd,''
<<elseif $monthDay == 3 or $monthDay == 23>>
	''$monthDay''''rd,''
<<else>>
	''$monthDay''''th,''
<</if>>

Yep, it works now off this.

Oh, I didn’t actually know that. That’s actually pretty interesting.

Also a little extra thing based off this, I decided to implement this definition of leap years, however I’m not sure how to exclude a point. (trying to exclude the $gameYear % 100) != 0 if $gameYear % 400 = 0.

								<<if ($gameYear % 4) == 0 && if ($gameYear % 100) != 0>>

									<<if $monthDay > 29>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

That makes sense. I realize that I could have simplified a lot of code during this process if I used <<elseif>> and <<else>> statements more often, but when I started trying to do the day/time cycle again, I didn’t understand too well how they work in Twine and avoided using them.

You can add the divisibility-by-400 with an OR, which means that it will suffice on its own to make a leap year.

What’s the logical condition for being a leap year that we want to express?

That the year is:
(simultaneously divisible by 4 AND not divisible by 100)
OR
(divisible by 400).

We can directly translate that into a condition:

<<if (($gameYear % 4) == 0 and ($gameYear % 100) != 0) or ($gameYear % 400) == 0>>

After putting this in, after doing some testing, on years such as 1700 and 1900, it goes on to leap year and doesn’t actually go to march.

Here’s what I have for the February code:

							<<elseif setup.dateMonth[$gameMonth] == "February">>

								<<if (($gameYear % 4) == 0 && ($gameYear % 100) != 0) or ($gameYear % 400) == 0>>

									<<if $monthDay == 29>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

								<<if ($gameYear % 4) != 0>>

									<<if $monthDay > 28>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are.

However it might be the game uses old style dates, especially if it takes part in a place and time where the old style was still applied.

As mentioned above, it can be useful for troubleshooting to plug the value into the equations and go through what each line does.

Ask yourself what happens exactly when the year is 1700, for example.

The calculation is correct, 1700 is not considered a leap year: ((true and false) or false) evaluates to false.

You just don’t have a case for 1700 (and such) in your code (<<if ($gameYear % 4) != 0>> doesn’t catch that case, because 1700 is divisible by 4 without remainder).

You shouldn’t need to check separately for that, because both 1700 (etc.) and the indivisible-by-4 (such as 2023) are just the else case of the leap year check. Put the code that should happen when it’s not a leap year into an else branch within the leap year check structure.

Of course. In the end it’s up to the author which style to use, and it’s good to be aware that the system wasn’t adopted everywhere at the same time.

But since the year was at least preliminarily given in the starting post as…

… I think it’s reasonable to propose the most common system in the world at present.

Okay, that makes sense. I put <<else>> in and it broke on any year divisible by 4. I’m assuming because I didn’t take away an <</if>> statement from the <<if>> statement I deleted for the <<else>> statement.

Yeah, the time the game starts is based on my current school year (the setting of the story is mostly going to be at school).

Everything seems to work perfectly, so thanks again. I guess the only thing I have left to do for this day/time cycle is making the code a lot more efficient, because as said earlier, it’ll be annoying to go back and edit things later since I have exact pieces of code running twice (particularly the month changing section). Below is that I currently have that works:

/* Changes the time of day by one */
/* Use <<add-time>> multiple times to pass more time for the same passage */
<<widget "add-time">>

	<<set $gameTime += 1>>

	/* If it is midnight, execute following function */
	<<if setup.time[$gameTime] == "Midnight">>

		/* If it is Saturday, the day will roll-over to Sunday */
		<<if setup.dateDay[$gameDay] == "Saturday">>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay = 0>>
/* month code start */
						<<if setup.dateMonth[$gameMonth] == "December">>

							<<if $monthDay > 31>>

								<<set $monthDay = 1>>
                                
                                <<set $gameMonth = 0>>

								<<set $gameYear += 1>>

							<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "January" or setup.dateMonth[$gameMonth] == "March" or setup.dateMonth[$gameMonth] == "May" or setup.dateMonth[$gameMonth] == "July" or setup.dateMonth[$gameMonth] == "August" or setup.dateMonth[$gameMonth] == "October">>

								<<if $monthDay > 31>>

									<<set $monthDay = 1>>
                                
                                	<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "April" or setup.dateMonth[$gameMonth] == "June" or setup.dateMonth[$gameMonth] == "September" or setup.dateMonth[$gameMonth] == "November">>

								<<if $monthDay > 30>>

									<<set $monthDay = 1>>

									<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "February">>

								<<if (($gameYear % 4) == 0 and ($gameYear % 100) != 0) or ($gameYear % 400) == 0>>

									<<if $monthDay > 29>>

										<<set $monthDay = 1>>
                                        
                                        <<set $gameMonth += 1>>

									<</if>>

								<<elseif ($gameYear % 4) != 0 or ($gameYear % 100) ==0>>

									<<if $monthDay > 28>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

							<</if>>
/* month code end */
						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		/* If the day is not Saturday, the day will continue forward */
		<<else>>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $totalDays += 1>>

						<<set $monthDay += 1>>

						<<set $gameDay += 1>>
/* month code start */
						<<if setup.dateMonth[$gameMonth] == "December">>

							<<if $monthDay > 31>>

								<<set $monthDay = 1>>
                                
                                <<set $gameMonth = 0>>

								<<set $gameYear += 1>>

							<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "January" or setup.dateMonth[$gameMonth] == "March" or setup.dateMonth[$gameMonth] == "May" or setup.dateMonth[$gameMonth] == "July" or setup.dateMonth[$gameMonth] == "August" or setup.dateMonth[$gameMonth] == "October">>

								<<if $monthDay > 31>>

									<<set $monthDay = 1>>
                                
                                	<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "April" or setup.dateMonth[$gameMonth] == "June" or setup.dateMonth[$gameMonth] == "September" or setup.dateMonth[$gameMonth] == "November">>

								<<if $monthDay > 30>>

									<<set $monthDay = 1>>

									<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "February">>

								<<if (($gameYear % 4) == 0 and ($gameYear % 100) != 0) or ($gameYear % 400) == 0>>

									<<if $monthDay > 29>>

										<<set $monthDay = 1>>
                                        
                                        <<set $gameMonth += 1>>

									<</if>>

								<<elseif ($gameYear % 4) != 0 or ($gameYear % 100) ==0>>

									<<if $monthDay > 28>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

							<</if>>
/* month code end */
						<<if setup.dateDay[$gameDay] == "Monday" or setup.dateDay[$gameDay] == "Tuesday" or setup.dateDay[$gameDay] == "Wednesday" or setup.dateDay[$gameDay] == "Thursday" or setup.dateDay[$gameDay] == "Friday">>
                        
                        <<set $schoolDays += 1>>
                        
                        <</if>>
                        
						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		<</if>>

	<</if>>

<</widget>>

If I were to change this, I think I would have to put it behind everything, and move the <<set $totalDays>> and <<set $monthDay>> variables towards beginning of the code from the end like so:

/* Changes the time of day by one */
/* Use <<add-time>> multiple times to pass more time for the same passage */
<<widget "add-time">>

	<<set $gameTime += 1>>

	/* If it is midnight, execute following function */
	<<if setup.time[$gameTime] == "Midnight">>
    
    	<<set $totalDays += 1>>

		<<set $monthDay += 1>>
        
    	/* month code start */
						<<if setup.dateMonth[$gameMonth] == "December">>

							<<if $monthDay > 31>>

								<<set $monthDay = 1>>
                                
                                <<set $gameMonth = 0>>

								<<set $gameYear += 1>>

							<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "January" or setup.dateMonth[$gameMonth] == "March" or setup.dateMonth[$gameMonth] == "May" or setup.dateMonth[$gameMonth] == "July" or setup.dateMonth[$gameMonth] == "August" or setup.dateMonth[$gameMonth] == "October">>

								<<if $monthDay > 31>>

									<<set $monthDay = 1>>
                                
                                	<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "April" or setup.dateMonth[$gameMonth] == "June" or setup.dateMonth[$gameMonth] == "September" or setup.dateMonth[$gameMonth] == "November">>

								<<if $monthDay > 30>>

									<<set $monthDay = 1>>

									<<set $gameMonth += 1>>

								<</if>>

							<<elseif setup.dateMonth[$gameMonth] == "February">>

								<<if (($gameYear % 4) == 0 and ($gameYear % 100) != 0) or ($gameYear % 400) == 0>>

									<<if $monthDay > 29>>

										<<set $monthDay = 1>>
                                        
                                        <<set $gameMonth += 1>>

									<</if>>

								<<elseif ($gameYear % 4) != 0 or ($gameYear % 100) ==0>>

									<<if $monthDay > 28>>

										<<set $monthDay = 1>>

										<<set $gameMonth += 1>>

									<</if>>

								<</if>>

							<</if>>
/* month code end */
		/* If it is Saturday, the day will roll-over to Sunday */
		<<if setup.dateDay[$gameDay] == "Saturday">>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $gameDay = 0>>

						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		/* If the day is not Saturday, the day will continue forward */
		<<else>>

			/* Interrupts clicked on passages to display sleep message */
			<<done>>

				<<replace "#regular-content">>

					It's getting late. You decide to head to bed before you feel more tired. 

					<br><br><<button "Okay.">>

						/* Player wakes up at their alarm time */
						<<set $gameTime = $playerAlarm>>

						<<set $gameDay += 1>>
                        
						<<if setup.dateDay[$gameDay] == "Monday" or setup.dateDay[$gameDay] == "Tuesday" or setup.dateDay[$gameDay] == "Wednesday" or setup.dateDay[$gameDay] == "Thursday" or setup.dateDay[$gameDay] == "Friday">>
                        
                        <<set $schoolDays += 1>>
                        
                        <</if>>
                        
						<<goto [[Disclaimer]]>>

					<</button>>

				<</replace>>

			<</done>>

		<</if>>

	<</if>>

<</widget>>

I haven’t tested this at all yet, but we’ll see how it works and if I come back for questions.

Okay, so in this variation of my attempt to make this widget more efficient, it mostly seems to work. The only issue is that the month, day of the month, and total days played changes at Midnight rather than when the player wakes up, however, the day of the week works just fine.

I don’t know if this is helpful, after so much work, but I have a complete set of date macros that might be of interest.

It’s designed especially for custom date systems.

If nothing else, you could mine the code for ideas if that’s of use.

1 Like

I could try to use this to make what I have more efficient. My only issue with that is that I barely learned how to use widgets from a previous thread I made of this topic, and I also have no idea how to use macros, so I would have to learn something new to make something I (almost) have to a decent level.

Although now that I look at what the macro could do, it looks pretty cool and would let me make more complicated timings within days on certain actions. It just depends if someone wouldn’t mind having to essentially reteach me how to make the day/time cycle.

What my macros are designed for (which is not the same as the way people use them :)) is to make a custom calendar and allow you time things down to the second, while providing day/night, day of week, month, season, etc. on demand.

If you only need to track day and night it would probably be overkill for you, which is why I would hesitate to say: “Throw away everything and use my code instead”.

If you did decide to use it, I’m happy to provide suggestions/advice/help.

Sorry for the late reply, I was looking over my storyboarding notes to see if I could alter some actions/storyline events to fit an actual time system rather than the crude one I had.

I’d love to use your macro. I guess my first question to start is, how do I install it (I’m never used Github before) and after I install it, where do I put the file?