Classes and extending Characters
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.
Classes and extending Characters
Please note: This is more of a Python-related thread than purely Ren'Py. It's perfectly relevant to Ren'Py, but I doubt that any code examples given aren't going to start with "init python:". Just a warning to the non-programmers here.
First, how do I give default values to variables in classes? I know that this should be pretty damn simple. Heck, it probably actually is. But I don't quite get it, nor do I understand the _init_ routine inside the class. I know that it runs when a variable of the class' type is created, but the specific timing and the usage of it kinda confuses me.
Second, is it possible to pass classes to python routines? I know that the answer is probably "yes," but I don't want to write or rewrite 200 lines of code just to find out that you can't pass classes or that doing so has so many issues that it's not worth doing.
Third, is it possible to extend the Character class, so that I can give it extra variables that I can treat as if in the class? (This directly relates to the second question: I want to give RPG-style stat variables to a Character and be able to just pass the Character into my routines to make the code a lot cleaner and readable.) If so, how?
I know that these questions are probably findable somewhere in the Python documentation, but it took me a week to just find a fraction of what I needed about lists and matrices. Finding what you want in that thing is like finding a needle in a needlestack. (NCIS fans should now quote DiNozzo and then I quote Ziva.)
I've been making for myself a couple of Test projects to work on my code before I actually try to implement it, so I'll be trying to find these answers out on my own. I doubt I'll be able to get my own answers before the community can, though.
First, how do I give default values to variables in classes? I know that this should be pretty damn simple. Heck, it probably actually is. But I don't quite get it, nor do I understand the _init_ routine inside the class. I know that it runs when a variable of the class' type is created, but the specific timing and the usage of it kinda confuses me.
Second, is it possible to pass classes to python routines? I know that the answer is probably "yes," but I don't want to write or rewrite 200 lines of code just to find out that you can't pass classes or that doing so has so many issues that it's not worth doing.
Third, is it possible to extend the Character class, so that I can give it extra variables that I can treat as if in the class? (This directly relates to the second question: I want to give RPG-style stat variables to a Character and be able to just pass the Character into my routines to make the code a lot cleaner and readable.) If so, how?
I know that these questions are probably findable somewhere in the Python documentation, but it took me a week to just find a fraction of what I needed about lists and matrices. Finding what you want in that thing is like finding a needle in a needlestack. (NCIS fans should now quote DiNozzo and then I quote Ziva.)
I've been making for myself a couple of Test projects to work on my code before I actually try to implement it, so I'll be trying to find these answers out on my own. I doubt I'll be able to get my own answers before the community can, though.
- Wintermoon
- Miko-Class Veteran
- Posts: 701
- Joined: Sat May 26, 2007 3:41 pm
- Contact:
Re: Classes and extending Characters
Assign them in __init__.Formedras wrote:First, how do I give default values to variables in classes?
When you create a new instance of a class by calling that class:Formedras wrote:But I don't quite get it, nor do I understand the _init_ routine inside the class. I know that it runs when a variable of the class' type is created, but the specific timing and the usage of it kinda confuses me.
- Python creates a blank object of the class you want.
- Python call that object's __init__ method, passing along any arguments that you passed to the class. At the time when this happens, the object already exists.
Yes. Classes, modules, functions and bound methods are all first class objects in Python.Formedras wrote:Second, is it possible to pass classes to python routines?
Don't do that. Character objects aren't saved.Formedras wrote:Third, is it possible to extend the Character class, so that I can give it extra variables that I can treat as if in the class? (This directly relates to the second question: I want to give RPG-style stat variables to a Character and be able to just pass the Character into my routines to make the code a lot cleaner and readable.) If so, how?
- Aenakume
- Regular
- Posts: 182
- Joined: Mon Aug 11, 2008 4:38 am
- Projects: Arts... i hate arts -_-
- Contact:
Re: Classes and extending Characters
Not only that, Character objects aren't really logically compatible with actual characters in the sense Formedras means. For example, if you were making a game with Eileen, and she was at school one scene and at home the next, you would probably find it more natural to make two different characters - one in school uniform and one in normal clothes, each with its own set of expressions. The more different versions of Eileen you have (beach, formal dress, naughty-naughty), the more Character objects you might create... even though it's all just one character - Eileen. i think of Characters as characters in a scene, not actual unique characters.Wintermoon wrote:Don't do that. Character objects aren't saved.Formedras wrote:Third, is it possible to extend the Character class, so that I can give it extra variables that I can treat as if in the class? (This directly relates to the second question: I want to give RPG-style stat variables to a Character and be able to just pass the Character into my routines to make the code a lot cleaner and readable.) If so, how?
So you'd probly be better off to just make your own stats class, and not bother extending the Character class.
“You can lead a fool to wisdom, but you cannot make him think.”
Re: Classes and extending Characters
whatAenakume wrote:For example, if you were making a game with Eileen, and she was at school one scene and at home the next, you would probably find it more natural to make two different characters - one in school uniform and one in normal clothes, each with its own set of expressions. The more different versions of Eileen you have (beach, formal dress, naughty-naughty), the more Character objects you might create... even though it's all just one character - Eileen. i think of Characters as characters in a scene, not actual unique characters.
Not that characters are really multipurpose characters and can or should be used as such, but what you just said doesn't make sense either. A Ren'Py Character is pretty much just a very elaborate text formatting device, nothing else. Actual character graphics have nothing to do with it except in some very, very far-fetched ways.
The rest is left as an exercise for the reader.
- Aenakume
- Regular
- Posts: 182
- Joined: Mon Aug 11, 2008 4:38 am
- Projects: Arts... i hate arts -_-
- Contact:
Re: Classes and extending Characters
i guess you don't use side images?delta wrote:whatAenakume wrote:For example, if you were making a game with Eileen, and she was at school one scene and at home the next, you would probably find it more natural to make two different characters - one in school uniform and one in normal clothes, each with its own set of expressions. The more different versions of Eileen you have (beach, formal dress, naughty-naughty), the more Character objects you might create... even though it's all just one character - Eileen. i think of Characters as characters in a scene, not actual unique characters.
Not that characters are really multipurpose characters and can or should be used as such, but what you just said doesn't make sense either. A Ren'Py Character is pretty much just a very elaborate text formatting device, nothing else. Actual character graphics have nothing to do with it except in some very, very far-fetched ways.
“You can lead a fool to wisdom, but you cannot make him think.”
Re: Classes and extending Characters
Nobody uses side images, because it's not the default. The like three people using side images should know what they are doing.
Apart from that, the side image is an example of a way that I would consider far-fetched. You either have to use a dynamic displayable (which has nothing to do with Characters directly) or create one Character per image, which is totally beside the point of Characters.
Apart from that, the side image is an example of a way that I would consider far-fetched. You either have to use a dynamic displayable (which has nothing to do with Characters directly) or create one Character per image, which is totally beside the point of Characters.
The rest is left as an exercise for the reader.
- herenvardo
- Veteran
- Posts: 359
- Joined: Sat Feb 25, 2006 11:09 am
- Location: Sant Cugat del Vallès (Barcelona, Spain)
- Contact:
Re: Classes and extending Characters
That got me interested on the threadFormedras wrote:Please note: This is more of a Python-related thread than purely Ren'Py. It's perfectly relevant to Ren'Py, but I doubt that any code examples given aren't going to start with "init python:". Just a warning to the non-programmers here.
Wintermoon's reply above is quite correct, but I thought you might better see it with some simple example:Formedras wrote:First, how do I give default values to variables in classes? I know that this should be pretty damn simple. Heck, it probably actually is. But I don't quite get it, nor do I understand the _init_ routine inside the class. I know that it runs when a variable of the class' type is created, but the specific timing and the usage of it kinda confuses me.
Code: Select all
class MyClass:
def __init__(self, stuff, whatever="something"): # this block defines the __init__ method
self.stuff = stuff # initialize each relevant field with the provided parameters
self.whatever = whatever # just like above
self.money = 0 # The objects will always start with 0 money
# The constructor call can't affect this value, because it's not based on any of the arguments
# ... later on the script:
MyObj1 = MyClass("stuff1", "what1") # this creates an object with the initial values:
# MyObj1.stuff = "stuff1", MyObj1.whatever = "what1", MyObj1.money = 0
MyObj2 = MyClass("stuff2") # now the whatever argument is omitted, and the default value will be used:
# MyObj2.stuff = "stuff2", MyObj2.whatever = "something", MyObj2.money = 0
That's most of it. However, I think it's worth to point out that you should pass to a routine what it expects. If a method wants a function or callable object and you feed it a tuple of modules Python is very likely to spit a TypeError at your face. But it's perfectly possible to define a method that takes a class, or a tuple of modules, or (almost) anything you can imagine, and (assuming you don't mess something up on the method itself) it can perfectly workWintermoon wrote:Yes. Classes, modules, functions and bound methods are all first class objects in Python.Formedras wrote:Second, is it possible to pass classes to python routines?
And, of course, you can also pass objects and "normal" values (such as numbers or strings) as well
This, in theory, can't be done on ren'py, mostly because Character objects are not saveable (despite Ren'py has actually succeed at saving/loading them everytime I tried, it's still not advisable because it's not supposed to work). However, if you are like me (and I have a good reason to think you are), a "can't be done" won't be enough of an answer for you. Actually, I faced a very similar problem, for a very similar purpose (that's why I think you are like meFormedras wrote:Third, is it possible to extend the Character class, so that I can give it extra variables that I can treat as if in the class? (This directly relates to the second question: I want to give RPG-style stat variables to a Character and be able to just pass the Character into my routines to make the code a lot cleaner and readable.) If so, how?
The solution was to define a RPGish character class (I called it Creature on my project) with all the RPGish stuff, plus all the stuff needed to define a Ren'py Character object. Then added a __call__ method that generates a Character object, based on this data, on the fly; and finally calls such object with the given arguments to produce the "say" effect: voilà, I got a saveable object that stores all my RPG-ish stuff and doubles as a Ren'py Character clone ^^
Of course, I didn't figure out how to do this on my own, but I had to ask for help on these forums. I strongly advise you to take a look on that threat, found at http://lemmasoft.renai.us/forums/viewto ... f=8&t=4097.
It's worth to mention that my Creature class' approach could easily allow for side images, despite I don't use them (at least not currently): the actual Character objects are very short-lived, they only last for a single say statement, and a new object is generated for the next use; so it's easily possible to store the different side images for each creature as a list on the class, keep track of which scene we are on, and add some logics on the __call__ method to chose the appropriate image.Aenakume wrote:i guess you don't use side images?
Even with "normal" Character objects, I don't think it's impossible to have different side images for a single character object: ConditionSwitch can do wonders
Wrong: apparently Aenakume doesdelta wrote:Nobody uses side images
HTH
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 
- Aenakume
- Regular
- Posts: 182
- Joined: Mon Aug 11, 2008 4:38 am
- Projects: Arts... i hate arts -_-
- Contact:
Re: Classes and extending Characters
Impossible, no - but when you get a longer and more detailed story, things start to add up. Let's say you have a single character that changes outfit 4 different times, with 5 different expressions for each outfit - that's already a 20 condition ConditionSwitch, and that's not really that many expressions and it doesn't include lip flapping. In short order you can find yourself with a 100+ condition ConditionSwitch, for a major character in a long game.herenvardo wrote:It's worth to mention that my Creature class' approach could easily allow for side images, despite I don't use them (at least not currently): the actual Character objects are very short-lived, they only last for a single say statement, and a new object is generated for the next use; so it's easily possible to store the different side images for each creature as a list on the class, keep track of which scene we are on, and add some logics on the __call__ method to chose the appropriate image.Aenakume wrote:i guess you don't use side images?
Even with "normal" Character objects, I don't think it's impossible to have different side images for a single character object: ConditionSwitch can do wonders
For minor characters like creatures - like what you're talkin about - there's no real problem, of course.
*shrug* Well apparently i'm nobody, and doing "very, very far-fetched" things in Ren'Py... so i guess i don't count, eh?herenvardo wrote:Wrong: apparently Aenakume doesdelta wrote:Nobody uses side images
“You can lead a fool to wisdom, but you cannot make him think.”
- herenvardo
- Veteran
- Posts: 359
- Joined: Sat Feb 25, 2006 11:09 am
- Location: Sant Cugat del Vallès (Barcelona, Spain)
- Contact:
Re: Classes and extending Characters
I didn't say ConditionSwitch was the best approach, not even that it'd be a good idea. I just mentioned it as a possibility.Aenakume wrote:Impossible, no - but when you get a longer and more detailed story, things start to add up. Let's say you have a single character that changes outfit 4 different times, with 5 different expressions for each outfit - that's already a 20 condition ConditionSwitch, and that's not really that many expressions and it doesn't include lip flapping. In short order you can find yourself with a 100+ condition ConditionSwitch, for a major character in a long game.herenvardo wrote:It's worth to mention that my Creature class' approach could easily allow for side images, despite I don't use them (at least not currently): the actual Character objects are very short-lived, they only last for a single say statement, and a new object is generated for the next use; so it's easily possible to store the different side images for each creature as a list on the class, keep track of which scene we are on, and add some logics on the __call__ method to chose the appropriate image.Aenakume wrote:i guess you don't use side images?
Even with "normal" Character objects, I don't think it's impossible to have different side images for a single character object: ConditionSwitch can do wonders
I'm not sure if you really know what I'm talking aboutAenakume wrote:For minor characters like creatures - like what you're talkin about - there's no real problem, of course.
Code: Select all
myChar.sides["school_outfit"]["happy"]Currently, all the creature sprites (both "history-mode" character sprites and combat effects and animations) in my project are being referenced from their Creature objects... it's just a matter of time I get them working directly with show statements
Well, in summary, with a bit of imagination and a good deal of headaches, the sky is the limit! ^^
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 
Who is online
Users browsing this forum: Bing [Bot], Ocelot, Sergei Falcon


