Stat meter renpy

Mescalino

Active Member
Aug 20, 2017
937
6,632
Hij, how do you create a stat meter like lovepoints etcetera. In ren'py? I know how to add the point but not how to display them. I could also not find a turorial that explains this.
 

Not Me

Newbie
Jun 23, 2017
16
13
Hij, how do you create a stat meter like lovepoints etcetera. In ren'py? I know how to add the point but not how to display them. I could also not find a turorial that explains this.
The easiest thing might be to look at the code of an existing game and see how they do it. If you download Lab Rats, Vren keeps all the code accessible so anyone can see how to make the game (very cool of him). I think previous versions of Katie's Corruption did too (I assume the current version does too), if you're just looking to see how they do a heart showing love points. The rpy files in the /game directory should show you everything you need.
 

Castle

New Member
Game Developer
Jul 31, 2017
7
28
Hij, how do you create a stat meter like lovepoints etcetera. In ren'py? I know how to add the point but not how to display them. I could also not find a turorial that explains this.
Bear with me as I haven't used ren'py, but the way I've gone about it has always been to draw a rectangle and then manipulate that accordingly.

You change the "width" of the rectangle based on the percentage of health remaining.
So "width * (currentHealth / maxHealth) " is what you would use to set the size of the box.
Example for when health is full:
width * (100/100) ----- width * 1 == default width of your meter.
half health:
width * (50/100) ----- width * .5 === half of your default width.

Thats really all the math you need, now you just have to draw the rectangle to the screen
You can use a stand alone "image.png" and transform that or maybe even easier from what I'm reading is to use a displayable.



image healthMeter = Solid ("#fff" , area = ("xPos","yPos","meterWidth","meterHeight"))
should create a solid colored filled in box, and I guess you use show to view it on the screen.

and finally use a transform method to update its width with what ever values you need to.


when something would change the health meter value, make sure to call the transform method again to update the visual.


EDIT:
afterthought, if you do go with using the displayable, you could also use the transform method to change its color, when health is low it could turn red, or whatever.
 

Mescalino

Active Member
Aug 20, 2017
937
6,632


I thought that was more what i was looking for but i will look into both
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,109
14,783
Warning, the cookbook is really out dated. The script you linked work, but it's not the better way to do it now. So :

In "screen button", replace this:
action ui.callsinnewcontext("aff_screen_label")
By this:
action Show( "aff_screen" )

In "aff_screen", replace this:
textbutton "Return" action Return()
By this:
textbutton "Return" action Hide( "aff_screen" )

Finally, completely forget about "aff_screen_label". Everything else is correct.

It will work exactly the same, but without the need of an external jump and the possible consequences of the new context.
 

Mescalino

Active Member
Aug 20, 2017
937
6,632
Thanks, i am curently gathering my assets and setting up the first two chapters. Then i Will start setting up the basics in ren'py. Hopefully tonight i Will have some renders of the mother to show and get feedback on. She Will be the focus of the story. Later i Will focus on the MC. Hopefully i did something unique(ish) designing the mother.
 

RVNSN

Drunken Pirate Skirtchaser
Game Developer
Jan 17, 2019
739
436
Thanks, i am curently gathering my assets and setting up the first two chapters. Then i Will start setting up the basics in ren'py. Hopefully tonight i Will have some renders of the mother to show and get feedback on. She Will be the focus of the story. Later i Will focus on the MC. Hopefully i did something unique(ish) designing the mother.

Assuming you have worked this out by now, could you post an "idiot's guide" with how you ended up doing it - with sample pics of screens would be great? thanks
 

Mescalino

Active Member
Aug 20, 2017
937
6,632
Assuming you have worked this out by now, could you post an "idiot's guide" with how you ended up doing it - with sample pics of screens would be great? thanks
I actually got this working. But life keeps kicking me in the but so i never ended up making the VN.

I created a file calle Mechanic.rpy with the following code:
Code:
#--------------------------------------------------------------------#
# * Configuration variables
#--------------------------------------------------------------------#
default friendship = 0
default love = 0
default lust = 0

#---------------------------------------------------------------------
# * GUI
#---------------------------------------------------------------------
screen gui_screen():

    add "gui/lust.png" xalign 0.975 yalign 0.005
    add "gui/flstats.png" xalign 0.95 yalign 0.20


    text "{b}[friendship]{/b}" xalign 0.905 yalign 0.265 color "#000000"
    text "{b}[love]{/b}" xalign 0.927 yalign 0.210 color "#000000"
    text "{b}[lust]{/b}" xalign 0.930 yalign 0.090 color "#000000"

init python:
    def ch_friendship(amount):
        global friendship
        friendship += amount

    def ch_love(amount):
        global love
        love += amount

    def ch_lust(amount):
        global lust
        lust += amount
The top 3 set the default value to 0 when starting the game.
the two lines starting with add are an image twich i place the counter
The 3 lines starting with text display the counter.

So in your conversation script ytou have something like:

Code:
 menu:
        "Yes!":
            $ friendship += 1
            jump yvacm

        "No":
            jump nvacm
So if the player selects Yes 1 point is added to the friendship meter. You can do the same with love, lust or any other meter you have created.

Hope this helps.
 

Epadder

Programmer
Game Developer
Oct 25, 2016
567
1,047
A true necromancer able to recall the dead at will...:unsure:

Anyway jokes aside, there isn't any reason to declare those variables as global. You can increase them by prefixing them with "store" which is ...well where Ren'py stores variables ;)

Python:
#--------------------------------------------------------------------#
# * Configuration variables
#--------------------------------------------------------------------#
default friendship = 0
default love = 0
default lust = 0

#---------------------------------------------------------------------
# * GUI
#---------------------------------------------------------------------
screen gui_screen():

    add "gui/lust.png" xalign 0.975 yalign 0.005
    add "gui/flstats.png" xalign 0.95 yalign 0.20


    text "{b}[friendship]{/b}" xalign 0.905 yalign 0.265 color "#000000"
    text "{b}[love]{/b}" xalign 0.927 yalign 0.210 color "#000000"
    text "{b}[lust]{/b}" xalign 0.930 yalign 0.090 color "#000000"

init python:
    def ch_friendship(amount):
        store.friendship += amount

    def ch_love(amount):
        store.love += amount

    def ch_lust(amount):
        store.lust += amount
 

recreation

pure evil!
Respected User
Game Developer
Jun 10, 2018
6,254
22,177
This made me think, wouldn't it also work like this (completely untested)?
Python:
default lust = 0

screen lust_screen(lu_amount):
    timer 1.0 action Hide("lust_screen")
    $ store.lust += lu_amount
    add Text ("[lu_amount] {image=lust.png}", style="mystyle"):
        at mytransform

call screen lust_screen(5)
Or am I wrong here?
 

Epadder

Programmer
Game Developer
Oct 25, 2016
567
1,047
The problem with that is that screens "loop" while they are displayed, so while that screen is active it's adding the amount of lust while it's displaying.

In a small test game using this code, Lust starts at 0, by the time the screen disappears Lust has gone to 20. (Also had to add a return to the timer because otherwise the game just sits there)
Python:
label start:
    "Hold"
    call screen lust_screen(5)
    "Current Lust: [lust]"

default lust = 0

screen lust_screen(lu_amount):
    timer 1.0 action [Hide("lust_screen"),Return()]
    $ store.lust += lu_amount
    text "+ [lu_amount]" xalign 0.5 yalign 0.5

return
 
  • Like
Reactions: recreation

recreation

pure evil!
Respected User
Game Developer
Jun 10, 2018
6,254
22,177
The problem with that is that screens "loop" while they are displayed
Hu? That's interesting, I didn't know that.
That reminds me, I've read somewhere that values like this:
Python:
 menu:
        "Yes!":
            $ friendship += 1
            jump yvacm

        "No":
            jump nvacm
get set no matter which choice you choose because of renpys "prediction". Is that true?
 

Epadder

Programmer
Game Developer
Oct 25, 2016
567
1,047
It doesn't seem to, not to say that it couldn't.

It may have been an error in an earlier version, because I felt like when I released the demo/prototype version of my project people seemed to be unable to rollback before they even hit the label that would cause it to be blocked.

It could have totally been my fault though, I was really new to Ren'py at the time. :LOL:

I ended up removing it anyway, as much as I sort of though it was silly to rollback through a fight. :confused:

I used the following code to test:
Python:
label start:
    "Current Lust: [lust]"
    if choice <= 4:
        jump menu_Lust
    else:
        "Game Over Man"
        return

menu menu_Lust:
    "Boobs?"
    "Yes":
        $ lust+= 1
        $ choice += 1
        jump start
    "No":
        $ choice += 1
        jump start

default lust = 0
default choice = 0

return
 
  • Like
Reactions: recreation

recreation

pure evil!
Respected User
Game Developer
Jun 10, 2018
6,254
22,177
It doesn't seem to, not to say that it couldn't.

It may have been an error in an earlier version, because I felt like when I released the demo/prototype version of my project people seemed to be unable to rollback before they even hit the label that would cause it to be blocked.

It could have totally been my fault though, I was really new to Ren'py at the time. :LOL:

I ended up removing it anyway, as much as I sort of though it was silly to rollback through a fight. :confused:

I used the following code to test:
Python:
label start:
    "Current Lust: [lust]"
    if choice <= 4:
        jump menu_Lust
    else:
        "Game Over Man"
        return

menu menu_Lust:
    "Boobs?"
    "Yes":
        $ lust+= 1
        $ choice += 1
        jump start
    "No":
        $ choice += 1
        jump start

default lust = 0
default choice = 0

return
yeah this seems to work. Good to know, thx!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,109
14,783
Or am I wrong here?
Here's a demonstration of the problem pointed by @Epadder .
Python:
init python:
    AuFile = renpy.os.path.join( config.basedir, 'AONlogFile.txt' )

    def logDebug( msg ):
        FH = open( AuFile, "a" )
        FH.write( "{}\n".format( msg ) )
        FH.close()

default simpleState = "predicted"
default increaseState = "predicted"
default counter = 0

screen simple():
    $ logDebug( "SCREEN 'simple' have been {}".format( simpleState ) )

screen increase(b):
    $ counter += b
    $ logDebug( "SCREEN 'increase' have been {}".format( increaseState ) )
    text "[counter]" xalign 0.5 yalign 0.5

screen pause:
    default timeLeft = 10
    timer 1.0 repeat True action If( timeLeft > 0, SetScreenVariable( "timeLeft", timeLeft - 1 ), Hide( "pause" ) )
    text "{b}[timeLeft]{/b}" xpos 0 ypos 0


label start:
    $ logDebug( "Started" )
    "Ready ?"
    $ logDebug( "Interaction 1" )
    "It's just filling line."
    $ logDebug( "Interaction 2" )
    "So take all your time, to ensure that Ren'py will do its own stuff."
    $ logDebug( "Interaction 3" )
    $ simpleState = "called"
    show screen simple
    "Now wait here"
    $ logDebug( "Interaction 4" )
    "Sorry, I'll put a hard pause here"
    $ logDebug( "In the pause" )
    show screen pause
    $ renpy.pause( 10, True )
    $ simpleState = "forgot"
    "And now for the second screen"
    $ logDebug( "Interaction 5" )
    $ increaseState = "called"
    show screen increase( 1 )
    "Now wait again"
    $ logDebug( "Interaction 6" )
    "Sorry, I'll put another hard pause here"
    $ logDebug( "In the pause" )
    show screen pause
    $ renpy.pause( 10, True )

    "DONE"
Look inside the "[main dir]/AONLogFile.txt" file, and you'll be surprised by the number of time the screen have been proceeded by Ren'py.
Note that the code is effectively proceeded only when the screen is displayed. Note that Ren'py don't proceed Python code when it isn't a refresh of the displayed screen... but that it continue to predict screens after they have been displayed.
 
  • Like
Reactions: recreation

RVNSN

Drunken Pirate Skirtchaser
Game Developer
Jan 17, 2019
739
436
I actually got this working. But life keeps kicking me in the but so i never ended up making the VN.

...

Hope this helps.
Thank you all for responding, the help is appreciated. And thanks for the necromancer compliment.