Using module execution mode to increase CPU performance

EDITED: okay so while I am still looking for help with this, I just realized the MASSIve frame rate drop was due to me having the wrong physics settings accidentally on the big gargoyle dude. woops. (on a side note, is there anyway to have a ‘character’ type physics object not have infinite pushing power against a rigidbody / dynamic with high mass?)

So at thanksgiving my aunt suggested I run my scripts as modules to increase the performance of the CPU while the game is running.

I have all my enemeis scripted, and they look and act great, but they drop my frame rate down to 2 fps, even with them being relatively low poly (about 1000-2000 each, with maybe 10 on screen? I might just have to decimate them into ugly pokey things?)

I haven’t used these before, and I am having a bit of trouble.

I understand that you change ‘Script’ to ‘Module’ in the python controller. Then I understand you type the name of the function, after a dot, after the ‘Module’ name, which is the same as the script name.

The thing is, the script normally was just a script without a main function. When I put it all in a main function so that I would have a function to type in after the module name on the python controller, and did so, I get the error:

‘Cannot add actuator from non active controller’

I am not exactly sure why that is happening.

The script is for an enemy searching. The script works fine, so that’s not the problem, but its there below. All of the enemies have the same general scripts on them, which is why I wanted to change them to 'Module’s I guess… I.E. they all have the same search, pursue, attack, turnaround, general scripts on them with just some parameters changed by unique game properties. Anyway, help solving what elements of these scripts need to be in functions for them to work as modules would be appreciated.

‘Search’ script example:

from bge import logic, renderfrom mathutils import Vector


gd = logic.globalDict
obj = logic.getCurrentScene().objects
cont = logic.getCurrentController()
own = cont.owner


ray = cont.sensors['Ray']
radar = cont.sensors['Radar']
near = cont.sensors['Near']
msgarmature = cont.actuators['MsgArmature']
pursuestate = cont.actuators['PursueState']
turnstate = cont.actuators['TurnState']


updown = Vector([0,0,1])
own.alignAxisToVect(updown,2,1)


rd1 = own['Rotate']
rd2 = own['RDirect2']


if radar.positive:
    ('printradar')
    forward = Vector([rd1,rd2,0])
    print(forward)
    forward.magnitude = own['Speed']
    own.alignAxisToVect(forward,1,1)
    own.applyMovement(forward)
    msgarmature.subject = 'Walk'
    cont.activate(msgarmature)
else:
   cont.activate(turnstate) 
   
                 
if near.positive or ray.positive:
    cont.activate(pursuestate)




        

You never use “obj” so you can delete that. Then everything after that should be inside your “main” function wich actually you shouldn’t name it “main”. Also if you use the first argument to get the controller it will improve the performance a little bit. Anyway I wouldn’t expect the performace to improve a lot anyway.

def main(cont):own = cont.owner

Thank you very much

In general, module mode is faster … but nearly not noticeable.

The bigger benefits are:

  • one file with several (bge callable) separate operations
  • the code/information of the highest abstraction layer can be placed at the top of the file
  • it is a real Python module
  • module level variables

‘Cannot add actuator from non active controller’

Is as it says: you can only activate actuators that are connected to the current controller. --> You can’t activate actuators that are not connected.

at thanksgiving my aunt suggested

Uh, wow. Your aunt knows programming? Lucky you.

Anywa. So the way you use module mode is:

create a function, like:


def search(cont):
    .... stuff goes here ....

Then in the actuator you put modulename.search
Then it will run everything in the function.

The advantage comes in that you can put static things outside the function.

I do not think you will see a sigmificant change with the script you have here. The expensive part is the near sensor, and no matter what you do in the script, that won’t change. I’d suggest changing the near sensor for manually calculating the distance between relevant objects in python - this should be a lot faster.

Yes! Near sensor uses physics. And it means - expensive. Near sensor can’t detect no-collision objects. But sometimes you need to. And getDistanceTo() will always work when you need it. However, it may be that the target object is non-uniform shape and very large. In that case getDistanceTo() wouldn’t always be the best thing. Although in those cases it is rarely seen that people need to detect if that object is close.

Thank you sdfgeoff for suggesting this about the near sensor. I will definitely go and try switching nears out for .getDistanceTo! I was curious about some other things like this today, but I have forgotten specifically what. I guess in general, my question today as I was working on this stuff was, ‘is it faster if i type in the python to, for example, end object instead of the actuator? is it faster if I use python for etc etc,’ I understand now, about the ‘use of physics’ by the sensors. Thank you very much again for the replies!

This actually makes me think of another thing:

So, I have a ‘radar’ sensor that makes sure there is ground to walk on (for the enemies) and if the radar detects no ground, the monster turns around. Is there some way to manually do this with vectors? I am curious if I could have some vector pointing down along the ‘lower surface’ to mimic the radar cone, constantly drawn in front of the monster, checking if there is ground

You can’t use getDistanceTo() for that becouse it doesn’t detect the distance beetwen the two nearest points but the distants beetwen the two object origins. You could use a rayCast but then if you have a tiny hole in the gound the raycast would detect it as no graund but the player would indeed still be touching the ground. If you insist in doing it in python you can use onether object with “ghost and invisible” on the phyciscs properties and use collisionCallbacks to detect the ground. Basically this object will phisically detect the ground but won’t react to it (it should be parented to the enemy/player/whatever). With a simple shape, like a cube, this may be faster that using logic blocks, but I wouldn’t put my hand on the fire for it (not sure if this has the same meaning in english, it’s still a funny expresion tought)

@ elmeunick9 thank you for that reply, I was considering doing that kind of ‘metal detector’ thingy with a cube

I just set up one enemy AI (big stone gargoyle) with .getDistanceTo and it works great, I am about to replace beholder and skeleton lord with it and get rid of their near sensors.

get distance to player.
Is player less than monsters range?
Yes, – > monster chases player
is player less than monsters range divided by some number (or less than another game property )
yes – > go into ‘attack state’