Ren'Py Classes Problem(Calendar System)

Axel Blaze

Newbie
Jul 1, 2020
65
378
I am Trying To make a little Complex Calendar System that includes dates and months and it was going successful so far until I Created a cheat Screen that allows users to set time to any month and any date. My major problem is there is no syntax error also there is no logical error. So I have created a class Calendar having a function called AddTime which allows parameter that can change hours minutes days and months.
When I call Calendar.AddTime() for changing months in script.rpy [picture 5 below] it works properly and changes month to whichever I want. But when I Call the same function in my TimeSetScreen.rpy [picture 1 below ]., it always changes month to December no matter which month value I put .
Please if any renpy Developer or coder who can help with this problem soon will allow me to progress with my project back. Calendar is very important part for my game and I want users to change date to any day of year according to their wish.
Screenshot 2022-01-11 040805.png Screenshot 2022-01-11 041044.png Screenshot 2022-01-11 041109.png Screenshot 2022-01-11 041129.png Screenshot 2022-01-11 041205.png Screenshot 2022-01-11 041300.png Screenshot 2022-01-11 041359.png
 

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,608
2,256
You might want to take a look at the python library .

It allows you to create a datetime object, which is just a date and time combined into a high precision number.
The library allows you do practically everything you could ever want to that number. Including displaying it in specific formats, increasing or decreasing by days/hours/mins/seconds.

The most important part (in my mind at least), is that it takes care of all those irritating things like adding 1 day when you add a number of hours to pass midnight and keeping track of whether the current date is a Monday or a Saturday.

You can start with something as simple as:

Python:
init python:
    import datetime

default gamedt = datetime.datetime(2020, 03, 06, 8, 0, 0) # Start game at 8am on Friday 6th of March 2020.

When I was messing with it, I was creating functions that store.gamedt += datetime.timedelta(hours=6).

I was also using to create labels within a RenPy screen() code to display the date as both the date number and the day name. Combined with a suitable background image, I was able to make something that looked like the calendar icon shown on an iPhone screen.

If your game operates within specific day periods (like Morning, Afternoon, Evening and Night) - you might want to play around with things a little, since most will equate Morning = 8am, Afternoon = 1pm, Evening = 7pm and Night = 11pm or 1am. These periods are NOT a fixed number of hours apart... so just adding 6 hours each time may not meet your needs.

But this is a "don't reinvent the wheel" solution. Using an exising comprehensive library to do the heavy lifting for you.

It may not fit your needs. Or you may be so attached to your own code, you don't want to change it.
I will admit, I haven't looked at your screenshots yet. If you say you'd rather stick with what you have, I'll take a look - although screenshots aren't ideal. (Consider [code] [/code] tags).

You can get lost in tiny details like timezones and such, but a simple RenPy game probably doesn't need that sort of fine detail tuning.
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,971
16,226
The "over complex" part having been addressed, lets talk about the two main errors.


I'll explain why you have an error, and tell how to solve it later, but first thing first, the most important error lay in this line:
My major problem is there is no syntax error also there is no logical error.
It's difficult to tell precisely from your screenshots, but I've seen many logical errors, including the one that lead to the issue that made you ask for help.

The most obvious, is that either you used the same name ("Calendar") for the class and the object itself, or you are working exclusively with the class. Both are as wrong. By naming the object like the class, you overwrite the class, and so loose it. And using the class instead of an object from this class, is like living in the blueprint of a house instead of living in an actual house.

The AddTime method is also full of logical error and weirdness.
By example you've this:
Code:
self.Minutes += minutes
if self.Minutes>60:
    self.Minutes -= 60
    self.Hours += 1
What can only works if you add at most 60 minutes. But one can want to add 61 minutes, or more, and then, boom. You should have looped here:
Code:
while self.Minutes>60:
    self.Minutes -= 60
    self.Hours += 1
Same for the part regarding the hours, that increment the day and should have been a loop. Then come the fact that after this there's the secondary processing (period of the day, season, etc.), but at no time you make the month change... It's perhaps on the not seen part of the code, but then it mean that the season processing is wrong, because based on a month that can change after that.

Talking about the AddTime method, what does it do exactly ? Its name and what you show of the code seem to imply that it advance the calendar. But then, what your screen is supposed to do ?
Code:
[...]
     action Calendar.AddTime( 0, 0, 0, 0 )
[...]
     action Calendar.AddTime( 1, 0, 0, 0 )
[...]
     action Calendar.AddTime( 2, 0, 0, 0 )
[...]
     action Calendar.AddTime( 3, 0, 0, 0 )
A choice "Advance by 0 month, 0 day, 0 hour and 0 minute" make absolutely no sense, so it's surely not what mean the first imagebutton.
But then this mean that each button is a "jump to month X"... what then mean that you are using AddTime to set the date, not to advance it.
Therefore, either the method is wrongly named, or it shouldn't be what to use here.


All this may sound harsh said like this (especially coming after 79flavors kindness), but being direct is the best way to show, and explain, why your claim regarding the absence of syntax and logical error IS an error.

"A computer is like a mischievous genie. It will give you exactly what you ask for, but not always what you want." - Joe Sondow
There's no "oh, it magically don't works, what can be the reason". When you code, 99% of the errors come from you, the reasons being, by order of frequency, a syntax/typo error, a logical error, or a misunderstanding of how something works.




