Subclassing game objects ...

Scratch this whole post, I was looking at Raco’s original example and not the rest of the thread.

I’ve searched it and found an interesting lesson about composition. It showed me what it is and I think this will be the road for me to go. Thanks. If everything works out I’ll finish with writing a simple example that illustrates it. I better change the title of this thread to something like: “Subclassing and Composition”.

You would benefit from looking at design patterns. They are a good way of maintaining code flow and function

Sent from my Nexus 5 using Tapatalk

There’s something I find really confusing about sdfgeoff’s demo code.

import bge


def init(cont):
    mutated_object = CustomGameObject(cont.owner)
    cont.script = 'subclassDemo.main'
    
def main(cont):
    cont.owner.update()
    
class CustomGameObject(bge.types.KX_GameObject):
    def __init__(self, old_owner):
        '''Runs when you create/mutate the game object'''
        self.property = 1
        
    def update(self):
        self.property += 1        
        print(self.property)

The code never explicitly sets cont.owner to mutated_object, so you wouldn’t expect it to work. But it does.
cont.owner is automatically replaced by the new object whenever CustomGameObject(myObj) is called.

This is definitely not normal behavior for Python classes. So I looked at the docs for KX_GameObject, and it turns out that when you construct a new instance of a subclass of GameObject, it automatically deletes the old object and replaces it with the new one. You have to pass in the old object as the second argument to init, though (as in the example).

Very weird. I would’ve preferred to do it explicitly like this:

cont.owner = CustomGameObject(cont.owner)

Thank you for looking in on that. I’ve been following this thread (and even mentioned before I believe) that the above code should NOT work. It is NOT basic Python behavior. So, glad you dug that up. Now I can move on with my life in peace, haha.

The controller owner is a reference to a python object. The python object is a proxy for a c++ object. You cannot create new data in the bge so the new object must replace the existing one,lest you have two incomplete references to the same type. In other words, because the python object belongs to a c++ object, you cannot think of the python object as owning itself, instead it is a proxy for the c++ object and hence we should have only one proxy interface

Sent from my Nexus 5 using Tapatalk

afaik subclass a gameObject should be done only one time when any other obj know that exist the “old” gameObject.

otherwise can happen :

frame 151 : enemy see Player, store it in a property->> own[“player”] = player
frame 152 : enemy follow player stored in (own[“player”]) …OK
frame 153 : enemy follow player stored in (own[“player”]) …OK
frame 154 : Player do a subclass since has some new weapon
frame 155 : enemy follow player stored in (own[“player”]) …WRONG … the object stored not exist more!!

also , subclassing you cannot use any names you want

self.state -> already used
self.sendMessage -> already used
self.position -> already used

i not surely a expert just my -1 to subclass.
using a property you have all class cleaned!!

to be honest not like subclassing for different reason

someone can do a example of using component?
manage the armature can be a component?
using steering actator inside a class can be a component?
if so, what is the correct way to use it as component?
how work component?

@MarcoIT

frame 154 : Player do a subclass since has some new weapon

That is where you are wrong. The player will not change class because he has a new weapon. That is something the player HAS not what the player IS.
Subclassing only makes sense if you are doing it at the beginning of the game/scene, or to an object that has just been spawned. If you are doing it any other time, then you have a design flaw.

And as to your point that some variables are already used, they are named sensibly, and so you should be able to avoid accidentally using them. And even if they weren’t, if you discover a conflict, you can just be imaginitive, such as using AI_state instead of state.

And what do you mean by ‘component’? If you mean function, it’s just the same as normal. If you mean an actuator, then write a function to do it the normal way.

true! , thanks for this hints HAS/IS a lot useful, this is really where i do ever mistake , but was not so clear the “why” :wink:
(so…one subclass IS necessary/correct for my NPCS…)

Subclassing only makes sense if you are doing it at the beginning of the game/scene, or to an object that has just been spawned. If you are doing it any other time, then you have a design flaw.

well ,:yes:

And as to your point that some variables are already used, they are named sensibly, and so you should be able to avoid accidentally using them. And even if they weren’t, if you discover a conflict, you can just be imaginitive, such as using AI_state instead of state.

i use UPPERCASE usually to solve conflict…

anyway self.state should be “free”, and get another name a bit more dirty as :> self.òò__logicBrickState(for some debug purpose)
since is completely useless FROM python

And what do you mean by ‘component’? If you mean function, it’s just the same as normal. If you mean an actuator, then write a function to do it the normal way.

nope, i misleading some post above reading -> composition = component :smiley:
instead i guess do nothing (composition http://learnpythonthehardway.org/book/ex44.html)

thanks

If you subclass any other class you inherit ALL attributes of the super class.
You can explicitly overwrite existing names (mangling). If you discover such a situation, you should seriously ask yourself if the current design of your model is sufficient to your needs. The main question in this case is: Do I really need to subclass here or is it because I can?

Example: the KX_GameObject already has a state attribute for a very specific purpose. If you want to introduce a different “state” you need to express the difference to the super.state. This could be “behavior_state” or similar. You still have the state from KX_GameObject, additional you get a different behavior_state from your own class.