Storing attributes of class and class instance
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.
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.
Storing attributes of class and class instance
Hi there. I already thought of a solution to my problem, but before going to a code nightmare, I prefer to make sure that it's not solved already.
I have some python classes in my init python block. These classes make instances with attributes.
Problem 1 is, renpy doesn't save the state of those instances, so their attributes remain as the initial values.
Problem 2. If I play the game and rollback, the state reamins the state of the last statement executed, so provoke some inconsistencies.
Is there a solution to this problem? I DEFINETELY want to use python classes: I have a complex behaviour, I know how to write advanced code in python and I don't wanna go the "easier" way of using thousands of variables that confuse the hell out of me and my script.
If there's no solution, those with python experience (pytom <3), what do you think of what I thought?
Since Ren'py saves the state of simple variables, I could make a dict for classes, called oop_classes, with the classes names as keys and its values another dict with attribute name key and value as value of that attribute.
Similar behaviour for a different dict oop_instances with all the attributes for each instance of any class.
And also overwriting some of the special class methods of python of a class OOP which make sure that any get/set of attributes of a given class/instance is saved to that dict. So, finally, any class that I define would inherit from OOP so that its gets/sets work the way I want.
The one true problem here would be garbage collection, I think. I don't know if there are special methods for deletion of objects too, but I'd try to make a workaround somehow.
Anyway, I think this solution is far too complex for ren'py, there should be an easier solution, only that I didn't find it. Could anyone help me?
Thank you SO much.
PS: if you need a more detailed explanation of my solution just ask, since I think I really didn't make it quite clear...
PS2: sorry if there's some bad english
I have some python classes in my init python block. These classes make instances with attributes.
Problem 1 is, renpy doesn't save the state of those instances, so their attributes remain as the initial values.
Problem 2. If I play the game and rollback, the state reamins the state of the last statement executed, so provoke some inconsistencies.
Is there a solution to this problem? I DEFINETELY want to use python classes: I have a complex behaviour, I know how to write advanced code in python and I don't wanna go the "easier" way of using thousands of variables that confuse the hell out of me and my script.
If there's no solution, those with python experience (pytom <3), what do you think of what I thought?
Since Ren'py saves the state of simple variables, I could make a dict for classes, called oop_classes, with the classes names as keys and its values another dict with attribute name key and value as value of that attribute.
Similar behaviour for a different dict oop_instances with all the attributes for each instance of any class.
And also overwriting some of the special class methods of python of a class OOP which make sure that any get/set of attributes of a given class/instance is saved to that dict. So, finally, any class that I define would inherit from OOP so that its gets/sets work the way I want.
The one true problem here would be garbage collection, I think. I don't know if there are special methods for deletion of objects too, but I'd try to make a workaround somehow.
Anyway, I think this solution is far too complex for ren'py, there should be an easier solution, only that I didn't find it. Could anyone help me?
Thank you SO much.
PS: if you need a more detailed explanation of my solution just ask, since I think I really didn't make it quite clear...
PS2: sorry if there's some bad english
-
- Eileen-Class Veteran
- Posts: 1258
- Joined: Fri Sep 21, 2007 7:13 am
- Projects: a battle engine
- Contact:
Re: Storing attributes of class and class instance
Try inheriting from _object instead of object
Re: Storing attributes of class and class instance
I do that everywhere but in this case it may aggravate Problem 2.Asceai wrote:Try inheriting from _object instead of object
Sounds like an utterly false statement, at least try to provide an example of this.sqmath wrote:Problem 1 is, renpy doesn't save the state of those instances, so their attributes remain as the initial values.
I don't use rollback but if you can figure out how it works (read Ren'Py code a bit), you can control that even with an exceptionally complex code.sqmath wrote: Problem 2. If I play the game and rollback, the state reamins the state of the last statement executed, so provoke some inconsistencies.
The only real problem you may encounter is when using Ren'Pys init is you cannot change anything on classes namespace (it will be overwritten next time Ren'Py is launched), otherwise you can program in Ren'Py as you would in pure Python using init or exactly as you would in pure Python using .py files and separate modules.
=============================
Basically your post looks like an invention of problems that are do not actually exist. If possible at all, try to isolate problematic code and post an example of it not working (whatever works with one attribute will work with a 100).
- ArachneJericho
- Regular
- Posts: 196
- Joined: Sun Jun 22, 2014 2:04 am
- Projects: Kaguya Hime
- Tumblr: mousedeerproductions
- Location: Seattle, WA, USA
- Contact:
Re: Storing attributes of class and class instance
As for objects, try inheriting from _object as otherwise your object's state will not be rollable-back.
I'm stupid. Forget all this.
Last edited by ArachneJericho on Tue Jul 08, 2014 9:05 pm, edited 1 time in total.
Re: Storing attributes of class and class instance
You contradict me from just one post above:ArachneJericho wrote:As for objects, try inheriting from _object as otherwise your object's state will not be rollable-back.
"object" is specifically created RenPy wrapper to facilitate Rollbacks, _object just like _dict, _set and _list are the original Python 2.7 (or below) implementations. In what world will _object work better with Rollback than the Ren'Py thing? It'll more likely end up screwing the game up completely.xela wrote:I do that everywhere but in this case it may aggravate Problem 2.Asceai wrote:Try inheriting from _object instead of object
I think that Authors original problem is with changing variables directly on classes namespaces during the game/init stages, I am yet to come up with a solution that would be considerably more elegant than what the Author suggests.
- ArachneJericho
- Regular
- Posts: 196
- Joined: Sun Jun 22, 2014 2:04 am
- Projects: Kaguya Hime
- Tumblr: mousedeerproductions
- Location: Seattle, WA, USA
- Contact:
Re: Storing attributes of class and class instance
You're right. Sorry about that.xela wrote:You contradict me from just one post above:ArachneJericho wrote:As for objects, try inheriting from _object as otherwise your object's state will not be rollable-back.
"object" is specifically created RenPy wrapper to facilitate Rollbacks, _object just like _dict, _set and _list are the original Python 2.7 (or below) implementations. In what world will _object work better with Rollback than the Ren'Py thing? It'll more likely end up screwing the game up completely.xela wrote:I do that everywhere but in this case it may aggravate Problem 2.Asceai wrote:Try inheriting from _object instead of object
I think that Authors original problem is with changing variables directly on classes namespaces during the game/init stages, I am yet to come up with a solution that would be considerably more elegant than what the Author suggests.
Re: Storing attributes of class and class instance
Hi everyone, thank you for your comments. As I see that my question is not that clear I'll post some code later with an example on why it doesn't work. I can't do so till midnight though (my midnight, around the time when I wrote my first message) so I'll need for you to wait a bit.
Thank you so much, I didn't expect so many comments so soon
EDIT:
Here's an example that illustrates my problem.
With this code, if you save, exit the game, restart and load, you get tmp = 1 though with playing without save you get tmp = 2.
I hope this makes matters easier.
If rollback is an issue here, it could be blocked, but I think it's quite a nice feature to block it at the first trouble.
So, what could be the solution?
Thank you so much, I didn't expect so many comments so soon
EDIT:
Here's an example that illustrates my problem.
Code: Select all
init python:
class A:
def __init__(self, x):
self.a = x
def __str__(self):
return str(self.a)
class B:
def __init__(self, x):
self.b = A(x)
def __str__(self):
return str(self.b)
tmp = B(1)
label start:
"tmp = [tmp]"
$tmp.b = A(2)
"tmp = [tmp]" #Save here
I hope this makes matters easier.
If rollback is an issue here, it could be blocked, but I think it's quite a nice feature to block it at the first trouble.
So, what could be the solution?
Re: Storing attributes of class and class instance
Sorry for the repost, this is just to make everyone who commented aware of the edit.
- trooper6
- Lemma-Class Veteran
- Posts: 3712
- Joined: Sat Jul 09, 2011 10:33 pm
- Projects: A Close Shave
- Location: Medford, MA
- Contact:
Re: Storing attributes of class and class instance
Why are you defining tmp = B(1) in the into python block?
I am no expert, but I put all of my variables and instances of classes at the beginning of the start block, not earlier.
So what happens if you do this instead?
I am no expert, but I put all of my variables and instances of classes at the beginning of the start block, not earlier.
So what happens if you do this instead?
Code: Select all
init python:
class A:
def __init__(self, x):
self.a = x
def __str__(self):
return str(self.a)
class B:
def __init__(self, x):
self.b = A(x)
def __str__(self):
return str(self.b)
label start:
tmp = B(1)
"tmp = [tmp]"
$tmp.b = A(2)
"tmp = [tmp]" #Save here
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
*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
- trooper6
- Lemma-Class Veteran
- Posts: 3712
- Joined: Sat Jul 09, 2011 10:33 pm
- Projects: A Close Shave
- Location: Medford, MA
- Contact:
Re: Storing attributes of class and class instance
Why are you defining tmp = B(1) in the into python block?
I am no expert, but I put all of my variables and instances of classes at the beginning of the start block, not earlier.
So what happens if you do this instead?
I am no expert, but I put all of my variables and instances of classes at the beginning of the start block, not earlier.
So what happens if you do this instead?
Code: Select all
init python:
class A:
def __init__(self, x):
self.a = x
def __str__(self):
return str(self.a)
class B:
def __init__(self, x):
self.b = A(x)
def __str__(self):
return str(self.b)
label start:
tmp = B(1)
"tmp = [tmp]"
$tmp.b = A(2)
"tmp = [tmp]" #Save here
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
*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
Re: Storing attributes of class and class instance
Since those variables must be defined during all the game and some of them can't be saved since can't be pickled (I use some lambdas), defining them in an init block avoids the problem of pickling those lambdas.
Could this be the source of my problem?
Could this be the source of my problem?
Re: Storing attributes of class and class instance
Simplified:
Keep starting a new game and you'll get += 1000 every time that you do. I had similar problem, the documentation states that init is ran every time the game is started, I got confused by that thinking that it meant the game created with Ren'Py, not Ren'Py itself. So basically, init is run once Ren'Py is started (and likely restarted) so without redefining var after the label start, you'll just keep adding stuff to it...
There is no simple way to fix this keeping the code structure. You need to think of a different approach.
Depending on the issues forcing you to use that kind of coding (I don't know what those are), you could try:
and see if this works for you.
Code: Select all
init python:
class A(object):
def __init__(self, x):
self.attr = x
var = A(0)
label start:
"[var.attr]"
$ var.attr += 1000
There is no simple way to fix this keeping the code structure. You need to think of a different approach.
Depending on the issues forcing you to use that kind of coding (I don't know what those are), you could try:
Code: Select all
init python:
from copy import deepcopy
class A:
def __init__(self, x):
self.a = x
def __str__(self):
return str(self.a)
class B:
def __init__(self, x):
self.b = A(x)
def __str__(self):
return str(self.b)
tmp = B(1)
label start:
"tmp = [tmp]"
$ tmp = deepcopy(tmp)
$ tmp.b = A(2)
"tmp = [tmp]" #Save here
Who is online
Users browsing this forum: Bing [Bot]