Ren'Py Help adding a "weeks" component to an existing class

moose_puck

Active Member
Sep 6, 2021
741
1,664
I'm attempting to add a simple time display in my game that shows up on all the called screens. I've been looking online for a while today and I found the following code that does 'almost' everything I need....

You don't have permission to view the spoiler content. Log in or register now.


Instead of displaying the number of days as the above code does ( clock.day ), I instead want to display the number of weeks that have passed, so my final display would be something like...

Week: 10
Saturday
noon

At first, I thought I could just keep the clock.day variable and just divide it by 7 to get a new Week total. But this is where my total lack of any python knowledge killed me... damned if i can figure out how to do a simple mathematical operation in Ren'Py, lol.

So, I was wondering if one of you knowledgeable coders on here could just help me modify the above Class (day_time) to include a Weeks section that automatically advances after every 7 days?
 

guest1492

Member
Apr 28, 2018
322
272
Python does not return the quotient of integers as an integer, you need to specifically turn it into one.

Python:
init python:
    class day_time(object):
        
        # stuff #

        def week(self)
            return int(self.day / 7) + 1

label start:

    # stuff #

    "{b}clock.week{/b} returns Week: {b}[clock.week]{/b}"
 
  • Like
Reactions: moose_puck

moose_puck

Active Member
Sep 6, 2021
741
1,664
Python does not return the quotient of integers as an integer, you need to specifically turn it into one.

Python:
init python:
    class day_time(object):
     
        # stuff #

        def week(self)
            return int(self.day / 7) + 1

label start:

    # stuff #

    "{b}clock.week{/b} returns Week: {b}[clock.week]{/b}"
Thanks.

I tried this, but had to change a couple of things to make it work...

First, there was a colon missing after defining week def week(self):

Second, I got a bound method error string when calling clock.week. I fixed that by adding a decorator @ property

I get the weeks now and they count up, but they roll over on Sunday, not Monday. Have to figure that one out...

EDIT:

Ok, this seems to work...

Python:
        @property
        def week(self):
            return int((self.day-1) / 7) + 1
Seems kind of inelegant, but it's functional, lol.

It starts at 1 week, counts up properly, and rolls over on Monday.
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,285
Python does not return the quotient of integers as an integer, you need to specifically turn it into one.
Python 2.x return the quotient of integers as integer, and Python 3.x have an operator for this, //.
 
  • Like
Reactions: guest1492

moose_puck

