Closed xescugc closed 5 months ago
I've read a bit the code and found that maybe you actually have some of them (or all). But they are not mentioned/documented on the README and the sames used are not the ones I've read on other parts.
For example you have:
Not
which looks like the Inverter
Shuffle
which looks like the Random
If that's the case, is there a reason on the names? Just curious, again I don't know much about this and I want to know if there are no "references" on names.
Hey @xescugc :)
Yep, you'll find that the terminology varies.
re: Contributing, feel free to put a PR up if you feel like it'd be useful. I'd recommend opening an issue to discuss it first though, as it will increase the chances that I'll merge it, and I wouldn't want you wasting your time.
This implementation is more closely based on the academic definition of what a behavior tree is, rather than what I have seen in game dev literature. I started with the wikipedia page - just Sequence
and Selector
, and built it out as I needed.
The only feature that didn't come from an immediate use case was Memorize
, which has effectively replaced the Sync
function, in my own personal projects, baring one or two specific use cases, and came from the whitepaper/book linked in the README.
In other words, my primary goal has been to solve problems I was facing, and the implementation reflects that. For the most part, the names were simply what I felt fit at the time, and don't necessarily align with any well-defined concept, in either academia or game dev. Beyond exceptions including Sequence
, Selector
, and Memorize
, that is.
You might find it interesting to read this documentation, from BehaviorTree/BehaviorTree.CPP, which is aimed at robotics, and is the second most starred behavior tree implementation on GitHub (the highest in C++ by a large margin). I'll go section by section because I'm invested in this explanation now lol.
Sequences: They provide 3 types, Sequence, SequenceWithMemory, ReactiveSequence. In comparison to this module, bt.New(bt.Sequence, children...)
behaves like ReactiveSequence
, bt.New(bt.Memorize(bt.Sequence), children...)
behaves like Sequence
, and SequenceWithMemory
doesn't have an analogue, but you could trivially emulate it by wrapping each child to map bt.Failure
to bt.Running
, and use those children within bt.New(bt.Memorize(bt.Sequence), children...)
. More on what I've termed "tick wrappers" in a bit.
Fallbacks: As above except bt.Selector
instead of bt.Sequence
, and no "run only once until all succeed" variant.
Decorators: Are simply for convenience in this module. They are much more important if your trees are defined in XML, rather than code. You'll notice that, bt.Not
, for example, is extremely trivial. I only included it because I found myself reimplementing it multiple times.
To quote their docs:
A decorator is a node that must have a single child.
It is up to the Decorator to decide if, when and how many times the child should be ticked.
Is the entirety of their preamble, before jumping into the types of decorators they support out of the box. The "decorators" that this module provides are simply closures that implement or wrap bt.Tick
values. I did not deliberately design in the concept, it was basically just an emergent pattern that I found worked well. The bt.Memorize
function is a "tick wrapper" in the same vein, though it doesn't fit the definition of a decorator used by BehaviorTree.CPP. I've documented the general rules I've followed to implement tick wrappers in the readme (I think?).
re: Contributing, feel free to put a PR up if you feel like it'd be useful. I'd recommend opening an issue to discuss it first though, as it will increase the chances that I'll merge it, and I wouldn't want you wasting your time.
Yes ofc an issue will always be first haha. But I always ask before doing anything just in case.
Thanks you for the explanation, it's fine for me to have whatever names but I was wondering if that was a difference between gaming/robotics/academics haha.
I'll close the issue as everything is clear :) (I'll open another one/two for something I want to add hehe)
Is your feature request related to a problem? Please describe.
I'm new to BT but one thing I've seen is that there are much more Composite nodes than the
Sequence
andSelector
, for exampleRandom Selectors / Sequences
.And there are also the
Decorators
:Inverter
: Simply put they will invert or negate the result of their child node.Repeater
: A repeater will reprocess its child node each time its child returns a result. These are often used at the very base of the tree, to make the tree to run continuously. Repeaters may optionally run their children a set number of times before returning to their parent.Succeeder
: A succeeder will always return success, irrespective of what the child node actually returned.For what I read there much more but those look like the main ones also
Describe the solution you'd like
To consider the option of adding them
Describe alternatives you've considered
As long as you are ok on adding them I could take a look into doing it myself :)
Additional context
Another GO lib that has some of the Composites and Deocrators: https://github.com/askft/go-behave?tab=readme-ov-file#composite-nodes
A blog also mentioning some of those https://www.gamedeveloper.com/programming/behavior-trees-for-ai-how-they-work
As I said before, anyone can add anything but looks like those are common.