Class objects don't revert on rollback?

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
Aleema
Lemma-Class Veteran
Posts: 2677
Joined: Fri May 23, 2008 2:11 pm
Organization: happyB
Tumblr: happybackwards
Contact:

Class objects don't revert on rollback?

#1 Post by Aleema »

Okay, silly question time ...

So I'm learning and using Python object classes, but I remember why I dropped them a while ago: they don't seem to behave like they should! All other variables, lists, etc go back to previous states on rollback or initialize properly. But these objects don't really do that ... They appear to be saving and loading right and run well the first time, but rollback just breaks it. The rollback thing is so crucial that I may have to disable it if I can't get it to retain. Once it's changed, it seems to stay changed.

For example:

Code: Select all

init python:
    class Fruit:
        def __init__(self):
            self.eaten = False
        def eat(self):
            self.eaten = True
            
label start:
    $ Apple = Fruit()
    e "I have an apple."
    
    
    if Apple.eaten:
        e "I ate it!"
    else:
        e "I think I'll eat it."
        $ Apple.eat()
        e "Yum!"
If I play through once, I'll reach "Yum!" but if I roll back to "I have an apple" line and proceed again, it will jump right to "I ate it!" Meaning, even though I rolled back, Apple.eaten was still True.

Am I doing it wrong? Do I need to update (currently 6.12.2)? Or ... is this just expected behavior? I read this page as well as I could, and as far as I can tell, objects should conform to rollback like other variables ... :(
Last edited by Aleema on Sat Nov 26, 2011 2:05 pm, edited 2 times in total.

Anima
Veteran
Posts: 448
Joined: Wed Nov 18, 2009 11:17 am
Completed: Loren
Projects: PS2
Location: Germany
Contact:

Re: Class objects don't revert on rollback?

#2 Post by Anima »

Try:

Code: Select all

class Fruit(store.object):
It helped a bit when I had problems with rollback.
Avatar created with this deviation by Crysa
Currently working on:
  • Winterwolves "Planet Stronghold 2" - RPG Framework: Phase III

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Class objects don't revert on rollback?

#3 Post by jack_norton »

From what I remember, in practice you need to put the suffix "store." when using classes if you want it to interact well with the rest of Ren'Py flow :)
(including even save/load, if I remember correctly even the variables weren't saving, but was a while ago when I tried to use python classes and Ren'Py).
follow me on Image Image Image
computer games

User avatar
Aleema
Lemma-Class Veteran
Posts: 2677
Joined: Fri May 23, 2008 2:11 pm
Organization: happyB
Tumblr: happybackwards
Contact:

Re: Class objects don't revert on rollback?

#4 Post by Aleema »

Ah!! :D Wow, I'm glad that was relatively easy to fix. It seems to have fixed many problems. Thanks!

User avatar
Deji
Cheer Idol; Not Great at Secret Identities
Posts: 1592
Joined: Sat Oct 20, 2007 7:38 pm
Projects: http://bit.ly/2lieZsA
Organization: Sakevisual, Apple Cider, Mystery Parfait
Tumblr: DejiNyucu
Deviantart: DejiNyucu
Location: Chile
Contact:

Re: Class objects don't revert on rollback? [Solved]

#5 Post by Deji »

EDIT: searching the forum some more, I found this thread http://lemmasoft.renai.us/forums/viewto ... f=8&t=4894 which explains the complexities of dealing with objects being saved, loaded and/or rollbacked.

So... I'll probably have to discard my object-centric idea and go back to handle 50+ variables and repeat 10 times about 10 lines of code instead of the 10 objects with 5 attributes each and one function that I wanted >:
Oh well ^^;

-------------------------------------

I'm having problems with this myself ):

I tried using what Spiky suggested, but it doesn't really work
I looked for store.variable_name but I'm not sure how to apply it in my case D: (I thought about using store.self.attribute, but that doens't work, of course ^^; )

If I have something like:

Code: Select all

 init python:
    class AnObject(store.object):
        def __init__(self, name):
            self.name = name
            #values the object is initialized with
            self.att1, self.att2, self.att3 = "a", "b", "c"          
                        
        def setPredef(self,predef):
            if predef== "d":
                self.att2, self.att3 = "d","d"
            elif predef == "e":
                 self.att2, self.att3 = "e","e"
               
        def changeElem(self,element,variation):
            if element == "att1":
                self.att1 = variation
            elif element == "att2":
                self.att2 = variation
            elif element == "att3":
                self.att3 = variation
                
           
And then I have...

