Announcement

Collapse
No announcement yet.

Goal Oriented Action Planning AI Framework

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [PLUGIN] Goal Oriented Action Planning AI Framework

    I started a project a little while back to have a go at building a GOAP framework. For a bit of background :

    From Jeff Orkin : http://alumni.media.mit.edu/~jorkin/goap.html

    Goal-Oriented Action Planning (aka GOAP, rhymes with soap) refers to a simplfied STRIPS-like planning architecture specifically designed for real-time control of autonomous character behavior in games. I originally implemented GOAP for F.E.A.R. while working at Monolith Productions. This A.I. architecture simultaneously powered Monolith's Condemned: Criminal Origins. (Brian Legge was responsible for the A.I. in Condemned). My GOAP implementation was inspired by conversations within the A.I. Interface Standards Committee's (AIISC) GOAP Working Group, as well as ideas from the Synthetic Characters Group's C4 agent architecture at the MIT Media Lab, and Nils Nilsson's description of STRIPS planning in his AI book.
    I've been devblogging the process, and am pretty close to getting the basic framework in place, just need to write the planner. Devblog is here:

    http://cashworth.net/code/unrealengine/goap

    UPDATE:

    Master is now on 4.15.0

    https://github.com/midgen/GOAPer

    4.14.3:

    https://github.com/midgen/GOAPer/tree/4.14
    Last edited by mid_gen; 03-14-2017, 05:20 AM.

    #2
    I recall F.E.A.R. had pretty convincing AI. Should be awesome!

    Will it be released as plugin for stock UE4 with full (or enough to work on AI without touching C++) exposure to Blueprints ?

    Thanks

    Comment


      #3
      As it currently stands, the AI Agent configuration is all done in blueprints, but all the state/action/goal code is non-UObject, so you need to get into the C++. So a C++ coder creates a library of Goals, States and Actions, and the designer just assigns a variety of these to a character blueprint and the framework takes care of the rest.

      There's only really two bits of code you need. 1) Each state needs to implement an 'Evalute' method that evaluates itself against the world or agent. 2) Each action needs to implement an Execute method that deals with actually performing actions in the world, running animations etc. The framework takes care of the rest.

      Ultimately I do want it to be completely extensible via blueprints....but that's a challenge I will get to a bit further down the line.

      During testing at the moment, instead of having AI's running around murdering each other, I've made them farm and gather food I'll probably start building out an FPS package with the usual attack, hide, patrol, type behaviours once the framework is finished.
      Last edited by mid_gen; 06-08-2016, 10:47 AM.

      Comment


        #4
        I am totally not a C++ programmer

        It would be nice to have bundled basic goals/states/actions so that folks like me could create something tangible and perhaps eventually build upon it (or someone could be hired to build upon it in C++).

        Good luck with the project! Hopefully it will make it to the Marketplace eventually!

        Comment


          #5
          Very interesting! I recall STALKER used this as well, and it had some very unpredictable AI.

          I've only used behavior trees, behavior stacks and state machines so I'm keen to cut my teeth on this

          I wish you luck.

          Comment


            #6


            Nearly there with the framework, just need to write the real planning algorithm.

            Comment


              #7
              Awesome work mid_gen, GOAP is probably my favorite AI framework, awesome to see it come to UE4.
              Storyteller - An immersive VR audiobook player

              Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

              Comment


                #8
                [MENTION=5136]mid_gen[/MENTION] - any progress on this? I'm curious to get my hands on a GOAP planner in UE4 for generating quests.
                Storyteller - An immersive VR audiobook player

                Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                Comment


                  #9
                  Originally posted by n00854180t View Post
                  @<a href="https://forums.unrealengine.com/member.php?u=5136" target="_blank">mid_gen</a> - any progress on this? I'm curious to get my hands on a GOAP planner in UE4 for generating quests.
                  Been busy recently, and my internet has been playing up

                  I've pushed a branch with the basic working implementation. It has a FSM with Idle/MoveTo/DoAction states and a very simple depth-first planning algorithm which just takes the first valid path here :

                  https://github.com/midgen/GOAPer/blo...OAPPlanner.cpp

                  It's very crude and not in the slightest bit optimised, about as slow as it can be, but it works.

                  I've kinda paused now because to start optimising it I need a decent suite of actions/states, so I'm scribbling down game ideas to build up around it. I might just do the usual first person shooter type setup to keep things simple.



                  I just have one goal 'Be Nourished' (keep health above 99), two actions - Gather Food, and Eat.
                  Last edited by mid_gen; 08-02-2016, 02:55 AM.

                  Comment


                    #10
                    [MENTION=5136]mid_gen[/MENTION] - So I was looking at implementing GOAP from scratch just for the experience, and was wondering about some implementation details in your version.

                    Namely, I was thinking of setting it up so that PerformAction is a BT_Task node that lets you reference an action object, and then using the BT for the FSM, e.g., set up Idle and Move states in the BT, with PerformAction being another BT_Task node.

                    Another thing is that it seems from your devblog that you're doing your own pathfind, curious why do that instead of hook into the normal pathfind.

                    Edit: This paper is topical to extending BTs with planning systems: http://projekter.aau.dk/projekter/fi...hesisFinal.pdf

                    Edit again: The above paper actually implements planning as an extension of the BT using a similar method to the one I propose above. The part of the paper in question is "4.3 Implementation" where it mentions the "Planning Node".
                    Last edited by n00854180t; 09-20-2016, 06:46 PM.
                    Storyteller - An immersive VR audiobook player

                    Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                    Comment


                      #11
                      Originally posted by n00854180t View Post
                      Namely, I was thinking of setting it up so that PerformAction is a BT_Task node that lets you reference an action object, and then using the BT for the FSM, e.g., set up Idle and Move states in the BT, with PerformAction being another BT_Task node.
                      I've never looked into the BT implementation in UE, if it's possible to re-use an Action class from there I should take a look into it! Thanks.

                      Originally posted by n00854180t View Post
                      Another thing is that it seems from your devblog that you're doing your own pathfind, curious why do that instead of hook into the normal pathfind.
                      The planner is just a pathfinding algorithm, except instead of finding a path through a navmesh, you're finding a path through world states.....so in the devblogs when I'm talking about pathfinding, I'm talking about the planner I use the standard AIController stuff for moving the AI Agent. The current pathfinding algorithm in the planner is just a simple depth-first. You can use whatever method you want, A* etc.

                      Edit: This paper is topical to extending BTs with planning systems: http://projekter.aau.dk/projekter/fi...hesisFinal.pdf

                      Edit again: The above paper actually implements planning as an extension of the BT using a similar method to the one I propose above. The part of the paper in question is "4.3 Implementation" where it mentions the "Planning Node".[/QUOTE]

                      Thanks, I'll have a read....

                      Comment


                        #12
                        I love you so much for this. I was looking at implementing this into UE4 for a personal project of mine as well. Have you looked the planning queue at all? I know the reason why FEAR had so few AI on screen at a time was because of how hard they were hitting their planner, once every couple of seconds or so. They also had to culling of their GOAP actors as well, so the Rats at the beginning of the first level were still planning even if the player was in another part of the level. Why I mentioned this was that because the more actions the AI could put into their plan queue the faster the system ran with more AI at the same time.


                        Thanks for doing a lot of legwork here, I will definitely keep an eye on it!

                        Comment


                          #13
                          Originally posted by mid_gen View Post
                          I've never looked into the BT implementation in UE, if it's possible to re-use an Action class from there I should take a look into it! Thanks.



                          The planner is just a pathfinding algorithm, except instead of finding a path through a navmesh, you're finding a path through world states.....so in the devblogs when I'm talking about pathfinding, I'm talking about the planner
                          Suspected as much but wasn't sure hah. Makes sense
                          Storyteller - An immersive VR audiobook player

                          Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                          Comment


                            #14
                            [MENTION=5136]mid_gen[/MENTION] - Trying to compile the project from Github, I get these errors:

                            Code:
                            > Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(548): error C2440: 'initializing': cannot convert from 'GOAPState *const ' to 'GOAPAtom *'
                            
                            >   Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(548): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
                            >   D:\ChromeDL\userimages\GOAPer-master\GOAPer-master\Source\GOAPer\Private\GOAPAction\CreateFoodAction.cpp(15): note: see reference to function template instantiation 'TSharedPtr<GOAPAtom,0>::TSharedPtr<GOAPState>(const SharedPointerInternals::FRawPtrProxy<GOAPState> &)' being compiled
                            
                            >   D:\ChromeDL\userimages\GOAPer-master\GOAPer-master\Source\GOAPer\Private\GOAPAction\CreateFoodAction.cpp(15): note: see reference to function template instantiation 'TSharedPtr<GOAPAtom,0>::TSharedPtr<GOAPState>(const SharedPointerInternals::FRawPtrProxy<GOAPState> &)' being compiled
                            
                            > Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(548): error C2439: 'TSharedPtr<GOAPAtom,0>::Object': member could not be initialized
                            >   Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(822): note: see declaration of 'TSharedPtr<GOAPAtom,0>::Object'
                            Any ideas? Was there something committed only part way?

                            It's hard to tell whether the Preconditions in GOAPAction class should be GOAPState, or if the IsFoodAvailable (etc) calls should be changed to return a GOAPAtom instead.

                            Edit: This ended up compiling though I don't know if it's right:

                            Code:
                            	IsFoodAvailableState* foodStateFalse = new IsFoodAvailableState(false);
                            	IsFoodAvailableState* foodStateTrue = new IsFoodAvailableState(true);
                            	// Only perform if there's no food
                            	PreConditions.Add(MakeShareable<GOAPAtom>(&foodStateFalse->Atom));
                            
                            	// Make food!
                            	Effects.Add(MakeShareable<GOAPAtom>(&foodStateTrue->Atom));
                            Edit again: Launching the project after successfully compiling, it gives a warning about missing a cursor asset and missing the TopDownCharacter asset.

                            Edit again again: Seems like nutrition value never decrements for some reason by default.

                            Edit final: Added a navigation mesh, a couple of GOAP actors and some food, but they don't seem to move or do anything. Any ideas?

                            Edit final again: Got it to do something, but the bots still don't move to the food.

                            I can see it changing to DoAction -> GatherFood, but it never moves.
                            Last edited by n00854180t; 09-23-2016, 07:51 PM.
                            Storyteller - An immersive VR audiobook player

                            Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                            Comment


                              #15
                              So I'm back actively developing this again now after finishing up work on my terrain generator.

                              I've made a fair few changes:
                              • Moved framework code into plugin (GOAPer)
                              • Removed GOAPState class, framework is now not concerned with evaluating state
                              • Game module implementation of AGOAPAIController is now responsible for updating state
                              • Slowly building out example project, just added AIPerception into the controller implementation.


                              The repo is now private as I have non-shareable assets in there (AnimationStarterPack). I'm also considering putting the plugin on the marketplace at some point once it's finished.

                              I'll open up the repo to some testers in future to get some feedback. In the meantime, I'm still updating the devblog :

                              http://cashworth.net/code/unrealengi...-ue4-devblog-9

                              Comment

                              Working...
                              X