Ai Formula

Hello,

I have been pondering AI, and pathfinding.

I would like to design a system, with more than one function, based on a few properties.

1.Health

2.Last Saw Frame time vs Current Time

3.Damage rate on player VS Damage taken

4.Player Vision cone angle vs Own Vision cone angle

5.Waypoint property name -(used to set up overlapping paths of waypoints)

These properties will be used to switch states from “Walking”, “Idle” , “Hunting”,“Targeting” and “fleeing” and “O crap it’s a grenade!”

Where walking is just using waypoints in sequence and then reverse sequence.

Idle is a random pause where they look around and then potentially play a random action, (talk to self etc)

Hunting is when they have spotted a target but don’t have a view cone aimed at them anymore this state will eventually decay into walking / idle, will use navmesh/A*

“Targeting” is when the AI has it’s vision cone on the player, aims guns and attempts to keep moving while dealing damage. and moving out of players vision cone,

This is a WIP, but also a discussion as I would like everyones opinion on how to keep this lean and mean.


PseudoCode

import bge
from mathutils import Vector

cont = bge.logic.getCurrentController()
own = cont.owner
if own['Target']]!=Empty 
    target=own['Target']
    if own['LastFrameTime'] - ['CurrentFrameTime'] > own['Persistence']

        own.state = 2 (hunting)

    if own['Health']<(.25*own['MaxHealth']

        own.state = 3 (fleeing)

    if own['WeaponRay']=TRUE

        own.state = 4 (targeting)

    if own['DamageRate'] is less than -10
        
         own.state = 3 (fleeing)


PseudoCode

import bge
from mathutils import Vector

cont = bge.logic.getCurrentController()
own = cont.owner
if own['Target']]!=Empty
    target=own['Target']
    if own['LastFrameTime'] - ['CurrentFrameTime'] > own['Persistence']

        own.state = 2 (hunting)

    if own['Health']<(.25*own['MaxHealth']

        own.state = 3 (fleeing)

    if own['WeaponRay']=TRUE

        own.state = 4 (targeting)

    if own['DamageRate'] is less than -10
        
         own.state = 3 (fleeing)

  1. Is not AI, it’s general health management, same as for the player, explody barrels etc. Write a single script you can apply to any object.
  2. Why? What impact will it have on the AI?
  3. Why? What impact will it have on the AI?
  4. Why? What impact will it have on the AI?
  5. Use the navmesh.

And your pseudo code is odly like python for pseudo code. I see maybe four things that aren’t syntactically correct. Trying to execute it, and looking at the errors will tell you where these errors are, and how to fix them.
***General thoughts on AI

If’s and then’s are bad. They break up the AI into something that is easily identifiable by the player. A skilled player can say “He’s fleeing, He’ll flee for 15 seconds, turn around and then look back the way he came. So I’ll zip around behind him so when he turns, I can hit him in the back” Or whatever.
Also, people don’t think in if’s and then’s. Our chosen paths are far more variable. If we tried to impliment a finite state machine to represent all the states of a human, it would be a zillion states.

So instead of states we can use weightings and a little randomness.
So let’s look at sight. How can we tell if our AI has ‘seen’ our player?
More accurate than your ‘Lidar’ (and about the same speed), and much much faster than the radar or near sensors, is the specific casting of a ray directly at the player. So let’s write a function to represent sight:


def sight(player_obj, AI_obj)
    hit = AI_obj.rayCastTo(player_obj, 40)
    if hit is not player:
        return 0 #Because the player is behind a wall
    angle = AI_obj.getVectTo(player_obj).dot(AI_obj.getAxisVect([0,1,0])) #Compare the way the direction is to the direction the AI is facing
    distance = AI_obj.getDistanceTo(player_obj)

    sight_value = 1/(angle*distance) #The smaller the angle, and the closer the player, the higher the sight_value
    return sight_value

So now instead of a simple ‘can I see the player’ we have ‘how well can I see the player’
Let’s say we write a whole bunch of other functions to represent other senses, smell, audio etc. How can we combine them? We want even a single ‘large value’, so we just add them together

function alertness(player_obj, AI_obj):
    sight_value = sight(player_obj, AI_obj)
    aural_value = aural(player_obj, AI_obj)
    scent_value = scent(player_obj, AI_obj)
    
    #Combine these values
    alertness_value = (sight_value+aural_value+scent_value)
    return alertness_value

And now we have to use this to evalute what the player does, so we can feed it into various other functions:


function AI(cont):
    AI_obj = cont.owner
    player_obj = [o for o in bge.logic.getCurrentScene().objects if 'player' in o][0]
    nav_act = cont.actuators['navigation']

    alertness_value = alertness(player_obj, AI_obj)
    
    nav_act.velocity = sqrt(alertness_value)*0.5
    if alertness_value > 10:
        cont.activate(nav_act)
    ....
    ..

And so on. I could spout on for days, but won’t because I have other stuff to do.

Hope some of that helped.

The damage rate = if damage rate is high enough, disregard own safety, if damage rate is negative and a certain magnitude, flee the scene!

What would be nice would be if the enemies would help a damaged enemy by attacking the player.Come to the rescue of their fellow enemy.I think that is what he means.You need to develop your ai behaviours.