Code: Select all

init:
    $Object1 = AnObject("object1")
    
# The game starts here.
label start:

     "Objects 1's att1 is [Object1.att1] (which should be -a-)"
     $Object1.changeElem("att1", "lalala")
     "Hmm."
     "I'll save now. I changed Object1's att1 two lines ago and it should be \"lalala\"... and it actually is [Object1.att1]"
     if Object1.att1 == "bluhbluh":
         jump bluhbluh
     elif Object1.att1 == "a":
         jump ifa
     
label later:
    
    "Now I'll change it to \"bluhbluh\"."
    $Object1.changeElem("att1", "bluhbluh")
    "Now try going back via rollback or loading the save and see what happens!"
    jump end
    
label bluhbluh:
    "Bluhbluh? Seriously? D:"
    jump the_end
label ifa:
    "Uhm... a? Shouldn't it be "lalala"?"
    jump the_end
label the_end:
    "The end!"
    $renpy.full_restart()
So... I reach bluhbluh if, after reaching the change, I rollback or load the previously saved game at the beginning.
And I reach ifa if, upon restarting the game, I load the game from the main menu.

I have many objects that actually display things on the screen, so this behavior is a real trouble for me right now @_@
Image
Tumblr | Twitter
Forever busy :')
When drawing something, anything, USE REFERENCES!! Use your Google-fu!
Don't trust your memory, and don't blindly trust what others teach you either.
Research, observation, analysis, experimentation and practice are the key! (:

Spiky Caterpillar
Veteran
Posts: 253
Joined: Fri Nov 14, 2008 7:59 pm
Completed: Lots.
Projects: Black Closet
Organization: Slipshod
Location: Behind you.
Contact:

Re: Class objects don't revert on rollback? [Solved]

#6 Post by Spiky Caterpillar »

Deji wrote: And then I have...

Code: Select all

init:
    $Object1 = AnObject("object1")
The problem's that Object1 is being created in an init block, so as far as Ren'Py is concerned it hasn't actually been changed. To make it saveable, move the initial creation to sometime after the game's started running, like so:

Code: Select all

label start:
     $ Object1=AnObject('object1')
     "Objects 1's att1 is [Object1.att1] (which should be -a-)"
     $ Object1.att1 = 'HoNk' # Because this is simpler than changeElem
Nom nom nom nom nom LEAVES.

User avatar
Deji
Cheer Idol; Not Great at Secret Identities
Posts: 1592
Joined: Sat Oct 20, 2007 7:38 pm
Projects: http://bit.ly/2lieZsA
Organization: Sakevisual, Apple Cider, Mystery Parfait
Tumblr: DejiNyucu
Deviantart: DejiNyucu
Location: Chile
Contact:

Re: Class objects don't revert on rollback? [Solved]

#7 Post by Deji »

Spiky Caterpillar wrote:
Deji wrote: And then I have...

Code: Select all

init:
    $Object1 = AnObject("object1")
The problem's that Object1 is being created in an init block, so as far as Ren'Py is concerned it hasn't actually been changed. To make it saveable, move the initial creation to sometime after the game's started running, like so:

Code: Select all

label start:
     $ Object1=AnObject('object1')
     "Objects 1's att1 is [Object1.att1] (which should be -a-)"
     $ Object1.att1 = 'HoNk' # Because this is simpler than changeElem
Yeah, I noticed that afterwards X_x

Problem for me though, is that on my actual code, I need to create the object in an init block because it's needed by another thing that must be defined on an init block. It seems handling that with classes just won't do ^^;

I'll keep it in mind for other objects I need to make later on, though (:
Image
Tumblr | Twitter
Forever busy :')
When drawing something, anything, USE REFERENCES!! Use your Google-fu!
Don't trust your memory, and don't blindly trust what others teach you either.
Research, observation, analysis, experimentation and practice are the key! (:

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Class objects don't revert on rollback?

#8 Post by jack_norton »

I don't understand, you can just do all the initialization at start of the code, no?
follow me on Image Image Image
computer games

User avatar
Aleema
Lemma-Class Veteran
Posts: 2677
Joined: Fri May 23, 2008 2:11 pm
Organization: happyB
Tumblr: happybackwards
Contact:

Re: Class objects don't revert on rollback?

#9 Post by Aleema »

You can do both, I believe.

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Class objects don't revert on rollback?

#10 Post by jack_norton »

Yes for arrays/lists etc I usually have on init:
stats=[ ]
and then just under label start:
stats=[50,50,50,50,50,50,50]

so I think is the same with Classes even if I never used them myself a lot :oops:
follow me on Image Image Image
computer games

User avatar
Deji
Cheer Idol; Not Great at Secret Identities
Posts: 1592
Joined: Sat Oct 20, 2007 7:38 pm
Projects: http://bit.ly/2lieZsA
Organization: Sakevisual, Apple Cider, Mystery Parfait
Tumblr: DejiNyucu
Deviantart: DejiNyucu
Location: Chile
Contact:

Re: Class objects don't revert on rollback?

#11 Post by Deji »

@Jack: Hmm... You say maybe I should make the class __init__ empty with a "pass" and then initialize the object during start?
I'll give it a try and see how that works, because that'd solve everything @_@
Image
Tumblr | Twitter
Forever busy :')
When drawing something, anything, USE REFERENCES!! Use your Google-fu!
Don't trust your memory, and don't blindly trust what others teach you either.
Research, observation, analysis, experimentation and practice are the key! (:

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4084
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Class objects don't revert on rollback?

#12 Post by jack_norton »

I think your problem is:
self.att3 = "a", "b", "c"
you shouldn't initialize values there.
But have at beginning of your code after the start label a call to the Class passing the variables you want to set by default?
I'm a newbie regarding classes too :(
follow me on Image Image Image
computer games

User avatar
Deji
Cheer Idol; Not Great at Secret Identities
Posts: 1592
Joined: Sat Oct 20, 2007 7:38 pm
Projects: http://bit.ly/2lieZsA
Organization: Sakevisual, Apple Cider, Mystery Parfait
Tumblr: DejiNyucu
Deviantart: DejiNyucu
Location: Chile
Contact:

Re: Class objects don't revert on rollback?

#13 Post by Deji »

Okay, I tried making an empty class, defining an external function (that takes the object as the argument) to initialize the object's attributes (with att1, att2 and att3) and external methods to change those attributes in groups.

Now, the rolback and load-from-inside-the-game problems are still there and when I load after just opening the game, all the attributes have vanished!

So... yeah. I gave up on this idea, lol. I'll try with lists later instead, as your example, and see if that works ^^;
Image
Tumblr | Twitter
Forever busy :')
When drawing something, anything, USE REFERENCES!! Use your Google-fu!
Don't trust your memory, and don't blindly trust what others teach you either.
Research, observation, analysis, experimentation and practice are the key! (:

herenvardo
Veteran
Posts: 359
Joined: Sat Feb 25, 2006 11:09 am
Location: Sant Cugat del Vallès (Barcelona, Spain)
Contact:

Re: Class objects don't revert on rollback?

#14 Post by herenvardo »

Deji wrote:Okay, I tried making an empty class, defining an external function (that takes the object as the argument) to initialize the object's attributes (with att1, att2 and att3) and external methods to change those attributes in groups.

Now, the rolback and load-from-inside-the-game problems are still there and when I load after just opening the game, all the attributes have vanished!
The problem here is that you are still creating your object in the init phase (you only change its fields afterwards).

For a variable to participate in save/load/rollback, it must be assigned to after the init phase.
Deji wrote:So... yeah. I gave up on this idea, lol. I'll try with lists later instead, as your example, and see if that works ^^;
This isn't likely to work. If you try to create the list on the init phase, and "fill" it afterwards, for example, the still will still be ignored by save/load/rollback.

Take a look at these examples:

Code: Select all

init python:
    class myClass:
        pass
    someList = [] # Won't be saved/rolled back
    someObject = myClass() # Won't be saved/rolled back
label start:
    $ someList[0] = "something" # Still, someList won't be saved
    $ someObject.someField = "something" # Still, someObject won't be saved
    $ savedList = [ 0 ] # This will be saved
    $ savedObject = myClass() # And so will this
    $ savedObject.field = someObject # This will cause someObject to be saved, but with caveats:
    if savedObject.field is someObject: # This will be true originally, but false after a save+load
        $ pass
The real solution to the problem is to create as much as possible after the init phase. During init, you should only be defining functions, classes, and variables that won't change at all during the game. Everything else should be defined afterwards.

So, here comes a big question: why do you want to create those objects during init? If you are willing to post the code (or the relevant fragments) that depends on those objects so early, I will try to help you refactoring it to avoid these issues.
I have failed to meet my deadlines so many times I'm not announcing my projects anymore. Whatever I'm working on, it'll be released when it is ready :P

Post Reply

Who is online

Users browsing this forum: BBN_VN