Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

B.R.A.I.N.S: Behavior Tree AI Plugin powered by Kismet

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

    #16
    that cycling image isnt very helpful. Its distracting and cycles too quickly to make any sense of. Any chance you could change it to static ones?

    Comment


      #17
      Originally posted by GeekyPayback View Post
      that cycling image isnt very helpful. Its distracting and cycles too quickly to make any sense of. Any chance you could change it to static ones?
      Hint: Save (download) the image and load it into GIMP. Then go to the layers section and use visibility to switch between layers.

      Comment


        #18
        This looks like great idea. I am releasing custom GUI framework with dozens of nodes this month. It will allow people to make whole high quality UI using just unreal editor and kismet. I really like this kind of projects. I did many tests in kismet because these things are not very well documented. Here are some suggestions:

        I'm open to suggestions on using custom shapes and sprites for Kismet Nodes (circles, squares, diamond, etc).
        Changing this is very easy however we don't have access to it because It is in native code. Atleast we can change color of border. That's what I did. I typed down some unused colors in kismet and used them for my custom nodes.
        ___________________________________
        - I also wanted to use custom variables in my framework. It works great however there is one bad thing about them. Value inside bubble is set in native code using function which you can see in Cpp block of SequenceVariable.uc
        virtual FString GetValueStr()
        {
        return FString(TEXT("Undefined"));
        }
        So ALL custom variables extended from SequenceVariables shows "Undefined" in bubble. It will be pretty chaotic when you will use many variables in kismet and all will display value as "Undefined".

        - I also found out one nice trick. If you specify sprite with name Sprite in default properties of some actor it will use this sprite as background of kismet variable. You can see that when you work with object variable which refers to trigger. Sadly, this does not work with classes that extend Object directly.

        - Latent actions have some annoing native code. They are hard-wrapped to outputs, so I needed to do some hacks to disable calls from native code.

        btw.
        One strange foreach+kismet bug: http://forums.epicgames.com/threads/...ht=foreach+bug

        Comment


          #19
          Originally posted by Skylonxe View Post
          This looks like great idea. I am releasing custom GUI framework with dozens of nodes this month. It will allow people to make whole high quality UI using just unreal editor and kismet. I really like this kind of projects. I did many tests in kismet because these things are not very well documented. Here are some suggestions:


          Changing this is very easy however we don't have access to it because It is in native code. Atleast we can change color of border. That's what I did. I typed down some unused colors in kismet and used them for my custom nodes.
          ___________________________________
          - I also wanted to use custom variables in my framework. It works great however there is one bad thing about them. Value inside bubble is set in native code using function which you can see in Cpp block of SequenceVariable.uc

          So ALL custom variables extended from SequenceVariables shows "Undefined" in bubble. It will be pretty chaotic when you will use many variables in kismet and all will display value as "Undefined".

          - I also found out one nice trick. If you specify sprite with name Sprite in default properties of some actor it will use this sprite as background of kismet variable. You can see that when you work with object variable which refers to trigger. Sadly, this does not work with classes that extend Object directly.

          - Latent actions have some annoing native code. They are hard-wrapped to outputs, so I needed to do some hacks to disable calls from native code.

          btw.
          One strange foreach+kismet bug: http://forums.epicgames.com/threads/...ht=foreach+bug
          Hi Skylonxe,

          Sincere Thanks for your reply and insight. Using ObjCategory, ObjName, ObjColor defaultproperties provided an acceptable level customization, although I would like use some Sprites and different shapes:triangles and rects w/ round corners. I found a workarounds for a few handicaps for classes extended from Object. One of these handicaps is the use of States, which I use to manage latency for each Task node independently. Can you elaborate on: "Latent actions have some annoing native code. They are hard-wrapped to outputs, so I needed to do some hacks to disable calls from native code."?

          Comment


            #20
            Brains at Work!

            [SHOT]https://arcadekomodo.com/home/wp-content/uploads/2014/03/brainsbehaviortreeinkismet41.png[/SHOT] Debug Log
            Code:
            [0135.52] Activating SequenceNode_1
            [0135.52] Adding to Valid ChildNode[0]: ParallelNode_1
            [0135.52] Adding to Valid ChildNode[1]: DecoratorNode_1
            [0135.52] Activated SequenceNode_1
            [0135.52] SequenceNode_1 Inactive State
            [0135.52] SequenceNode_1 Start State
            [0135.52] funct() NodeSelectionBehaviorSequence
            [0135.52] SequenceNode_1 CurrentValidOutputLinkIdx=0 OutputLinkIterator=0 bAllChildNodesActivated=False
            [0135.52] Activate ChildNode[0]: ParallelNode_1
            [0135.52] SequenceNode_1 Running State
            [0135.60] Activating ParallelNode_1
            [0135.60] Adding to Valid ChildNode[0]: ConditionNode_1
            [0135.60] Adding to Valid ChildNode[1]: ActionNode_2
            [0135.60] Adding to Valid ChildNode[2]: ActionNode_0
            [0135.60] Activated ParallelNode_1
            [0135.60] SequenceNode_1 Checking
            [0135.60] funct() NodeCheckBehaviorSequence
            [0135.60] Checking ChildNode[0]: ParallelNode_1
            [0135.60] ParallelNode_1 Inactive State
            [0135.60] ParallelNode_1 Start State
            [0135.60] funct() NodeSelectionBehaviorParallel
            [0135.60] Activate ChildNode[0]: ConditionNode_1
            [0135.60] Activate ChildNode[1]: ActionNode_2
            [0135.60] Activate ChildNode[2]: ActionNode_0
            [0135.60] ParallelNode_1 CurrentValidOutputLinkIdx=2 OutputLinkIterator=0 bAllChildNodesActivated=True
            [0135.60] ParallelNode_1 Running State
            [0135.62] Activating ConditionNode_1
            [0135.62] Activated ConditionNode_1
            [0135.62] Activating ActionNode_2
            [0135.62] Activated ActionNode_2
            [0135.62] Activating ActionNode_0
            [0135.62] Activated ActionNode_0
            [0135.62] SequenceNode_1 Checking
            [0135.62] funct() NodeCheckBehaviorSequence
            [0135.62] Checking ChildNode[0]: ParallelNode_1
            [0135.62] ParallelNode_1 Checking
            [0135.62] funct() NodeCheckBehaviorParallel
            [0135.62] Checking ChildNode[0]: ConditionNode_1
            [0135.62] All ChildNodes are NOT is Finished. Exiting...
            [0135.62] ConditionNode_1 Inactive State
            [0135.62] ConditionNode_1 Start State
            [0135.62] funct() NodeSelectionBehaviorNone
            [0135.62] ConditionNode_1 Running State
            [0135.62] ActionNode_2 Inactive State
            [0135.62] ActionNode_2 Start State
            [0135.62] funct() NodeSelectionBehaviorNone
            [0135.62] ActionNode_2 Running State
            [0135.62] ActionNode_0 Inactive State
            [0135.62] ActionNode_0 Start State
            [0135.62] funct() NodeSelectionBehaviorNone
            [0135.62] ActionNode_0 Running State
            [0135.69] SequenceNode_1 Checking
            [0135.69] funct() NodeCheckBehaviorSequence
            [0135.69] Checking ChildNode[0]: ParallelNode_1
            [0135.69] ParallelNode_1 Checking
            [0135.69] funct() NodeCheckBehaviorParallel
            [0135.69] Checking ChildNode[0]: ConditionNode_1
            [0135.69] All ChildNodes are NOT is Finished. Exiting...
            [0135.69] ConditionNode_1 Checking
            [0135.69] funct() NodeCheckBehaviorNone
            [0135.69] Bail = SUCCESS
            [0135.69] ConditionNode_1 Results are in. Change to Finish.
            [0135.69] ConditionNode_1 Finish State
            [0135.69] ActionNode_2 Checking
            [0135.69] funct() NodeCheckBehaviorNone
            [0135.69] Bail = SUCCESS
            [0135.69] ActionNode_2 Results are in. Change to Finish.
            [0135.69] ActionNode_2 Finish State
            [0135.69] ActionNode_0 Checking
            [0135.69] funct() NodeCheckBehaviorNone
            [0135.69] Bail = SUCCESS
            [0135.69] ActionNode_0 Results are in. Change to Finish.
            [0135.69] ActionNode_0 Finish State
            [0135.73] SequenceNode_1 Checking
            [0135.73] funct() NodeCheckBehaviorSequence
            [0135.73] Checking ChildNode[0]: ParallelNode_1
            [0135.73] ParallelNode_1 Checking
            [0135.73] funct() NodeCheckBehaviorParallel
            [0135.73] Checking ChildNode[0]: ConditionNode_1
            [0135.73] ChildNode[0] Finished
            [0135.73] Checking ChildNode[1]: ActionNode_2
            [0135.73] ChildNode[1] Finished
            [0135.73] Checking ChildNode[2]: ActionNode_0
            [0135.73] ChildNode[2] Finished
            [0135.73] All ChildNodes Finished!
            [0135.73] Bail = 1
            [0135.73] ParallelNode_1 Results are in. Change to Finish.
            [0135.73] ParallelNode_1 Finish State
            [0135.76] SequenceNode_1 Checking
            [0135.76] funct() NodeCheckBehaviorSequence
            [0135.76] Checking ChildNode[0]: ParallelNode_1
            [0135.76] ChildNode[0] Finished!
            [0135.76] ChildNode[0] Result = SUCCESS, Proceed to Next ChildNode.
            [0135.76] funct() NodeSelectionBehaviorSequence
            [0135.76] SequenceNode_1 CurrentValidOutputLinkIdx=0 OutputLinkIterator=1 bAllChildNodesActivated=False
            [0135.76] Activate ChildNode[1]: DecoratorNode_1
            [0135.76] SequenceNode_1 CurrentValidOutputLinkIdx=1 OutputLinkIterator=2 bAllChildNodesActivated=True
            [0135.80] Activating DecoratorNode_1
            [0135.80] Adding to Valid ChildNode[0]: SelectorNode_1
            [0135.81] Activated DecoratorNode_1
            [0135.81] SequenceNode_1 Checking
            [0135.81] funct() NodeCheckBehaviorSequence
            [0135.81] Checking ChildNode[1]: DecoratorNode_1
            [0135.81] DecoratorNode_1 Inactive State
            [0135.81] DecoratorNode_1 Start State
            [0135.81] funct() NodeSelectionBehaviorDecorator
            [0135.81] Activate ChildNode[0]: SelectorNode_1
            [0135.81] DecoratorNode_1 CurrentValidOutputLinkIdx=0 OutputLinkIterator=0 OutputLinkIterator=0 bAllChildNodesActivated=True
            [0135.81] DecoratorNode_1 Running State
            [0135.83] Activating SelectorNode_1
            [0135.83] Adding to Valid ChildNode[0]: ConditionNode_0
            [0135.83] Adding to Valid ChildNode[1]: ActionNode_3
            [0135.83] Adding to Valid ChildNode[2]: ActionNode_1
            [0135.83] Activated SelectorNode_1
            [0135.83] SequenceNode_1 Checking
            [0135.83] funct() NodeCheckBehaviorSequence
            [0135.83] Checking ChildNode[1]: DecoratorNode_1
            [0135.83] DecoratorNode_1 Checking
            [0135.83] funct() NodeCheckBehaviorDecorator
            [0135.83] Checking ChildNode[0]: SelectorNode_1
            [0135.83] SelectorNode_1 Inactive State
            [0135.83] SelectorNode_1 Start State
            [0135.83] funct() NodeSelectionBehaviorSelector
            [0135.83] SelectorNode_1 CurrentValidOutputLinkIdx=0 OutputLinkIterator=0 bAllChildNodesActivated=False
            [0135.83] Activate ChildNode[0]: ConditionNode_0
            [0135.83] SelectorNode_1 Running State
            [0135.87] Activating ConditionNode_0
            [0135.87] Activated ConditionNode_0
            [0135.87] SequenceNode_1 Checking
            [0135.87] funct() NodeCheckBehaviorSequence
            [0135.87] Checking ChildNode[1]: DecoratorNode_1
            [0135.87] DecoratorNode_1 Checking
            [0135.87] funct() NodeCheckBehaviorDecorator
            [0135.87] Checking ChildNode[0]: SelectorNode_1
            [0135.87] SelectorNode_1 Checking
            [0135.87] funct() NodeCheckBehaviorSelector
            [0135.87] Checking ChildNode[0]: ConditionNode_0
            [0135.87] ConditionNode_0 Inactive State
            [0135.87] ConditionNode_0 Start State
            [0135.87] funct() NodeSelectionBehaviorNone
            [0135.87] ConditionNode_0 Running State
            [0135.92] SequenceNode_1 Checking
            [0135.92] funct() NodeCheckBehaviorSequence
            [0135.92] Checking ChildNode[1]: DecoratorNode_1
            [0135.92] DecoratorNode_1 Checking
            [0135.92] funct() NodeCheckBehaviorDecorator
            [0135.92] Checking ChildNode[0]: SelectorNode_1
            [0135.92] SelectorNode_1 Checking
            [0135.92] funct() NodeCheckBehaviorSelector
            [0135.92] Checking ChildNode[0]: ConditionNode_0
            [0135.92] ConditionNode_0 Checking
            [0135.92] funct() NodeCheckBehaviorNone
            [0135.92] Bail = SUCCESS
            [0135.92] ConditionNode_0 Results are in. Change to Finish.
            [0135.92] ConditionNode_0 Finish State
            [0135.94] SequenceNode_1 Checking
            [0135.94] funct() NodeCheckBehaviorSequence
            [0135.94] Checking ChildNode[1]: DecoratorNode_1
            [0135.94] DecoratorNode_1 Checking
            [0135.94] funct() NodeCheckBehaviorDecorator
            [0135.94] Checking ChildNode[0]: SelectorNode_1
            [0135.94] SelectorNode_1 Checking
            [0135.94] funct() NodeCheckBehaviorSelector
            [0135.94] Checking ChildNode[0]: ConditionNode_0
            [0135.94] ChildNode[0] Finished!
            [0135.94] Bail = FAILURE
            [0135.94] SelectorNode_1 Results are in. Change to Finish.
            [0135.94] SelectorNode_1 Finish State
            [0135.98] SequenceNode_1 Checking
            [0135.98] funct() NodeCheckBehaviorSequence
            [0135.98] Checking ChildNode[1]: DecoratorNode_1
            [0135.98] DecoratorNode_1 Checking
            [0135.98] funct() NodeCheckBehaviorDecorator
            [0135.98] Checking ChildNode[0]: SelectorNode_1
            [0135.98] Bail = FAILURE
            [0135.98] DecoratorNode_1 Results are in. Change to Finish.
            [0135.98] DecoratorNode_1 Finish State
            [0136.03] SequenceNode_1 Checking
            [0136.03] funct() NodeCheckBehaviorSequence
            [0136.03] Checking ChildNode[1]: DecoratorNode_1
            [0136.03] ChildNode[1] Finished!
            [0136.03] Bail = FAILURE
            [0136.03] SequenceNode_1 Results are in. Change to Finish.
            [0136.03] SequenceNode_1 Finish State
            Making steady progress in Brains. Composite Nodes: Sequence, Selector, Parallel are functional. I'm directing my efforts on the Leaf Nodes: Condition and Action Nodes. BRAINS has 3 subsystems: Planner, Motor, Sensor. Composite Nodes are part of the Planner Subsystem, making decisions for selecting the Condition (Sensory) and Action (Motor).

            The Condition Node performs simulated perception with various Trace and Collision detection methods, internal and external status checks. I intend to implement a simplified rule-based expert machine to process internal/external status checks using the concept of GiveTake Registry (Knowledge-base). It is possible to temporarily store SimPerception Query results in the GTR for comparison by the expert-machine.

            The Action Node performs Animation, Navigation, Inventory selection and item use (Weapons/Powerups).

            Comment


              #21
              The Original Behavioral Rules A.I. Nodes System (BRAINS)

              In 2008, I was developing The Original B.R.A.I.N.S to address two questions posed:

              1. How do I resolve player actions, or have a good system of restricting/allowing player action without writing hundreds of functions?
              2. How can I make the avatar "smart" so that it will interact with different objects in the world in different ways.I was working on this


              Answering these questions and providing a more comprehensive AI are the motivators behind BRAINS Interactive Model. BRAINS incorporates Give||Take Registry (Rules-based System), Binary Decision Trees, Hit Objects (Triggers), Tasks (LUA Script), Dark AI (Pathfinding), and Q & A Diaglog.



              The Give||Take Registry

              The Give||Take Registry is a list (queue, stack, or any other data structure) of Node Keys. A Node Key contains a: name, value, compare operator, and logical operator. Node Keys can represent any kind of property. The data in the Node Key is used to perform a simple IF condition and return a TRUE/FALSE result. I find it easier to visualize each IF Condition as a `node` in a decision tree, hince the label Node Key. All the Node results are tallied to produce a final TRUE/FALSE result.


              All Interactive Entities have their own Registry and the Give||Take role is based on the entity that initiates the interaction (collision check). Entities who initiate the interaction are Giving, the receiving Entities are Taking. When Giving, each Node Key can represent something the Entity possesses. When Taking, each Node Key can represent something required by the Giving Entity for positive interaction.


              From a coding perspective, we iterate through each Node Key in the Take Registry. Each Node Key is matched-by-name to a Node Key in the Give Registry. The Operators from Take Registry Node Key are used to perform the comparison. If the result is TRUE we continue to the next Node Key, otherwise we exit checking returning a FALSE result. If we’re able to iterate through all the nodes we return a TRUE. Thats it! The final result can used to execute a scripted action.


              GTR is a simple and high performance solution for dealing with Interactions that require many conditional checks against a Player Character abilities, skills, accessories, items etc. GTR solves Question #1.


              Hit Boxes

              Triggers address Question#2. A Trigger is a type of Hit Object placed in the environment to trigger events (ie: Door Switch). A Hit Object is a 2D/3D Object that executes one or more scripted actions when a collision event occurs between itself and other Hit Objects. Hit Objects are `glued` to other objects such as Players/NPCs, Weapons, Projectiles, etc to create a means of interaction. Hit Objects are used for all 3D interactions and are what make Interactive Entities…interactive.

              A Quest Map can contain hundreds of Triggers. Thus, instead of requiring a slew of actions for a Interactive Entity to `intelligently and logically` respond to a Triggered Event, the Trigger executes a action that acts upon the Interactive Entity.

              The Unofficial List of Mob/Boss AI Behaviors

              I will be using Dark AI for directing AI Behaviors in DarkMORG. The goal is to create distinctive and challenging behavior. Below is a list of behaviors that I will add too as they pop in my head.

              Kamikaze : Relentless Pursuit and damaging Self Destruction to enemies at close range.
              ScaryKat : Relentless Full-Powered Attack close or long range, immediately followed by retreat to neareast barrier.
              Ninja : Silent Attack (no Audio Triggers) and usual visual distortion, uses only close range single hit melee attacks.
              Sniper : Seeks Barriers only attacking from long distance.
              Bowler : Attacks enemies by converting enemies into throwing projectiles upon contact.
              Virus : Infects enemy mobs upon contact reproducing finite number of clones of itself and attacks with ranged weapons.
              Boomer : Infects enemy mobs upon contact reproducing a finite number of clones of infected mob.
              BackStabber : Relentless pursuit and attack when not facing enemy, retreats when faced.
              Pawn : Only pursuits and attacks (melee) when enemy is adjacent with reduced defense, otherwise its frozen in place when directly faced with double defense.
              Reverend : Heals weak friendlies.
              Nemesis : Infects `corpses` upon contact reproducing finite number of clones of itself and attacks with ranged weapons.
              Replicant : Consumes a finite number of weaker Enemies, Replicaticating.
              Boulder : Great in Size|Speed|Both, Relentessly pursuits Enemy with Devastating Melee Attacks, Weakens in Size/Speed/Both from Critical Damage.
              Fuser : Combines with finite number of its own kind to metamorph into a more power foe.
              Blinker : Attacks various distances, Pauses for short time to Recharge/Reload, then Teleports.
              Hydra :Great in Size|Speed|Both, Attacks from various distances, Replicates into finite number of copies with 1/2 Size/Speed/Both from Critical Damage.
              Mad-Man : Relentless Attack, practically invincible with specific weak point that causes critical damage.

              Comment


                #22
                BRAINS Overview #1

                Comment


                  #23
                  Latent Functions

                  Latent Function are special native functions that can only be used in state code. (i.e. in labels outside of functions within states. See ScriptedPawn's script for excellent examples). They will cause script execution within the state to pause until some condition is met. All other functions and states in other classes will continue to execute normally.
                  While you cannot define new latent functions, it possible to pull a similar effect:

                  Sleep (float Seconds)
                  Waits for the specified amount of time. Note using continual low values of sleep() (<0.1) is not recommended, as this creates signnificant dependance on frame rate. For instance, the minigun has this problem, where different frame rates make it fire different amounts of bullets in a second. See this graph.

                  FinishAnim ( )

                  Waits till the current animation is finished. WARNING: If you have an AnimEnd() that plays a new animation, this will never pass!

                  FinishInterpolation ( )
                  Only used mostly in movers. Pauses until the mover has finished interpolated to the next key.

                  MoveTo (vector NewDestination, optional float speed)
                  This function moves the pawn to the specified destination. The destination is an actual point in space rather than a displacement vector to be travelled. The pawn will travel at the speed * groundspeed or use groundspeed itself if no value is specified.

                  MoveToward (Actor (UT) NewTarget, optional float speed)

                  This function will cause the pawn to move towards the Actor (UT) specified. The pawn will travel at the speed * groundspeed or use groundspeed itself if no value is specified.

                  StrafeTo (vector NewDestination, vector NewFocus)

                  This function "strafes" the pawn to the specified destination. The pawn faces in the direction specified by NewFocus. It is assumed that the RotationRate property is used to determine how long this operation takes.

                  StrafeFacing (vector NewDestination, Actor (UT) NewTarget)

                  This function "strafes" the pawn to the specified destination. The pawn attempts to keep turning to face the Actor (UT) specfied. It is assumed that the RotationRate property determines how successful this is.

                  TurnTo (vector NewFocus)
                  This function turns the pawn to face the direction specified.

                  TurnToward (Actor (UT) NewTarget)

                  This function causes the pawn to turn towards the Actor (UT) specified.

                  References:
                  http://wiki.beyondunreal.com/Legacy:...(UT)/Functions
                  http://wiki.beyondunreal.com/Legacy:Pawn_(UT)/Movement
                  http://wiki.beyondunreal.com/Legacy:...)/AI_Functions

                  Comment


                    #24

                    Comment


                      #25
                      When is it going to be able to download?

                      Comment


                        #26
                        Originally posted by MaKiPL View Post
                        When is it going to be able to download?
                        Hi MaKiPL, I'll make the code immediately available to anyone interested in contributing to its research and development. Otherwise no official release date for public consumption at this time (unofficially aiming for Apr 30th). If you're interested in contributing please advise.

                        Comment


                          #27
                          Originally posted by GeekyPayback View Post
                          I don't understand the point of this thread? The title implied there would be an AI framework to discuss and feedback into, then the second post talks about a scripted mood music generator?
                          This was the first ting I was thinking

                          Progress: Until now, my exposure to working with Kismet has been little to none, I now find myself breaking down the Kismet Classes to get a firm understanding of its inner workings.
                          This should have been understood from reading classes when you first got into udk back when? 2009?

                          I would still like to see where this goes.
                          I don't mean to sound sarcastic in anyway, I'm just old-school and prefer writing hundreds of line of code and functions.

                          Comment


                            #28
                            Originally posted by DWGS View Post
                            This was the first ting I was thinking



                            This should have been understood from reading classes when you first got into udk back when? 2009?

                            I would still like to see where this goes.
                            I don't mean to sound sarcastic in anyway, I'm just old-school and prefer writing hundreds of line of code and functions.
                            I signed up on the UDK forums in 2009, I didn't start working with UDK until 2013. BRAINS utilizes Kismet as a Visual Behavior Tree Editor similar to:Think,CryEngine Behavior Selection Tree Editor,RAIN,Brainiac Designer,Behave 2,ComBE,LOVE BTEditor. It still requires hundreds of line of custom UnrealScript to make it work as such.

                            Comment


                              #29
                              what kind of OOP and coding background do you have?

                              Comment


                                #30
                                Originally posted by DWGS View Post
                                what kind of OOP and coding background do you have?
                                My previous projects. Relevance to Unrealscript? Not much.

                                Comment

                                Working...
                                X