8
\$\begingroup\$

I'm a little bit stuck:

I implemented an AI with GOAP (Goal oriented Action Planning, http://alumni.media.mit.edu/~jorkin/gdc2006_orkin_jeff_fear.pdf) for a simulation game. That works fine.

Now I want that the agents can cooperate (e.g. doing actions together). What is in this case the best AI-Design that the GoapActions keep loose couplet?

Should they plan together? (what is in this case the "worldstate"?)Or Should they share their plans? some kind of message-system?

Example
Agent1: Worldstate Agent 1: isLonely= true
Goal Agent1: isLonely = false

Plan Agent1: AskAgent2ToTalk -> TalkToAgent2

Agent2 Worldstate Agent 2: hasWood = false
Goal hasWood = true

Plan Agent2: GetAxe -> ChopWood -> BringWoodToSupply

How I get this constellation?

Agent1 Plan: TalkToAgent2
Agent2 Plan: TalkToAgent1 -> GetAxe -> ChopWood -> BringWoodToSupply

Or if they are talking and one of the agents is interrupted (e.g. by an attacking enemy) the other agent must know that his TalktoAgent2 Action has ended.

\$\endgroup\$
1
\$\begingroup\$

I highly recommend you do not use aciton planning. It's very difficult to extend, design, and bugfix. We abandoned task planning very early on in DwarfCorp because it's too complex to quickly design new behaviors around. But if you must, you have to interpret this as a multi-agent planning problem.

One way to achieve this is through Heirarchical Planning. You need to create a meta-agent for assigning subproblems to your lower level agents. The meta agent, or "Task Planner" tries to achieve an overall goal, and uses the sub-agents under its control as meta-actions.

For example, your meta-agent might have a goal "Build a house". It has the action "gather wood" which takes as input an agent and a location to gather the wood at. It can then assign different agents to different subtasks. Maybe one agent goes and gathers the wood while the other uses the gathered wood to build the house.

It may have other goals, like "reduce loneliness". Those goals need to be ordered by priority so that they can subsume each other. The central task planner decides at any given time what the most important goals are, and assigns agents to them using different subgoals. It looks for idle agents, figures out what the best subtask is to assign to the agent, and then puts them on the case.

\$\endgroup\$
  • \$\begingroup\$ What for a planing System are you using in dwarfCrop? The hierarchical planning system has an issue: how do you mddel the 'free will' of an agent? the agent should not always doing that what the 'meta agent' asking for. \$\endgroup\$ – james Jan 7 at 10:24
  • 1
    \$\begingroup\$ So the meta agent says "These are the tasks I want you to do." The agent also has a set of preferences like "I'm bored" or "I'm hungry". These get put onto a priority queue. Sometimes the meta agent's priorities override the agent's priorities, other times the agent overrides the meta agent. \$\endgroup\$ – mklingen Jan 9 at 15:08
0
\$\begingroup\$

I think goap is new version of state machines that tries to setup states to achieve a goal. you just have to define which scenarios are happening in every state.

for example you have some AI enemies that have patrol, chase, search and attack states.you can simply write a code that when one of enemies found player, all off change state to attack or chase state. other example you have scenario that in attack state, one or 2 of enemies have to flank player and other have to support them. so every enemy checks if there is an enemy flanking or some other condition(you can just define a bool variable for that). if there isn't, go flank else go support. all depends on scenarios and rules you define.

\$\endgroup\$
  • \$\begingroup\$ But imagine the following situation: agent1 like to talk with agent2, agent2 are collecting some wood In this case agent2 must know, that agent1 like to talk with agent1 and agent1 must know if agent2 is talking back or just ignoring him. how i achieve this? \$\endgroup\$ – james Aug 19 '17 at 9:28
  • \$\begingroup\$ I added an example \$\endgroup\$ – james Aug 19 '17 at 10:12
0
\$\begingroup\$

I don't know if you try to achieve a coupling loose between agents, since that was what I interpreted, anyhow, that would be the best approach, you should check for the Observer Pattern, which is an event subscription system that avoids dependencies. You could use it like this way (I'll try to be language agnostic):

public interface ILonelyObserver
{
    void ItsLonely();
}

public class Agent implements ILonelyObserver
{
    private static List<ILonelyObserver> observers;
    private bool busy;

    public static void IAmLonely()
    {
        for(int i = 0; i < observers.Count; i++)
        {
            observers.ItsLonely();
        }
    }

    public static void Subscribe()
    {
        if(observers == null) observers = new List<IObserver>();
        observers.Add(this);
    }

    public static void Unsubscribe()
    {
        if(observers != null) observers.Remove(this);
    }

    public void ItsLonely()
    {
        /// Do what it takes to make company...
    }

    public Agent()
    {
        Subscribe();
    }

    ~Agent()
    {
        Unsubscribe();
    }
}

So it would be up to you to make the logic to subscribe/unsubscribe when the agent is busy and cannot make company.

If you were to use C#, you should check Event Delegates, which already implements the aforementioned pattern.

Hope it gives you an idea at least.

\$\endgroup\$
0
\$\begingroup\$

You would have to A: use step and assess and B: you have to have multiple goals with priorities.

If Agent1 wants X and Agent2 never wants X, they can't work together. That can't happen in any system. To fix this, you will need to have multiple goals tracked. You can even prioritize goals based on how far one has progressed towards them and how easily other goals can be accomplished. In your scenario with out priorities, this becomes:

Agent1: Worldstate Agent 1: isLonely= true Goal: isLonely = false

Plan Agent1: AskAgent2ToTalk -> TalkToAgent2

Agent2 Worldstate Agent 2: hasWood = false, isLonely= true

Goal: hasWood = true

Goal: isLonely = false

Plan Agent2: GetAxe -> ChopWood -> BringWoodToSupply, AskAgent1ToTalk -> TalkToAgent1

Agent1 then would continually ask Agent2 to talk until it got an affirmative, which would happen after it completed its first task.

Taking steps towards each goal will have to be evaluated, and while with only one goal this isn't a big deal, more goals could potentially slow down your game.

To solve this issue you need trees generated from accomplishing tasks which may hide checking multiple goals at a time, speeding up processing of decisions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.