[SOLVED] Proper way of using classes

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
hapciupalit
Regular
Posts: 56
Joined: Tue Nov 13, 2018 6:00 am
Contact:

[SOLVED] Proper way of using classes

#1 Post by hapciupalit »

Hello guys,
I have build a class with a few methods to change the parameters, but when I save I loose my changes. Here is one of the classes that I have created and a variable.

Code: Select all

init -100 python:
    class Time:
        def __init__(self, time, day):
            self.time = time
            self.day = day
            
        def incTime(self):
            if self.time == 3:
                self.time = 0
                self.day += 1
            else:
                self.time += 1
                
default time = Time(0,0)
And I have a screen with a skip button

Code: Select all

screen header_example:
    imagebutton:
        idle "gui/menu/ic_skip.png"
        hover "gui/menu/ic_skip_hover.png"
        xalign 0.5
        focus_mask True
        action Function(time.incTime)
        tooltip "Skip Time"
I also tried doing calling the time.incTime in a label, and it worked, but in the end when I load the scene everything is back to default.

Thank you.
Last edited by hapciupalit on Mon Feb 17, 2020 5:55 am, edited 1 time in total.

User avatar
Kia
Eileen-Class Veteran
Posts: 1050
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: Proper way of using classes

#2 Post by Kia »

You should name your class something else since time is already in use in python. also you need to create an instance of your class and use that in your screen:

Code: Select all

default timekeep = timekeep_class(0, 0)

hapciupalit
Regular
Posts: 56
Joined: Tue Nov 13, 2018 6:00 am
Contact:

Re: Proper way of using classes

#3 Post by hapciupalit »

Kia wrote: Sat Feb 15, 2020 10:35 am You should name your class something else since time is already in use in python. also you need to create an instance of your class and use that in your screen:

Code: Select all

default timekeep = timekeep_class(0, 0)
I'm not sure I understand what's an instance. Isn't the

Code: Select all

 default timekeep = timekeep_class(0,0)
an instance?

User avatar
Kia
Eileen-Class Veteran
Posts: 1050
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: Proper way of using classes

#4 Post by Kia »

an instance is a copy of your class stored in a variable.
once you instance a class, you can use that instance name to access the variables and functions of that instance.
$ timekeep .incTime()

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Proper way of using classes

#5 Post by trooper6 »

Also, your classes need to inherit from Object if you want them to work properly with save, load, rollback, etc.

Code: Select all

init python:
    class TimeClock(object):
        def __init__(self, time, day):
            self.time = time
            self.day = day
            
        def incTime(self):
            if self.time == 3:
                self.time = 0
                self.day += 1
            else:
                self.time += 1
                
default tclock = TimeClock(0,0)
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

strayerror
Regular
Posts: 159
Joined: Fri Jan 04, 2019 3:44 pm
Contact:

Re: Proper way of using classes

#6 Post by strayerror »

I'm a little confused by this thread, so please disregard if I'm way off base here. The tl;dr is in bold. ;)

Firstly, the original post does (at least at the time of reading) create an instance of the Time class in the final line of the first block. While - as Kia correctly points out - time is a module name in python, it's not by default present in the store module acting as the locals() in this context, so there isn't any ghosting occurring in the original code. That said, avoiding names that conflict with python builtins is still excellent advice as this could easily become a point of confusion when maintaining this code in future.

With that out the way, the question returns to "why does the code function, but not retain it's updated value?" The answer to this lies in how it is being updated, more specifically that it is occurring as a screen action. To understand why this is relevant, it's necessary to understand that Ren'Py's save system is built around the concept of interactions, and that a little confusingly confusingly screen actions are not by default classed as interactions.

When the game is saved, it's state is stored as it was at the start of the current interaction. In this instance: when the screen was displayed. i.e. Before the button was ever clicked. In order to faciliate use-cases like this one, Ren'Py provides a helper function, which when called will update the data to be saved with the current changes. Adding a call to renpy.retain_after_load() to the end of the incTime method will likely resolve the issue you see. It's definitely worth reading up on this function in the documentation as it's not a panacea for all related cases, and so it's use can be quite situational.

P.S. In current versions of Ren'Py (perhaps due to the py3 prep work?) class TimeClock(object): and class TimeClock: will both result in a class of type type (rather than the to-be-avoided classobj). This doesn't hold true of older versions of Ren'Py, although at which point this occurred I'm unsure. So while it can't hurt to explicitly inherit from object it no longer appears to be a requirement of modern Ren'Py to facilitate rollback and saving compatibility.

User avatar
Kia
Eileen-Class Veteran
Posts: 1050
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: Proper way of using classes

#7 Post by Kia »

ow, you're right. I've seen `time` and assumed time is imported somewhere else causing a problem, jumping to conclusion I've missed the real question. :oops:

hapciupalit
Regular
Posts: 56
Joined: Tue Nov 13, 2018 6:00 am
Contact:

Re: Proper way of using classes

#8 Post by hapciupalit »

strayerror wrote: Sat Feb 15, 2020 7:18 pm
Adding a call to renpy.retain_after_load() to the end of the incTime method will likely resolve the issue you see. It's definitely worth reading up on this function in the documentation as it's not a panacea for all related cases, and so it's use can be quite situational.
Thank you very much good sir, I've been struggling with this issue for a few days. It's working perfect.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot]