Search Unity

Simpler AI solution than action planning

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Jun 12, 2018.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    I'm working on a spy game, so I want entire networks of NPC spies to operate like interconnected clockwork: agents will retrieve messages with orders, carry out an operation to steal blueprints/secrets/equipment, and stash those in dead drops for other agents to retrieve. I've already built a node graph that represents the world in data, and initially I thought I would run the entire NPC network with an action planner where every possible action was represented as a set of preconditions("hasDeadDropLocation") and effects ("itemDelivered"), and the system simply runs an A* search across a character's entire library of actions to figure out the cheapest and fastest series of actions that will accomplish their objective.

    This technically works, but it's really complicated. I need tons of variations on basic verbs to account for skills (e.g. lockpicking and breaking & entering both get you into a location, but the former requires the NPC to have a specific skill as a precondition), and representing the world context (e.g. the state of every door/window/item/character who might be useful to the NPC) means building an absolutely huge hashset to traverse.

    In my experience "really complicated" usually means that you're doing AI wrong, since you're aiming for something that feels realistic but is relatively simple under the hood. So am I barking up the wrong tree trying to make action planning work here? I'd considered something like fuzzy logic/literal RNG, where each NPC just rolls a dice to decide what action they take each turn, but since the whole point of the game is giving the player a logical, understandable network to pick apart and mess around in, it feels like there needs to be a coherent, well-organized logic driving the characters.
     
  2. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    I think that something like a network of spies is always going to be somewhat complicated. Most of the "simple under the hood" systems I've seen are for more instinctive / non-directed things where the actions don't have to make sense individually, just look good in aggregate.

    To deal with the huge amount of context, one approach would be multiple layers of planning.
    So for example, at the top level, you have "Steal the submarine plans from U.N.C.L.E." which generates the step "Infiltrate an U.N.C.L.E. research base", only knowing that the organization has research bases.
    The next layer knows what specific research bases there are and picks one.
    The next layer, where it's choosing between lockpicking and B&E, only needs to consider the state for that single building.

    This could lead to slightly suboptimal courses of action, since the layer that's choosing the target wouldn't know that building #37 has a broken camera in the parking garage. But that seems more accurate to reality - no organization has perfect communication and intel.
     
  3. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    That's a really good idea and one I hadn't considered, thank you for the suggestion!

    Assuming I stick with the action planner, one of the other challenges I've had is structuring the goal condition- taking your example of stealing submarine plans, the way my system would handle that right now is by creating some unique PlotItem named "Submarine Plans", populating it with all the descriptive niceties, then planting it at a random U.N.C.L.E. facility where it could be stolen. To actually instruct one of my spies to go for it, I give them a TakeItem action with the effect "HasItem[item name]", and create a goal whose sole precondition is "HasItemSubmarinePlans", and whose effect is "CompleteMission".

    That works, but the drawback is that the HasItem condition requires me to give every agent a list of conditions including one instance of "HasItem[item]" for everything in their inventory. This immediately bloats the searchable space like crazy, especially since I have to do this for every NPC (since anyone could be carrying the desired item/weapon/money/cipher/whatever). This seems like the obvious approach, however, since the entire point of a well-designed action planner is that you can express any combination of actions by pathfinding through a series of <string, object> hashsets.