AI Enemies Moving to Last Known Player Location

I’ve been working on creating some basic AI that will follow the player when they see him and go to his last known location when they lose sight of him. However, I am running into the problem that when one of the AI loses sight, all the enemy AI go to that last location.

I understand there are manual ways to fix this problem, but I am looking for a more modular approach so that I could just import an enemy instance into my game and duplicate him as needed without having to edit each enemy AI.

I can’t attach my .blend due to the size of the file, but here is the AI code: http://www.pasteall.org/55360. I implemented my script thinking that each object would run its own version of the script (each would create its own track to last known location position) but the script seems to run collectively for all the objects that use it.

Does anyone have any modular approaches to this AI issue?
(If I need to elaborate more or try to create a smaller .blend to show the problem just ask)

Can you give more details on the game logic that runs this python code ?

The setup is: a ray sensor that sends a positive signal if there is a ray to the player and one ray sensor that sends a positive if there is no ray to the player. Both run into the python code brick. Then out of the python code brick 2 steering actuators connect. One actuator is to the player and one is to the last known location of the player.

one moment.

Ok


Attachments

LastGood.blend (462 KB)

Analysis
Your description sounds like the instances share their knowledge. You need to make sure each instance has it’s own memory.

Typically this is not a problem of the logic bricks as this is object dependent already. So it is - most-likely - a problem of the Python code.

Lets look at it:


import bge
 
scene = bge.logic.getCurrentScene()
track = scene.addObject(scene.objectsInactive["Player_lastKnownLoc"],scene.objects["Player"],0)
print("Track Created")
 
def toLastKnownLoc(cont):
   ...

it seams that you use module mode. This is fine … but you cache the last known position (track) at the module.

The possible issue
As all instances use the same module … they all use the same “track” object.

A possible solution
I suggest you change the design. Make sure each instance comes with it’s own track object. You do not even need to created it on the fly, you can place it in the same group and make sure the character knows about it. But this is something that does not really matter. The important thing is, that each instance has an own track object and knows how to get it.


import bge

def toLastKnownLoc(cont):
    ...
    player = scene.objects["Player"]
    lastLoc = getTrack()
    ...

def getTrack():
   # however you find the object for your instance
   # e.g.
   owner = bge.logic.getCurrentController().owner
   return owner["track object"]

you also need to place “track” at the last know position when the character lost the player.

A suggested solution
in general I would design the code this way:


def determineTrack():
    if canSeePlayer():
        trackPlayerLocation()

def moveToTrack():
    track = getTrack()
    if near(track):
        targetReached()
    else:
        turnTo(track)
        moveTo(track)

This separates the operation to determine where to go and how to go. How you implement each single step is up to you. You can even delegate it to a logic brick (e.g. turnTo, moveTo). You can use information from logic bricks (e.g. canSeePlayer() can use information from a ray sensor)

I hope it helps