[Solved] Storing several variables (Making titles via leveling)

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
Uy27
Regular
Posts: 29
Joined: Wed Apr 04, 2018 2:07 am
Contact:

[Solved] Storing several variables (Making titles via leveling)

#1 Post by Uy27 »

I wanna start by saying sorry if the title is not correct.
This is my first time with renpy and I'm very new to the coding world and the terms are still a tad confusing for me!

What I'm basically trying to do is changing a variable depending on how another is. Example a title is 'Asomething' when level 1 and 'Bsomething' when at level 5.
This is how I went about doing it;

Code: Select all

 class Player(renpy.store.object):
        def __init__(self, level=1, money=0, exp=0, rankName=""):
            self.level = level
            self.money = money
            self.exp = exp
            self.rankName = rankName

Code: Select all

if pc.level <=5:
   $ pc.rankName = "Test1"
elif pc.level >= 6:
   $ pc.rankName = "Test2"
elif and so on 
And this is how I went about making it appear on screen;

Code: Select all

screen stat_screen:
    
    add "gui/stat.png"
    hbox:     
        vbox:
            spacing 20
            label "{b}Details:{/b} \n" 
            label "Level: [pc.level] ([pc.rankName])"        
And everything works in the sense that level 1-5 show test as it should. But it does not change the new title after reaching level 6 and above!
I tried changing the operators around and even made several titles and changed into == signs to test it out. And it appears as it can only be assigned to it once.
I even tried to have the if statements in the class code but same results. I feel like I'm using a method that is overcomplicating the process or simply missing something simple.
Last edited by Uy27 on Wed Apr 04, 2018 10:26 pm, edited 1 time in total.

DannX
Regular
Posts: 99
Joined: Mon Mar 12, 2018 11:15 am
Contact:

Re: Storing several variables (Making titles via leveling)

#2 Post by DannX »

What are you doing to actually change the player's level? Each time the level variable is updated, the lv check should be run afterwards so the rank is also changed, than means that if statement must be repeated many times. You have to make it so every time the player gains a level, the game checks what level it is and change the rank if it matches one of those if statements. For that, you need a function.

Code: Select all

init python:

    class Player(renpy.store.object):
        def __init__(self, level=1, money=0, exp=0, rankName=""):
            self.level = level
            self.money = money
            self.exp = exp
            self.rankName = rankName
    
    # A function that checks a player's level and changes their rank accordingly
    def check_player_rank(player): 
            if player.level <=5:
                player.rankName = "Test1" 
            elif player.level >= 6:
                player.rankName = "Test2"
            # and so on

default pc = Player(rankName="Rankless") #Here we create a new player instance

label start:

    show screen stat_screen

    "..."

    $ pc.level = 5 #Here we manually change the lv to 5

    $ check_player_rank(pc) #We call the check_player function with pc as an argument

    "Change lv to 5"

    $ pc.level = 6 #Here we change it to 6

    $ check_player_rank(pc) #Call the check_player function again, this is so the rank updates and the screen

    "Change lv to 6"

    "End"

    return
Of course, that last code can be simplified even more into a single function, but that depends on how you code the rest of your game.

Uy27
Regular
Posts: 29
Joined: Wed Apr 04, 2018 2:07 am
Contact:

Re: Storing several variables (Making titles via leveling)

#3 Post by Uy27 »

Thanks for taking your time to help, DannX!

Sadly it didn't work out. When I follow the steps it tells me that the check_player_rank is not defined. And I tried to do that with no results.
The way I do the leveling system is really simple;

Code: Select all

label levelUp(target_label=""):
    if pc.exp >=500 and pc.level == 1:
        $ pc.level = 2
        $ check_player_rank(pc)
    if pc.exp >=1500 and pc.level == 2:
        $ pc.level = 3
        $ check_player_rank(pc)
    if pc.exp >=2500 and pc.level == 3:
        $ pc.level = 4
        $ check_player_rank(pc)
    if pc.exp >=3500 and pc.level == 4:
        $ pc.level = 5
        $ check_player_rank(pc)
    if pc.exp >=4500 and pc.level == 5:
        $ pc.level = 6
        $ check_player_rank(pc) 

    jump expression target_label
I also tried to add the check to the code where I gain the exp for the level;

Code: Select all

label test3:
    
    while dayTime ==  4:
        scene black 
        return         
    $ results = [('success',110 ),('fail',0)]
    $ place = NonUniformRandom(results)
    $ renpy.transition(longfade)

    if place.pick() == 'success':
        scene success with longfademore
        $ dayTime += 1
        $ expEarned = renpy.random.randint (10000, 20000)
        $ pc.exp += expEarned 
        $ moneyEarned = renpy.random.randint(10, 15)
        $ pc.money += moneyEarned
        $ check_player_rank(pc)
        "You earned [moneyEarned]."
        "You got [expEarned] exp."
        call expression 'levelUp' pass ('end')

        return
    else:
        scene failure with longfademore
        $ dayTime += 2
        return
    

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Storing several variables (Making titles via leveling)

