Modding Discussion Behaviors

Discussion in 'Starbound Modding' started by CTFJERK, Sep 4, 2017.


    CTFJERK Intergalactic Tourist

    Hello, i am working on a mod that requires editing behaviors. My implementation involves allowing certain actions to be initiated for npc that have certain equipment, for example, you can tell a shield npc to block damage for you by positioning themselves between you and the target.(I will implement equipment modification later)

    Now what i learned is that there is a tree in each of the .behavior files. The nodes in these trees have different parameters and functionality based on it type. I've noted 5 types:
    just means it has multiple nodes
    "name:" points to another .behavior file
    "name:" points to a function in one of the listed scripts
    as the type suggests, functions of this node generate actions for the npc to executes. From movement to reading npc info.
    "name:" points to a function in one of the listed scripts
    as the type may not suggest,(unless you think everyday is Christmas) these nodes modify how the node communicate with each other. Doing things like modifying the return values of nodes, blocking off branches with a cool down, etc.

    keep in mind that the .node files dictate the manifestation of these nodes in-case you are thinking of creating your own. also, some action parameters can receive data via key pairs. basicially, you have an action that outputs something, in the output field, you set the returned item to be returned as "blah". in another action you can read in that value by setting the "key" field as "blah".

    for composite types, the name contains either
    It runs each child node from left-to-right till one returns false, returning false as a result. Otherwise it returns true.

    Like an inverted sequence node, it runs each child node in the same order till one of them returns true, returning true as a result. Otherwise it returns false.

    The last 2 are mostly speculation. Haven't even tested it yet. in these, I'm just going to use branches when i mean child nodes, sounds more natural.

    -Parallel(theory): I am a bit unsure about how parallel works but in theory:
    Each branch is executed at the same time till one of them returns false.
    It has 2 values; fail and success. In each a value that hold an integer that is either 1 or -1.
    with fail represents what happens when a branch returns false, success vice versa:
    a value of -1 means that the branch repeats if it hits parameters associated result.(example: with success:-1, if a node/subtree returns true, repeat that node/subtree)
    a value of 1 means the entire parallel subtree is terminated onto the next node if it hits the parameters associated result.

    I think it just runs all the branches, if a branch returns anything, only that branch is terminated while the rest continue till they finish. Now in order to prevent excessive data consumption, these branches usually read for certain boolean values to confirm execution. That way only designated actions are executed.
    As for return values go, I'm not sure. maybe every branch return a value through the dynamic node upon completion, or maybe only the last/first branch to finish is returned. Sounds a little messy if you ask me, but that's probably why some of the cases involve setting a dynamic node as the child of a parallel or succeeded in-case you don't need the return value from the dynamic node itself.

    but yea, that's my take on the matter I would appreciate any help, clarifications, or info pertaining to this subject.
    some of the trees are a little too big to be worth illustrating by hand, but i might post some pictures if I have time to do it.(or maybe post a program that does that for you, idk)

    edit: updated!
    I may create a tutorial on this, but unless i'm sure that the data I have is sufficient and reliable, I'm kindo'v holding on that. Plus I have to take into consideration the possibility of the architecture changing across game updates. The current NPC programming is alittle fidgety; certain actions (Like custom dances) don't seem to hold all that well.
    Last edited: Sep 17, 2017
    Tamamo89 likes this.

    CTFJERK Intergalactic Tourist

    As for now, here is a pretty useful visualizer for the JSON behavior files:
    it does not generate graph but a manageable hierarchy, its quite neat. Now i think viewing the code in eclipse(an IDE(Interactive Development Environment) which is fancy for code editing software) can yield a similar effect using one of it's features.

    I'm probably not going to actually make a graph based visualizer,I don't necessarily have that kind of time... yet... maybe... who knows. I can make due with this so I simply don't feel the need to make such a tool unless i intended to add a behavior create functionality... which i also don't have time for.
  3. v6ooo

    v6ooo Cosmic Narwhal

    CTFJERK likes this.

    CTFJERK Intergalactic Tourist

    Holy howitzers didn't even know they had one. This is way better than the visualizer. Thank you for sharing this.
  5. Tamamo89

    Tamamo89 Big Damn Hero

    Actually parallel and dynamic work a bit different then you might think.

    The parallel node ticks all children at the same time, allowing them to work in parallel. This node is a way to use concurrency in Behavior Trees. Notice that, using this node, the parallelization is contained locally, avoiding losing control of the execution flow as happens on with state machines. Parallel nodes return SUCCESS if the number of succeeding children is larger than a local constant Success (this constant may be different for each parallel node); return FAILURE if the number of failing children is larger than a local constant Falure; or return RUNNING otherwise.

    The dynamic node is a bit different but similiar. It is basically a selector version of the parallel node. Dynamic nodes tic all children until one return SUCCESS and will also return FAILURE if all of the children return failure. If a RUNNER node is used, it will continue to tic it's children until one returns true.

    Correct me if I'm wrong here. @Healthire
  6. Healthire

    Healthire Can't Most Program the Least Chucklefish

    Dynamic works like the selector, where it will run its children until one returns RUNNING or SUCCESS. The difference is that it will keep trying the previous children that returned FAILURE the next tick. If one of those previous children return RUNNING, that will interrupt whatever child ahead of it is currently running. Returning SUCCESS from any child will return SUCCESS for the dynamic node. A better name for the node would be the Priority node. The higher up the child, the higher the priority.

Share This Page