As for the error that made you write this, it's a misunderstanding regarding the action property.
You use action Calendar.AddTime( whatever ), what is wrong, and not just because of the "Calendar" part. Each time Ren'Py display/refresh the screen, it will call the AddTime twelve times, what is not what you expected.

Be noted that this confuse me even more. 0+1+...+11+12 => 78, what don't round to 12, yet you end in December, what seem to imply that, at least for the month, AddTime works as a set method, not as a advance one ; it would end in June. Therefore there's another error in the parts of AddTime that you haven't shown.


Now, why it don't works, independently to the logical error of your class ? Well, as I said, it's due to a misunderstanding.

Ren'Py documentation:
"Along with these actions, an action may be a function that does not take any arguments. The function is called when the action is invoked. If the action returns a value, then the value is returned from an interaction."

It's not necessarily worded correctly, and can be a bit obscure for a novice, but the part regarding the arguments should have made you question what you did ; you pass arguments. Worded (a bit) better, the action property wait for a "code reference", that mean a function or method that is not called yet.
By adding the ( whatever ) part, what you provide is in fact the return value of the Calendar.AddTime method. Not only this make the time advance without waiting that the player make his choice, and make it advance each time Ren'Py refresh the screen, but it also mean that nothing will happen when the player press a button, because the action will be None.

Now, being on the Screen Actions page of the documentation, a look at it make us find an action named . I admit that its description is not made for everyone, but yet the name is relatively explicit, and it's what you should have used:
Code:
[...]
     action Function( Calendar.AddTime, 0, 0, 0, 0 )
[...]
     action Function( Calendar.AddTime, 1, 0, 0, 0 )
[...]
     action Function( Calendar.AddTime, 2, 0, 0, 0 )
[...]
     action Function( Calendar.AddTime, 3, 0, 0, 0 )
Then the date will not magically change and wait for the player to effectively press a button.


But, as implied by the first half of my answer, this will solve your direct issue, but not make your class works as you expect it to do.
 
Last edited:

Axel Blaze

Newbie
Jul 1, 2020
65
378
Thabks
You might want to take a look at the python library .

It allows you to create a datetime object, which is just a date and time combined into a high precision number.
The library allows you do practically everything you could ever want to that number. Including displaying it in specific formats, increasing or decreasing by days/hours/mins/seconds.

The most important part (in my mind at least), is that it takes care of all those irritating things like adding 1 day when you add a number of hours to pass midnight and keeping track of whether the current date is a Monday or a Saturday.

You can start with something as simple as:

Python:
init python:
    import datetime

default gamedt = datetime.datetime(2020, 03, 06, 8, 0, 0) # Start game at 8am on Friday 6th of March 2020.

When I was messing with it, I was creating functions that store.gamedt += datetime.timedelta(hours=6).

I was also using to create labels within a RenPy screen() code to display the date as both the date number and the day name. Combined with a suitable background image, I was able to make something that looked like the calendar icon shown on an iPhone screen.

If your game operates within specific day periods (like Morning, Afternoon, Evening and Night) - you might want to play around with things a little, since most will equate Morning = 8am, Afternoon = 1pm, Evening = 7pm and Night = 11pm or 1am. These periods are NOT a fixed number of hours apart... so just adding 6 hours each time may not meet your needs.

But this is a "don't reinvent the wheel" solution. Using an exising comprehensive library to do the heavy lifting for you.

It may not fit your needs. Or you may be so attached to your own code, you don't want to change it.
I will admit, I haven't looked at your screenshots yet. If you say you'd rather stick with what you have, I'll take a look - although screenshots aren't ideal. (Consider [code] [/code] tags).

You can get lost in tiny details like timezones and such, but a simple RenPy game probably doesn't need that sort of fine detail tuning.
Thanks alot for the information . It Will definitely help me.
 

Axel Blaze

Newbie
Jul 1, 2020
65
378
You might want to take a look at the python library .

It allows you to create a datetime object, which is just a date and time combined into a high precision number.
The library allows you do practically everything you could ever want to that number. Including displaying it in specific formats, increasing or decreasing by days/hours/mins/seconds.

The most important part (in my mind at least), is that it takes care of all those irritating things like adding 1 day when you add a number of hours to pass midnight and keeping track of whether the current date is a Monday or a Saturday.

You can start with something as simple as:

Python:
init python:
    import datetime

default gamedt = datetime.datetime(2020, 03, 06, 8, 0, 0) # Start game at 8am on Friday 6th of March 2020.

When I was messing with it, I was creating functions that store.gamedt += datetime.timedelta(hours=6).

I was also using to create labels within a RenPy screen() code to display the date as both the date number and the day name. Combined with a suitable background image, I was able to make something that looked like the calendar icon shown on an iPhone screen.

If your game operates within specific day periods (like Morning, Afternoon, Evening and Night) - you might want to play around with things a little, since most will equate Morning = 8am, Afternoon = 1pm, Evening = 7pm and Night = 11pm or 1am. These periods are NOT a fixed number of hours apart... so just adding 6 hours each time may not meet your needs.

But this is a "don't reinvent the wheel" solution. Using an exising comprehensive library to do the heavy lifting for you.

It may not fit your needs. Or you may be so attached to your own code, you don't want to change it.
I will admit, I haven't looked at your screenshots yet. If you say you'd rather stick with what you have, I'll take a look - although screenshots aren't ideal. (Consider [code] [/code] tags).

You can get lost in tiny details like timezones and such, but a simple RenPy game probably doesn't need that sort of fine detail tuning.
Thanks for the information . I wish I know that early . I already have created it.