News Forums RAIN General Discussion and Troubleshooting Problem Understanding BT nodes

This topic contains 12 replies, has 2 voices, and was last updated by  Ibrahim 7 months, 1 week ago.

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #40014

    Ibrahim
    Participant

    Hello,

    I learned to build simple BTs that do simple tasks. But now when I tried to use BTs for my AI characters in the project I found difficulty building the BTs that will execute the behavior I wish to have. I have watched tutorials (all are very basic examples), and also read all the RAIN WIKI but still not able to build what I want.

    My game is about fire fighting: For instance, I want my AI (Team Leader) to check if the game started or not, once it started, he should query the GameController script about the first situation to handle, once he get this answer, he should send a message to all Firefighters to go to the fire truck, and once they are all inside it, the fire truck should move to the situation, and then he should command them to line up in front of the Truck, and so forth.. querying about the game from the game environment, receive and send information to other AIs and do some actions.

    Every other AI should also has its own BT, that controls his actions, receiving messages, doing actions, sensing and sending messages.

    I have started with the following BT for the Team Leader, but I it really seems weak and not working as expected (because of not understanding the nodes rules and how the sequence follow from one step to the next).

    <behaviortree version="1.1" repeatuntil="" name="FF_TL_BT" debugbreak="False"><sequencer usepriorities="False" repeatuntil="" name="TL_root" debugbreak="False"><constraint repeatuntil="" priority="" name="Game started? and there is at least one situation to handle?" debugbreak="False" constraint="gameStarted == true && numberOfSituations > 0"><constraint repeatuntil="" name="Far from situation?" debugbreak="False" constraint="distanceToSituation > 50"><sequencer usepriorities="False" repeatuntil="" name="sequencer" debugbreak="False"><action repeatuntil="" priority="" parametervalues="" parameters="" namespace="(global)" name="Send Message to FFs to go to FF Truck" debugbreak="False" classname="SendMessageToFFs" /></sequencer><parallel tiebreaker="fail" succeed="all" repeatuntil="" name="parallel" fail="any" debugbreak="False"><move turnspeed="" repeatuntil="" name="Move to my door in fire truck" movetarget="myDoor" movespeed="3" facetarget="myDoor" debugbreak="False" closeenoughdistance="" closeenoughangle="" /><animate repeatuntil="" name="animate" debugbreak="False" animationstate="Locomotion.WalkRun" /></parallel><constraint repeatuntil="" name="constraint" debugbreak="False" constraint="!ffDetector.active"><action repeatuntil="" parametervalues="" parameters="" namespace="(global)" name="Send message to FF Truck to go to currentsituation" debugbreak="True" classname="SendMessageToFFTruck" /></constraint></constraint></constraint></sequencer></behaviortree>

    Any help will be appreciated.

    #40029

    Sigil
    Keymaster

    Just letting you know I saw your post, I’ll be back a bit later with some possible solutions for you.

    #40045

    Sigil
    Keymaster

    Ok, so let’s lay out an outline of what we need, and we’ll go from there. I’ll jump back on tomorrow and fill these out a bit more after I get some sleep.

    So starting with the easiest, the fire truck itself. I would probably start really simple and assume the fire truck does only one thing, head to a destination. Well one main thing, it also gets a message telling it where to go, and then sends a message when it arrives at its destination.

    root
       sequencer
          custom action (class: GetMessage) // new situation target message
          move (move target: situationTarget)
          custom action (class: SendMessage) // reach target message

    I’ll come back and define what I think the message class should be like, but for now we’ll just assume it’s fairly simple and will assign any variables that we may need (depending on the recipient). So in this case it assigned our situationTarget.

    Next up will be a random fire fighter, not the commander though. Again we’ll start simple, and assume the AI does only a few things: it idles, it gets in the fire truck, it waits until it gets somewhere, it gets out, repeat.

    root
       sequencer
          parallel (succeed: any, fail: any, tie breaker: fail)
             custom action (repeat: until success, class: GetMessage) // get in truck message
             sequencer (repeat: forever)
                expression (expression: debug("Idling"), returns: success)
                timer (seconds: 4)
          sequencer
             move (move target: fireTruckTarget)
             custom action (class: SendMessage) // inside truck message
             custom action (repeat: until success, class: GetMessage) // move to fire message
             move (move target: fireTarget)

    So they do very little fire fighting, essentially they just get in the truck and then get out of it. This is OK at first.

    Last tree is the commanders, which will be issuing some of the initial commands to get things going. We’ll start simple with him as well and assume he is waiting for a command from some game component somewhere.

    root
       sequencer
          parallel (succeed: any, fail: any, tie breaker: fail)
             custom action (repeat: until success, class: GetMessage) // new situation message
             sequencer (repeat: forever)
                expression (expression: debug("Idling"), returns: success)
                timer (seconds: 4)
          sequencer
             custom action (class: SendMessage) // get in truck message
             move (move target: fireTruckTarget)
             custom action (repeat: until success, class: GetMessage)  // everyone is in the truck
             custom action (class: SendMessage) // new situation position message
             custom action (repeat: until success, class: GetMessage) // reached target message
             custom action (class: SendMessage) // move to fire message
             move (move target: fireTarget)

    So this is still missing a lot, but that is OK. One of the key things to setting up a behavior tree is to start simple. So once we have a GetMessage/SendMessage setup properly, we should have a group of firemen, who get in a truck, drive the truck somewhere, get out of the truck, wait around, repeat.

    I’ll be back on later tomorrow to add some more and fix any issues I run into. Gonna put this together with some spheres and a cube.

    #40047

    Ibrahim
    Participant

    Thank you Sigil for this in-depth explanation. I really appreciate your effort. I also started to build my AI according to your guidance step-by-step.

    #40048

    Sigil
    Keymaster

    I’ll have the next part up in a few hours. I put something together but I need to double check it before posting.

    I put together an initial message class and updated the fire truck to match.

    #40054

    Sigil
    Keymaster

    So just an update on this:

    So I started out (as is evident by my behavior trees) with this idea that the AI would message each other (similar to what you were trying to start with). This has quickly gotten fairly complicated and isn’t the way I want to go with it. The best AI I’ve put together is also some of the simplest (relatively speaking), so when things start to get complicated I tend to stop and try again.

    At this point I’m trying to figure out where the boundary between the behavior tree and the game logic lies. The behavior tree tends to be good at making decisions and following through with simple actions, so I’m trying to work around that. I’ll post back when I have something more concrete.

    You wouldn’t think a few firemen would be that complex, but it can quickly get out of control, unless you just script it all from one end to another. That is always an option, but that doesn’t scale well so I try to avoid it.

    #40063

    Ibrahim
    Participant

    I always have difficulty distinguishing the boundary between the behavior tree and the game logic. Lately, I was able to implement your approach, and the basic behavior worked fine. However I have some issues:

    1- Sending and receiving messages will be used often in my project, I do not know how to implement it correctly. For the time being, I have a class for each custom action, and in this sendMessage classes I update the variables values directly. While in getMessage glasses I check for the wanted value and if it is there, it returns success, else returns failure.

    I believe it is not the correct way to do it, do you have any suggestions about sending and receiving messages using Custom Actions?

    2- Truck navigation is not using the Navmesh I have!

    Again, thank you for your help.

    • This reply was modified 7 months, 3 weeks ago by  Ibrahim.
    #40105

    Ibrahim
    Participant

    Hello Sigil, any updates?

    I know you must be busy with other more important stuff. I just wish if you can explain a bit about the flow of the nodes, and how I should think about it when I try to build more complicated behavior.

    Thank you.

    #40118

    Sigil
    Keymaster

    Sorry, got side tracked and hadn’t gotten back to this yet. I’ll take another swing at it tonight/tomorrow and let you know.

    #40140

    Sigil
    Keymaster

    Update on this: I have an example written up but I’m just going to upload the project instead of just posting code. I’ll also explain what I did and why. I don’t have it put together just yet (wanted to change a few names) so I’ll be putting it up later tonight.

    I liked this setup enough that I’m going to add it to our starter kit. Some useful behavior trees and it shows how to work between custom elements and the behavior tree.

    EDIT: Looks like I accidentally put this together with the wrong version of RAIN. All the code and Behavior Trees are good but I have to redo my scene, so I have to wait till morning.

    • This reply was modified 7 months, 1 week ago by  Sigil.
    • This reply was modified 7 months, 1 week ago by  Sigil.
    #40142

    Ibrahim
    Participant

    I appreciate your effort. Thank you.

    #40145

    Sigil
    Keymaster

    Here is the package. Import it into a blank project and try it out. It is fairly simple right now but expandable and a good example of how to simply communicate between several AI. There are firemen, a firetruck, and a firecommander who instructs them on what to do.

    I’ll be back later to update with a full post.

    FireMen 1.0

    #40149

    Ibrahim
    Participant

    I downloaded the package, and studying it now. It is very helpful

Viewing 13 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic.