2
\$\begingroup\$

I am back with another question about Goal Oriented AIs.

To explain my problem, I will use a specific example.

In my game, population nodes are spawned on a world map, and important characters called "Migration leaders" can spawn, take in migrants, lead them to a good spot, and then establish a new population node there and finally despawn as they have served their one-time purpose.

What I want to achieve is having only one action called "MoveToTarget" which has no pre-conditions apart from having a target location, and has the effect of setting the fact "Reached target location" to true, which itself is the precondition for other actions. Not sure this is the right way to structure that in the GOAP but that's not exactly my problem, at least I do not think so.

My problem is that, since you can't work with actions that take in an argument, I have little notion of how the AI should determine the location which it will move to when the "MoveToTarget" action triggers, for the following reasons :

  • Depending on the character type and generally what is happening, each character will think differently about where they're interested in going. Furthermore, what happens when I have to interrupt the AI's "plan" for some reason ? The original target location for, say, transporting migrants is lost !

  • I do not which to make different actions like "MoveToMigrationTarget" because then I'll have to make many MANY more actions, like "MoveToCombatTarget" or "MoveToRessources" and I do not think that will work as that will make me have to keep a "Migration target", a "Combat target".. in memory even for characters that have nothing to do with either of those.

So my question exactly is, where is the AI supposed to do the "practical thinking" in a GOAP ? The Actions themselves must be abstract, and can't take in any argument so I have to somehow have target location(s) in memory and have the GOAP planner know which target corresponds to which action.

I could also extend that question to basically any action that need a specific target / object to work.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You should share what program/language you are working in to add more tags so it reaches more people that may help. \$\endgroup\$
    – n_plum
    Commented Feb 8, 2017 at 15:17
  • \$\begingroup\$ Based off your question, and your response to the current answer, may I ask what your rough level of understanding is in regards to programming / c#? We get users of all different variations, and I think it would help (in this case) to know, in order to tailor an understandable answer. \$\endgroup\$
    – Gnemlock
    Commented Feb 8, 2017 at 23:07
  • \$\begingroup\$ Well, I think I know my way. I've been doing programming since I was like 12. I'm currently a student in IT, first year. However this is the first time I'm dabbling with complicated AI stuff, which is why I may seem like I don't really know a lot. So, to answer your question, yes I'd like answers to explain in good detail how and why that solution works. \$\endgroup\$
    – Marc Jacob
    Commented Feb 8, 2017 at 23:21

2 Answers 2

2
\$\begingroup\$

You could have a universal method (public static void MoveToTarget(Transform targetLocation, GameObject objectThatNeedsMoving) {/.../}) that can be reused, regardless of the goal location, as long as you intend for their pattern of movement towards the path to be the same. For instance, you may intend to simply lerp to that location, regardless of character type.

If you need a variety of path patterns, you could inspect the GameObject to determine what kind of object it is, and what pattern you would choose to follow. For instance, perhaps a GameObject has a script called Monster attached to it, so I can see if the passed in Object has a Monster script, and if it is not null, tell it to follow a parabolic curve rather than a straight line. From there, forward the targetLocation and gameObject to your method for moving in that special pattern, perhaps you would have named it MoveToTargetParabolic(Transform targetLocation, GameObject objectThatNeedsMoving) or MoveToTargetMonster(Transform targetLocation, GameObject objectThatNeedsMoving).

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I don't understand, how does that help me find a target ? Where does the code for the AI go in there ? I have no trouble actually moving the characters about, they can do it just fine. My question is more about how and when does the AI find its target location in relation with what it plans to do ? \$\endgroup\$
    – Marc Jacob
    Commented Feb 8, 2017 at 20:10
  • \$\begingroup\$ I've read your question a few times and I don't believe I understand what you are asking then, based on your response. I thought you were asking how to structure your solution to reuse the method to move the migration leaders regardless of their goal so you have a clean solution. Can you revise your question to better articulate your problem? Also, are you writing this AI yourself or are you consuming a third party unity asset? \$\endgroup\$
    – Proto
    Commented Feb 8, 2017 at 22:54
  • \$\begingroup\$ I'll do that then, thanks for taking the time to keep responding :) Yes, I am writing this AI fully by myself. No third party involved. \$\endgroup\$
    – Marc Jacob
    Commented Feb 8, 2017 at 23:10
3
\$\begingroup\$

Generally your problem seems to be focusing on actions more than goals. Your migrant characters have the goal of establishing a new population center, not going to point a. This goal can remain unchanged, even if the target location becomes unavailable, or if a better location becomes available.

Establishing a population center can be broken down into prerequisites: having migrants and being at the location. Since being at the location is a prerequisite for the goal, the character should search for a good location, and then initiate an attempt to move there (this would initiate the moveToTarget action.) When the current action of a character no longer favors their goal, they will stop perusing it (ie: if they arrive at a good location along the way, the prerequisite is met, no need to keep moving). As for if the location becomes unavailable, moveToTarget should fail/become impossible to initiate. The character will have to look for other means to satisfy the "good location" prerequisite.

You can continue breaking down prerequisites into less abstract levels until you get something you can implement. For example a good location could be broken down into having food, water, ect.

The practical thinking occurs by characters selecting the "best" action available, when one action becomes infeasible/impossible, it is no longer a candidate for the best action, and something else must be selected as a means to satisfy the goal prerequisites.

\$\endgroup\$
7
  • \$\begingroup\$ Thank you for your answer, starting to get the idea. I've done some thinking of my own, and I thought I could use a "FindSuitableMigrationTarget" action which has the effect of looking around the character in game for a good spot, and write down the location in a "blackboard", blackboard which would basically be a list of KeyValuePairs<string, object> anyone could "write on". Then the planner would satisfy the pre-requisite of "being there" by planning a move, and said move would use the "written" location upon actual execution by the character'AI. Is this the idea ? Or did I get it wrong ? \$\endgroup\$
    – Marc Jacob
    Commented Feb 9, 2017 at 6:38
  • \$\begingroup\$ @Marc Jacob: Separating the action selection and execution should help, and if you are now able to do that, you got what you need. However, it seems like your suggested approach might result in a large number of "FindSuitable___target" methods as your project grows. You might want to generalize finding a valid map location with a "FindLocation(criteria)" method. The way you describe it the "blackboard"seems to be a global object, which might not be the best way to manage individual character's chosen targets. You know your implementation, there is no right/wrong use of this abstract advice. \$\endgroup\$
    – Will
    Commented Feb 9, 2017 at 21:49
  • \$\begingroup\$ I'm honestly starting to feel stupid. I don't know how I could separate the execution from the selection since AI actions code must be outside any character-related class. Also, I still do not understand how you could have actions that take an argument like the FindLocation(criteria). I'm sorry, I'm really much worse at complex AI than I first thought, must be. Do you have any examples, or books / videos, just anything that could show me a practical example of an implementation ? \$\endgroup\$
    – Marc Jacob
    Commented Feb 10, 2017 at 6:31
  • 1
    \$\begingroup\$ Alright, I'm gonna try to go for the model I've suggested, with the blackboard. Blackboard isn't global, there's one per agent and only its own actions and subsystems will be able to read or write information on it. So, in the case of my "MoveToTarget" problem, basically the "MoveToTarget" action will make the character ("Pawn") move to whatever the "TARGET_DESTINATION" information is set to on the Blackboard. That way I can have actions that set a target for any purpose but that do not worry about movement. Information is stored in a Dictionary<string, object> on the Blackboard. Sounds good ? \$\endgroup\$
    – Marc Jacob
    Commented Feb 10, 2017 at 10:52
  • 1
    \$\begingroup\$ @MarcJacob there are plenty of implementations of GOAP done in C# on github (search) - some are very complex, some are toy implementations, hopefully you can find something useful. I know you have trouble making actions with parameters, but I don't know why that's a problem in your implementation. As per the idea of having actions to find targets, you may need to expand or find more clever ways to use your Knowledge Representation (that's a broad topic), in particular what you describe is that the AI doesn't know the type of target. \$\endgroup\$
    – Theraot
    Commented Feb 13, 2017 at 3:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .