Saveable characters; or whatever that gets closest and works

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
herenvardo
Veteran
Posts: 359
Joined: Sat Feb 25, 2006 11:09 am
Location: Sant Cugat del Vallès (Barcelona, Spain)
Contact:

Saveable characters; or whatever that gets closest and works

#1 Post by herenvardo » Sat Sep 20, 2008 8:11 pm

Essentially, I have several stuff about each character (such as stats, inventory, feelings, etc) that changes often during gameplay and hence needs to be cared about by save/load/rollback. I can make a class "Creature" to represent them (actually, I already have it partially done); but the main issue is that these creatures are indeed the characters that are speaking when I use renpy Character objects in say statements, so they should be the same object. The most (conceptually) obvious solution would be to put my "creature data" inside the character objects, probably inheriting the Creature class from renpy's Character; but last time I asked something similar, I was told that Character objects are not serializable.
Characters are not saveable, so they are ruled out for storing the "creature-data". Plan B is to reverse the things:
Is there any way I can make my Creature class similar enough to Character so renpy accepts it in say statements? I have thought on going to renpy's source, make a list of the functions in Character, then add each one to my Creature class, and implement them all by creating a Character object "on-the-fly" (the creature has all the information I might need for that), and delegate the task to the "volatile" Character. Before I get into this, it'd be good to know if it would work or if I'm wasting my time. Also, if this approach might work, it would also be interesting to know what do I really provide in my class (ie: functions in Character that are only used internally shouldn't be needed, but I wouldn't know which ones are).
If that doesn't work, I've also thought on plan B-bis: do python and renpy support the idea of implicit conversions as in C++/C# (ie: a specially-named method in class A that returns a B object and is implicitly invoked when an A object is used where a B is expected)?
If neither of this can work, but someone can come up with a plan B-bis-bis or C, it would also be appreciated :P

Thx in advance for any help provided.
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

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Saveable characters; or whatever that gets closest and works

#2 Post by PyTom » Sat Sep 20, 2008 8:41 pm

That's pretty easy. Just add the following to your creature class

Code: Select all

    def __call__(self, what, **kwargs):
        return getattr(store, self.character)(what, **kwargs)
And initialize self.character to the variable containing the character object.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
Wintermoon
Miko-Class Veteran
Posts: 701
Joined: Sat May 26, 2007 3:41 pm
Contact:

Re: Saveable characters; or whatever that gets closest and works

#3 Post by Wintermoon » Sat Sep 20, 2008 9:46 pm

PyTom wrote:

Code: Select all

    def __init__(self, what, **kwargs):
        return getattr(store, self.character)(what, **kwargs)
That can't be right. Returning anything other than None from __init__ raises an exception.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Saveable characters; or whatever that gets closest and works

#4 Post by PyTom » Sat Sep 20, 2008 9:47 pm

Sorry. I thought __call__, and typed __init__.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

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

Re: Saveable characters; or whatever that gets closest and works

#5 Post by herenvardo » Sat Sep 20, 2008 10:20 pm

:? ... ok... after ten minutes staring at this code snippet, and googling "getattr" within the python docs, I hope I start getting an idea of what that code is supposed to do... but I still have some doubts:
PyTom wrote:And initialize self.character to the variable containing the character object.
At first that was confusing: having the character object in a field would cause it to be saved when the containing object is saved, which wouldn't be a good thing. However, after finding out that getattr takes a string, I guess you mean the variable's name, which makes enough sense.

There is something that was confusing me even more: maybe should that __init__ actually be __call__? If so, then I already understand the code; otherwise I'm completelly lost :?
Update: I've seen the later replies when I was going to submit this ^^; So, everything makes sense now.

Yet this still misses my central point: getting rid of one of the variables. Fortunatelly, it seems that your suggestion is already a good basis for it: would this code work?:

Code: Select all

init python:
    class Creature:
        def __init__(self, name, color="#FFFFFF"):
            self.name=name
            self.color=color
        def __call__(self, what, **kwargs):
            return Character(self.name, color=self.color)(what, **kwargs)
That's a heavily simplified version, but it gets into the idea: actually, the name and color of creatures are initially based on user choices; and may sometimes change (for example, on some situations the name may get stuff like "[possessed]" or "[dreaming]" appended, and the color's saturation and brightness is used to denote emotional state, relying only on hue for identification). I've made a bit of testing and it seems to be working, but trying to get a Character object saved and loaded also seemed to work the last time I tried; so I'd like to have some confirmation that I'm not doing anything "forbidden".
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

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Saveable characters; or whatever that gets closest and works

#6 Post by PyTom » Sat Sep 20, 2008 10:33 pm

Yeah, that should work. You can create new Characters, and since the rewrite, it's relatively fast to do so.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

Post Reply

Who is online

Users browsing this forum: Google [Bot], Ocelot