#4 Post by Remix »

If I was you I would define rank_name as a property of the object:

Code: Select all

init python:

    class Player(renpy.store.object):

        def __init__(self, level=1, money=0, exp=0):
            self.level = level
            self.money = money
            self.exp = exp

        @property
        def rank_name(self):
            return {
                1 : "Complete Noob",
                2 : "Apprentice",
                # add more
                9 "Grand Master"
            }.get( self.level, "Unknown Rank" )
This basically creates an attribute of the class with the same name as the method (so, self.rank_name in this case) except each time the attribute is read the method is called and the return is used as the value.
The return {dict}.get( key, default ) syntax just looks in the dict for the key and returns the value.
Note: In general, @property attributes are read only, so they excel in cases like yours where the value depends on other values within the class. If you did want to set a property value, you'd need a @rank_name.setter method.
Frameworks & Scriptlets:

Uy27
Regular
Posts: 29
Joined: Wed Apr 04, 2018 2:07 am
Contact:

Re: Storing several variables (Making titles via leveling)

#5 Post by Uy27 »

Thank you remix but I must admit I am a bit lost on how to incorporate that into making it appear on the screen and combine it with the level.

Code: Select all

 label "Level: ([pc.rank_name])"        

Is my failed attempt.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Storing several variables (Making titles via leveling)

#6 Post by Remix »

Uy27 wrote: Wed Apr 04, 2018 3:19 pm Thank you remix but I must admit I am a bit lost on how to incorporate that into making it appear on the screen and combine it with the level.

Code: Select all

 label "Level: ([pc.rank_name])"        
That should work fine as long as the class is instantiated fine. Do the other attributes work ok? Do you get any error message?
Frameworks & Scriptlets:

Uy27
Regular
Posts: 29
Joined: Wed Apr 04, 2018 2:07 am
Contact:

Re: Storing several variables (Making titles via leveling)

#7 Post by Uy27 »

The other attribute works fine and I don't really get an error but in the game where the title should be it shows:
<bound method Player.rank_name of <store.Player object at 0x0A683750>>

I tried without anything added but your code as shown and then i also tried to do it like this

Code: Select all

        def __init__(level=1, money=0, exp=0, rank_name=""):

            self.level = level
            self.money = money
            self.exp = exp
            self.rankname = rank_name
            
        def rank_name(self):
            return {
                1 : "Complete Noob",
                2 : "Apprentice",
                3 : "test 2",
                4 : "test 3",
                5 : "test 4",
                6 : "test 5",
                7 : "test 6",
                8 : "test 7",
                9 :"Grand Master"
            }.get( self.level, "Unknown Rank" )
        
and at the default i added

Code: Select all

default pc = Player(stuff stuff, rank_name = "")
But both methods was the same outcome.

*Edit* I noticed i forgot a '_' at self.rankname. This fixes the store object message but instead, now nothing shows up. I will keep playing around with it to see .
*Edit2* but by reading what you wrote I'm basically doing self.rank_name twice I think. Which then takes us back to the store object problem again

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Storing several variables (Making titles via leveling)

#8 Post by Remix »

Note on mine it has
@property
just before the method... that is Vitally important...

A quick working example (increase level makes rank_name change)

Code: Select all

init python:

    class Player(renpy.store.object):

        def __init__(self, level=1, money=0, exp=0):
            self.level = level
            self.money = money
            self.exp = exp
            
        @property
        def rank_name(self):
            return {
                1 : "Complete Noob",
                2 : "Apprentice",
                3 : "test 2",
                4 : "test 3",
                5 : "test 4",
                6 : "test 5",
                7 : "test 6",
                8 : "test 7",
                9 :"Grand Master"
            }.get( self.level, "Unknown Rank" )

default pc = Player() # level 1, 0 money or xp

label start:
    "[pc.level] [pc.rank_name]"
    $ pc.level += 1
    "[pc.level] [pc.rank_name]"
    $ pc.level += 1
    "[pc.level] [pc.rank_name]"
    $ pc.level += 1
    "[pc.level] [pc.rank_name]"
    $ pc.level += 1
    "[pc.level] [pc.rank_name]"
    return
Note: The class does not use rankName or rank_name as a parameter (value passed in) or as an attribute (a self.nnnn = xxx in init)
Frameworks & Scriptlets:

Uy27
Regular
Posts: 29
Joined: Wed Apr 04, 2018 2:07 am
Contact:

Re: Storing several variables (Making titles via leveling)

#9 Post by Uy27 »

Ahhhhh! I mistook the property as a comment! Never seen that piece of code before haha. It works wonderfully now I thank you a thousand times Remix, you amazing!
Lot's to learn yet and thank you too DannX

DannX
Regular
Posts: 99
Joined: Mon Mar 12, 2018 11:15 am
Contact:

Re: [Solved] Storing several variables (Making titles via leveling)

#10 Post by DannX »

I'm sorry my code didn't work, strangely it did when I tested it, anyway I'm glad Remix gave a much better solution, honestly I didn't know about @property so I'll have to take a look soon.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot]