Variable definition process

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
nature1996
Regular
Posts: 62
Joined: Wed Jun 21, 2017 10:35 am
Contact:

Variable definition process

#1 Post by nature1996 »

Hi,

I have a few closely related question about variable definition. I must say, I'm completely lost.

1- First thing first, from previous programming experience, I have the reflex of trying to define every variable before the start label. Also, I tend to give them the right type, for example, I will set a variable that will serve as a float as a float (a=0.0), an array as an empty array (a=[]) and a string as an empty string (a="")
Is this something that help/ is recommended/ is needed?

2-I'm not sure I define my variable the right way. Here a few example from my most recent script. I will also include some function, as it will be pertinent for a later question:

Code: Select all

init python in chara:
    #Fix
    name = "Pholder"
    
    #Physical
    muscle=5.0
    fat=5.0
    cardio=5.0
    HP=10.0
    
    def dayend():
        #Physical
        global muscle
        global fat
        global cardio
        global HP
        
        HP=HP+1-fat/10.0+muscle/5.0+cardio/5.0
        if HP>50:
            HP=50.0
        
        return

    def add(variable,value):
        #Physical
        global muscle
        global fat
        global cardio
        global HP
        
        #physical
        if variable == "muscle":
            if (muscle>1)&(cardio>0):
                muscle=muscle+value/10.0*cardio/muscle
            else:
                muscle=muscle+value
            if muscle>10:
                muscle=10.0
            elif muslce<0:
                muscle=0
            return
        elif variable== "fat":
            if value>0:
                fat=fat+value/cardio/10.0
                if fat>10:
                    fat=10.0
            elif value<0:
                fat=fat+value/10.0*(cardio+1)/10.0
                if fat<0:
                    fat=0
            return
        elif variable== "cardio":
            cardio=cardio+variable/10.0
            if cardio>10:
                cardio=10.0
            elif cardio<0:
                cardio=0
            return
        elif variable== "HP":
            HP=HP+value
            if HP>50:
                HP=50
            elif HP<=0:
                renpy.jump("game_over")
            return
    
define mnt=[None,
    _("January"),_("February"),_("March"),_("April"),
    _("May"),_("June"),_("July"),_("August"),
    _("September"),_("October"),_("November"),_("December")]

default mlen=[None,
    31,30,31,
    30,30,31,
    31,30,31,
    30,30,31]
    
label game_over:
    nvl clear
     
    "You're dead"
    
    return
I choose an int python in block for the character variable because of the number associated with that single character, namely over 30. Also, I plan on creating at least 10 other character with about the same number of variable each. That's one. The second reason is that I would like to be able to execute group of function as a block on those variable. For example, chara.dayend will be executed every night before the start of a new day, and will control may variable, such as the character tan(not in the example). I also like to have an add function for those variable, as it let me use general variation value, such as add 1 point, than automatically scale that values for what I want for general variation.

Next is the define mnt statement. This is an array I use to determine what to write for the month in the date on my status screen. I've used define because, from what I understood, you shouldn't change a variable set with define.

To finish, I've used default to define the mlen array, representing month length because I want to cut a day to February when the year isn't a leap year, as it is the first year of the game.

I should also add that, as of now, it works, and all relevant variable seems to save (I haven't done extended testing yet.), even if my search indicate that it shouldn't (Manual on python init block). Also, the chara initialization is in a separated .rpy file from the script.

Can I do that (should it work?) and will that still work with ren'py 6.99.14?

3-Is there a way to discardd variable that arn't usefull anymore, as to liberate space in the save file/memory? For exemple, there is no need to keep in memory the answer at the start of the game that would influence only two line a bit later in the same section. If there is a way, should I do it? If not, should I try to always reuse the same variable in all situation? (Eg. I don't need a variable "salad" to note a character choice for lunch. I could use the same variable as the one I would use later on to remember if they want to play soccer or tennis.)

4-It is a bit unrelated, but is there a way to use more complex function, such as exponential and logarithm? I would like to use some to scale the previously mentioned chara variables.

5-A yet less related question, but with the search engine down, I'm a bit too shy to post 4 new topic in the same category in less than a day. So, I would like to end the game after the label game_over is reached, but as I use many call to label in the script, as of now I end up just going back to the middle of the story.

In conclusion, sorry for the long post and the numerous question, but with the search engine down, it was the or multiple post, and I believe this to be the lesser evil. If I'm wrong, you can tell me and I will edit the post in consequence.

Thanks in advance for your help
Je parle aussi français

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Variable definition process

#2 Post by Ocelot »

from previous programming experience, I have the reflex of trying to define every variable before the start label
Simple checklist:
  • Is my variable a game-wide constant? → Use define
  • Should my variable participate in save-load? → Use default
  • Else declare and use variable when needed
it works, and all relevant variable seems to save (I haven't done extended testing yet.), even if my search indicate that it shouldn't
It is not that it shouldn't. It might not save whenever RenPy feels like that (concrete behavior is hard to predict and explain). Also: appears to work is, in fact, the worst possible result of mistake. In your case, you should define character class and create default instance of that class.
Is there a way to discardd variable that arn't usefull anymore, as to liberate space in the save file/memory?
There is: del variable (techncally it just releases reference. Variable will be deleted when Python VM feels like it). But why do you care? A single background image will take more memory than all variables in your game combined.
is there a way to use more complex function, such as exponential and logarithm?
Check Python documentation: https://docs.python.org/2/library/math.html
In short: 9 == 3**2, 2 == math.log(9, base=3)
as I use many call to label in the script, as of now I end up just going back to the middle of the story
If this is normal game end then your control flow is bad. call meanst that you will return there and continue from this point. Otherwise you need to use jump. If you want to terminate game due to bad ending, renpy.full_restart would help there.
< < insert Rick Cook quote here > >

User avatar
nature1996
Regular
Posts: 62
Joined: Wed Jun 21, 2017 10:35 am
Contact:

Re: Variable definition process

#3 Post by nature1996 »

Simple checklist:

Is my variable a game-wide constant? → Use define
Should my variable participate in save-load? → Use default
Else declare and use variable when needed
Thanks for that. That should definitely be in the manual.
Also: appears to work is, in fact, the worst possible result of mistake.
Figured as much, that's why I choose to make a post at that moment.
In your case, you should define character class and create default instance of that class.

I remember seeing how to do something like that somewhere, but I can't seem to figure out where, and with the forum search function HS, I'm out of luck. Do you have a link on how to do that?
A single background image will take more memory than all variables in your game combined.
Never thought about that, but fair enough. Though I guess sometime it might be useful to delete variable, especially in the case I don't want to accidentally use a previous value.
In short: 9 == 3**2, 2 == math.log(9, base=3)
Thanks about that.
If you want to terminate game due to bad ending, renpy.full_restart would help there.
I wasn't fully sure that was what I needed to use. As for call, I use it especially because I want to go back, unless there is a game over that is.
Je parle aussi français

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Variable definition process

#4 Post by Ocelot »

Do you have a link on how to do that?
For everything outside of RenPy script itself (stuff after $ sign and inside python blocks) you should look into Python language specification tutorials. For example: https://docs.python.org/2/tutorial/clas ... at-classes
< < insert Rick Cook quote here > >

User avatar
LateWhiteRabbit
Eileen-Class Veteran
Posts: 1867
Joined: Sat Jan 19, 2008 2:47 pm
Projects: The Space Between
Contact:

Re: Variable definition process

#5 Post by LateWhiteRabbit »

nature1996 wrote: Mon Jan 08, 2018 3:09 am I have a few closely related question about variable definition. I must say, I'm completely lost.

1- First thing first, from previous programming experience, I have the reflex of trying to define every variable before the start label. Also, I tend to give them the right type, for example, I will set a variable that will serve as a float as a float (a=0.0), an array as an empty array (a=[]) and a string as an empty string (a="")
Is this something that help/ is recommended/ is needed?
I have to say, this has been one of the most difficult and nerve-wracking challenges for me too, moving from C# to Python. This whole 'dynamic syntax' thing, and not declaring the variable type when it is created. It feels like messy madness to me, and still makes it a challenge for me to read Python code at a glance. I know I just need more practice, but it bothers me not being able to immediately read that 'yes, this variable is going to hold a float, or an int, or a string, etc. etc.'.

And I'm still not a fan of Python's use significant use of whitespace. I find it tedious. I miss my brackets, semi-colons, and curly braces. The only thing I used whitespace for in C# was to make the code easier to read, but I didn't have to count spaces, and if I wanted to break a complex operation into multiple lines for easy readability I could do that without breaking anything.

Note that I wasn't a great or even good programmer before this, but I was comfortable and proficient in C#. Python has been a bit of a learning curve.
Ocelot wrote: Mon Jan 08, 2018 5:37 am Simple checklist:
  • Is my variable a game-wide constant? → Use define
  • Should my variable participate in save-load? → Use default
  • Else declare and use variable when needed
Thanks, Ocelot. This is actually really helpful. Like Nature1996, I had been used to declaring all variables before the start when using C#. I've actually been using a separate .py file to declare all my variables, just to keep them in one nice, neat, easy to access location. I didn't figure it mattered since Renpy will compile everything into one .py file once the game is built. I take it that is a bad idea?

User avatar
nature1996
Regular
Posts: 62
Joined: Wed Jun 21, 2017 10:35 am
Contact:

Re: Variable definition process

#6 Post by nature1996 »

Ocelot wrote: Mon Jan 08, 2018 5:37 am In your case, you should define character class and create default instance of that class.
While searching in the documentation, I found a section about what I did, and it is a name store, which should be working with rollback and save the same way default does: Name store. Or maybe I'm still misunderstanding the whole thing.
Je parle aussi français

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], mirceea