Active Member
Sep 6, 2021
741
1,664
Code:
screen weekNumber():
    text ( "{}".format( ( clock.day // 7 ) + 1 )  )

init python:
    config.overlay_screens.append( "weekNumber" )
Nice!

EDIT: I made one small change to your code, so that the week rolls over on Monday and not Sunday ...

Code:
screen weekNumber():
    text ( "{}".format( ( (clock.day-1) // 7 ) + 1 )  )


Can I pick your brain for something related to screens?

I'm making a sandbox navigation screen with 8 boxes across the top of the screen. The 6 boxes in the center change depending what room you are in... the standard sort of navigation you see in many games. The box on the far right is the phone (Gonna tackle that mountain next week, lol)

What I'm working on this weekend is the box on the left, which is my time box. I want to show a 234 x 234 pixel image that represents the time of day (clock.time in that code I posted in the OP) So, I'll need to have some sort of function where the image file is chosen based on clock.time. Then, on top of that image, I want to put the text I was talking about before... Week #, Day of Week (Saturday, Sunday...) and text representation of the time of day (Morning, Noon ...)

Screen language is giving me fits though. I can code this using an image and text directly in all the navigation screens, but that would add literally about 500 extra lines of code and, more importantly, leave like 50 instances of that code I would have to edit, if I changed anything down the road.

Does Ren'py have something similar to a 'server side include' (sorry for the php reference) where I can define this code and then just call it in each of the navigation screens? Correct me if I am wrong, but Renpy doesn't allow you to call or show a screen from within a screen, does it? I haven't been able to yet, so far.

Here's an example of the image I'll be using...

afternoon.png

And here's how it looks when I hard code the text info on top of the image (just a test, not really formatted at all)...

morning.png
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,369
15,285
I want to show a 234 x 234 pixel image that represents the time of day (clock.time in that code I posted in the OP) So, I'll need to have some sort of function where the image file is chosen based on clock.time. Then, on top of that image, I want to put the text I was talking about before... Week #, Day of Week (Saturday, Sunday...) and text representation of the time of day (Morning, Noon ...)
Something like this ?
Code:
screen day():

    fixed:
        add "background_{}.png".format( clock.time_of_day )
        text "Whatever you want" xoffset 30
fixed act as a box, except that every child will have the same origin. Therefore add will display the image starting 0,0. Then text will display the text, also starting 0,0 ; xoffset being then used to center it.


Since the information you've to display will probably be on more than one line:
Code:
screen day():

    fixed:
        add "background_{}.png".format( clock.time_of_day )
        vbox:
            text ( "Week {}".format( ( clock.day // 7 ) + 1 )  ) xoffset 30
            text ( "{}".format( clock.weekdays[clock.day] ) ) xalign 0.5
It's past 3AM, so I'm not sure that xalign would works here. I give it as example, more than as practical code.
Here, there's still two child for the fixed. The second one being vbox, that will act as usual, and so display the second text below the first one. You can use null height 10 to force a 10 pixels separation between them if you need.


Does Ren'py have something similar to a 'server side include' (sorry for the php reference) where I can define this and then just call in each of the navigation screens? Correct me if I am wrong, but Renpy doesn't allow you to call or show a screen from within a screen, does it? I haven't been able to yet, so far.
You can't call a screen, but you can show one ; renpy.run( Show( nameOfTheScreen) ).But it's not what you need here.

You just need use, that will include another screen into the actual.
Code:
screen UI():
    use day  # as defined above
    use phone

screen phone():
    [whatever you want]

screen whatever():
    use UI
Like any other elements, the place where the screen will be added depend of the place of its statement. So by default, the screen "phone" will be shown at the same place than the screen "day", since they aren't in a vbox nor a hbox.
But it's only half a problem. Generally when you rely on such structure for a screen, the position come from the included screen:
Code:
screen UI():
    use day
    use phone

screen day():

    fixed:
        xpos 0 
        ypos 0
        add "background_{}.png".format( clock.time_of_day )
        vbox:
            text ( "Week {}".format( ( clock.day // 7 ) + 1 )  ) xoffset 30
            text ( "{}".format( clock.weekdays[clock.day] ) ) xalign 0.5

screen phone():

   imagebutton:
       idle "phone.jpg"
       xpos 0
       ypos 300
       action NullAction()

screen whatever():
    use UI
The part related to the day will be display on the top left corner, and the part related to the phone will be displayed below.


Or there's the config.overlay_screens list I used previously.
 

moose_puck

Active Member
Sep 6, 2021
741
1,664
Something like this ?
Just skimming over your examples, I can already see how I can apply this to my navigation screens. It's only 9:30pm here, but I've been working on this for over 12 hours and my eyes are getting tired, so I think I am going to go watch some TV and come at this fresh, first thing in the morning!

I wrote 1200 lines of code today, getting the navigation screens working smoothly. I actually added in all the locations I plan on having in the complete game, even though half of them will be commented out for the first version. But looking at what you just showed me, I think I see a way of reducing a lot of that code that I just wrote. And that will make it easier to update the game down the road.

I'll run some tests in the morning (about 1pm your time)

Thanks again anne O'nymous!
 

moose_puck

Active Member
Sep 6, 2021
741
1,664
You just need use, that will include another screen into the actual.

Ok, this use was a life saver! I tried all of your examples and I tweeked a few things to be more in-line with what I wanted to do, but this code to use a screen within a screen is the cat's ass! Now I can keep the Time Display and the Phone elements as separate screens and just add them to other screens as needed. That saved me apx 400 lines of code alone, and instead of 27 separate instances of this code that I might have to change down the road, I only have to change the 2 screens now. I played with the order that I call this function, and I found out that if you put it in after you add the background screen, it will stay on top. That was a little easier to use then making a custom layer, since the custom layers tended to show up all the time (and you can't seem to use onlayer with add when in a screen) I only want this UI overlay to show up during sandbox parts of the game - not during any VN style events.

Btw, the xalign didn't seem to work (as you guessed) so I just used xpos and ypos to align the text.

It's annoying though, how poorly the Ren'Py language is documented out there. Sure the Ren'py ORG site has a pretty extensive documentation archive, but it's constructed like a quick reference guide, more geared towards people who already have some training in Ren'py and/or Python. It's terrible as a teaching aide. I've spent dozens, maybe 100+, hours researching code in the past month, and I never saw that use anywhere. I just went back to renpy.org and tried to find the section on it, and I still can't find it. Word searches bring up hundreds of hits because, of course it's 'use'd in a million places (pun intended).
 

Greslux

Member
Apr 24, 2022
243
335
My message has already been deleted (they did it right), but if you suddenly encountered it, then I must apologize to everyone: to the people, to the author of the topic, and to the moderator... I accidentally missed the topic (browser tab) and posted the link to the music in the wrong place, instead of posting it in the topic "what music are you listening to right now?" Once again, I apologize for my inattention. The matrix has failed. Now I understand people's reaction to my message.
 
  • Like
Reactions: moose_puck