Why only 1 npc is working when they share same python module?

i have python script and inside i use a function as a python module. Why when i duplicate the npc , only 1 is active ?

I use own = cont.owner , there’s no error generated , so i dont understand why i have to create a duplicate of the same script/module for each of my npc’s

I do not fully understand your question… because a from programmatically standpoint:

A module is a “collection” of functions and objects to be used as a “library”.

So usually when adding some behaviour to some object this object has to have some addBehaviour( Behaviour b) – method which has to follow at least some Behaviour interface.

Or when using some more un-OOP approach add this by some function (using pointers)
addBehaviour( Object x, Behaviour b)

In Python ther are no pointer by you also do not have to use objects dirived from class…

Anyway:
You may have to elaborate this… (one time assignment ??)

… to get a more suited answer.

ofc, talking with a BGE standpoint.

So, those 2 bricks are 2 python modules (at least, in our BGE stand of view) attached to a npc . “look” and “play” are 2 functions inside a same npc.py

image

I was saying that if i duplicate (1 or many times) the npc object (character on screen) … i noticed that only npc character is moving, others aren’t. The file npc.py isn’t duplicated , they are sharing the same python script .

And own = cont.owner is just a pratice we use to refer the object owning the file.

No error in console

Ohh… yes logic bricks… i totaly forgot… only used this a littel back in 2.79…

I had to look into the Gamelogic Module template to remember…

def main(cont):
    own = cont.owner

so the script is actually associated for every npc ( in 2.79 show “over” the image you showed) … :thinking: andthe docu says something about

cont.owner → The object the controller is attached to.

So i do not remember correctly if changes on the localPosition or worldPosition does immediately take effect or something like applyMovement(..) has to be called…

Anyway:
This should be “done” by the engine for every object associated to any controller… but you say only one is working… (so it seems you know how do do this…)
…i’m puzzled too. :sweat_smile:

Not getting enough error messages in module mode is sometimes a problem.
Don’t know why it doesn’t work for you.
No problem in 0.3 (after I created it I saw you probalby use an earlier bge version)

03_npc_modules.blend (818.9 KB)

Ah yeah, i got it when i see your printscreen @musikai

We need to target the controller inside the function itself (and not in the top of the script.

This


import bge

''' declaring on the top works for single used script/module '''
##cont = bge.logic.getCurrentController()    
##own = cont.owner
##own.sensors ....
##own.actuators .... 

def look() :
    cont = bge.logic.getCurrentController()    
    own = cont.owner
    own.sensors ....
    own.actuators ....

@musikai It’s just strange how you don’t have to define your “cont” anywhere

Hmm… the old 2.79 template uses cont as a parmeter to the function ( called main see above) and includes this comment

#  dont call main(bge.logic.getCurrentController()), the py controller will

:sweat_smile: but maybe things have changed ??

And then: it was always not “easy” to get the information one want to know about the API especiallu the architecture/concept used to “work” ( in fact this is also in some other projects not as easy as one whishes… only knowing the functions signature is not enough… :face_with_diagonal_mouth:)

Adding the template for reference:

# This module can be accessed by a python controller with
# its execution method set to 'Module'
# * Set the module string to "gamelogic_module.main" (without quotes)
# * When renaming the script it MUST have a .py extension
# * External text modules are supported as long as they are at
#   the same location as the blendfile or one of its libraries.

import bge

# variables defined here will only be set once when the
# module is first imported. Set object specific vars
# inside the function if you intend to use the module
# with multiple objects.


def main(cont):
    own = cont.owner

    sens = cont.sensors['mySensor']
    actu = cont.actuators['myActuator']

    if sens.positive:
        cont.activate(actu)
    else:
        cont.deactivate(actu)

# dont call main(bge.logic.getCurrentController()), the py controller will

…seing now: @musikai’s example also uses this as parameter…

i didn’t open his file , so didn’t know if he used a main or not.

But anyway, i don’t use a main. So i still need to use

cont = bge.logic.getCurrentController() 

But maybe i should use a main to see if it helps me not having to write it each time

you just have to put it into the function argument:
def look(cont):

oh didn’t see that

so this

import bge

cont = bge.logic.getCurrentController()    

def look(cont) :
    own = cont.owner
    own.sensors....
    own.actuators ....

Btw, is there anything existing that helps us to filter what pulse the module and what doesnt ? I mean , the Controllers can be “Expression” and they condition the pulse to the actuators . But i want to know if one can control upstream the pulses that would trigger the module or not.

Something like (even if i know this is not pythonly correct :stuck_out_tongue:
def look(cont.sensors["pulse"].status == 1) :

Just

import bge
def look(cont) :
    own = cont.owner

2nd part of the question I don’t understand :slight_smile:

It’s not about the name of the function (you have to type it into the brick anyway)… it’s about the parameter… ( but i think you have got it now :wink: )

cont seems to be abbr. for controller and the owner i guess is the object which is associated with/to…

One might “see this” if lookinf tinto the blender (2.79) API bge.types…GameObject docu…