How can I make a controller the active controller?

Okay, I have 32 objects each with an action actuator attached to a controller with the following initialization code, (fired by a run-once always sensor.)

# adds the controller name into a property attached to the piece this should allow 
# me to get the controller and activate any attached actuators
def init_controllers(controller):
    controller.owner["controller"] = controller
    #debug
    print("initialized the controller property for ",controller.owner.name)
    return

On the game board tiles, I have the following code that tries to take control of a selected controllers actuators.

    # testing
    j_key = SensorList["j-key"]
    scene = GameLogic.getCurrentScene()
    knight = scene.objects["Black-Knight-queen"]
    knight_controller = knight["controller"]
    print("looking for j-key")
    if j_key.positive:
        print("okay, I am trying to activate actuator")
        actList = knight_controller.actuators
        jiggleMove = actList["jiggle-move"]
        <b>knight_controller.activate(jiggleMove)</b> # error is here

Everything seems to work until I try to activate the actuator jiggle-move, when I get the following output.

Python script error - object 'e8', controller 'Python':
Traceback (most recent call last):
  File "C:\Documents and Settings\Hope\Desktop\Blender-Chess\chess.py", line 239, in move_piece
    knight_controller.activate(jiggleMove)
<b>SystemError: Cannot add an actuator from a non-active controller</b>

Am I on the correct track here and, if so, how can I activate the objects controller. If not, I would be grateful for a bit of direction.

Irvine

Thanks Monster, you more or less confirmed what I had started to suspect, (after I had posted.) It’s a shame really since it was such an elegant and self contained solution. Using messages and properties seems so messy and artificially contrived.

It is not really messy. It turns messy if you try to apply a different architecture over the existing one.

I think it is important to keep in mind Python runs on top of the BGE (not the BGE on top of Python).
There is an event system already -> the sensors.
Other systems use listeners (or callbacks which is basically the same). If you look a sensor is a listener. It listens for events and transfers the result to the controller which (the secondary event system) activates/deactivates actuators.

The benefit is everything runs synchronous. This removes a lot of headache (e.g. creating event loops). But there are situations when an asynchronous processing would be nice (a really advanced topic).

The BGE’s architecture forces the game developers to keep the logic in small object dependent blocks. What is missing is the inter-object communication to build (independent) groups of objects that they can act as one game object (from logic perspective). This is a sort of “logic encapsulation” which allows an higher level of abstraction.

E.g. you simply link the group “Knight” into your scene from a content file. The knight comes with collision box, armature and skin meshes plus all the necessary logic to act as knight.
Why should this knight allow another object which does not belong to the knight to manipulate its internals?
If you need such things (like passing events) the objects should use a well defined interface e.g. via messages or properties.

The components of the knight on the other hand all belong to the knight. They should be able to directly pass events from one object (of the knight) to another without delay.

I understand what you are saying and it makes perfect sense. My thinking was being driven from the perspective of input to the chess-engine, which sees the entire move as a single “logical object” represented by a string of four characters. As you quite rightly pointed out, from the BGE’s perspective it is actually three distinct “game objects”.

It is sometimes easy to forget that writing code to be used with the BGE is not the same as writing code that exists in isolation.

Hi Irvine

If ya…

import bge
from bge import logic as l

Now you can save variables to the logic, creating globals in essence.

l.varName = 'Hippo'
l.knightIsMoving = True
l.listCosPythonDoesntDoArrays = ['I only found that out last night']

Now you could create a list of object names and actuator names.
If you keep the names of the objects and actuators the same you can pump them through you scene stuff…

l.conObjects = ['Knight', 'Guard', Wizard'] # This would be in your.. def init():

# Then in any other script/module.
actOwner = c.actuators[l.conObjects[0]].owner
actOwner.applyRotation([0, 0, 2], 1) # Remember to tell the actuator what to do.

c.activate(c.actuators[l.conObjects[0]]) # Runs until told to stop as far as I know

I usually run most of my scripts from the camera, co I`ve normally got a camera view screen active somewhere and its easy to click on.

Then just remember to name the object and actuator the same AND connect all the actuators to the camera script.

!! Actually, thinking about it, I`m not sure if the actuators even need to be connected to the relevant scripts if you go through the getCurrentScene()… stuff?

Its possibly not the best way to use Blender. But its easy and feels a little more like coding if ya ask me.

Hope this helps at all.
-Daz.

Running all scripts from camera? I wouldn’t expect game behavior on a camera. I would expect camera/viewer logic at the camera if any.

Imagine you replace your camera. Then all the logic is gone ;).

I suggest to apply tho logic to objects the belong to. If there is none, you can add an empty. An empty does not eat much render power. I is small. And you can place it wherever you want.

If you give it a meaningful name it is very easy to guess what it is doing. This allows it to be reused at other games.

For example:
SelectionManager, SaveLoader, ScenesManager, MouseOrbiter, Synchronizer

Anyway

If the chess engine expects a four character string then this is your interface to the chess engine.
What you need is to translate your game model (the status of your scene) into the required format of the chess engine. You need this conversion as the chess engine can’t deal with you scene (and it is not supposed to deal with it).

Here you see the logic encapsulation again:

  • the chess engine can’t access the internals of your scene
  • your scene can’t access the internals of the chess engine

That makes both components completely independent from each other.

The components communicate via an defined interface with each other. As far as I understood you it is a string of a specific format.
You could even replace them with another component that supports the same interface (the string!). The remaining component would not even recognize there is a change. (This is a very easy way to test game components.)

What you can do is to define one object as “converter” or “interface”. It performs the connection to the chess engine and translates the status of your scene into the required format of the chess engine (and back).

This interface object could communicate via messages or properties with the scene. BTW. I do not think you need real time communication as a chess game is round based.
The chess engine will not care if you immediate place the stones at their positions or if your scene performs heavy animations to entertain the player ;).

I think I wrote earlier at an other thread that you can use an internal model (e.g. a grid [Python]).
If you do that, you can translate from your internal model to the required communication format. This might be easier than to analyze the 3D objects in the scene.
Keep in mind the 3D objects are there to make your game look good and entertain the player. But you could play chess with a simple text editor. This means the logic of the chess game can be quite simple while the logic of the animations are complex.

Hehe, you`ve got me thinking now. :slight_smile: