Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle interruptions? #8

Open
aus70 opened this issue May 27, 2023 · 2 comments
Open

How to handle interruptions? #8

aus70 opened this issue May 27, 2023 · 2 comments

Comments

@aus70
Copy link
Contributor

aus70 commented May 27, 2023

Hi, is there an idiomatic way to generate interruptions, as described in Petter Ögren's video https://youtu.be/DCZJUvTQV5Q?t=544 ?

Thanks!

[edit] I guess that making sure that "longer running actions are merely the repetition of smaller actions" (see https://gamedev.stackexchange.com/questions/114125/behavior-tree-with-interrupted-sequence) is the way ensure that conditions are evaluated often enough. Do you agree?

@jschomay
Copy link
Owner

Hello again. This is a good question. For reference, the term I use is "Priority nodes", which are nodes that can interrupt the current running node.

I definitely gave it some thought when I was first writing this library and my conclusion then was that this functional approach just doesn't work so well for this kind of use case. The reason is because of the fundamental difference between "normal" behavior trees that walk the whole tree based on each node's "running status" vs the zipper tree that only has one "running" node. However, you can probably get this functionality with a little work.

I have thought about one possible way, though it isn't very nicely abstracted. Basically, when you reach a node that you want to mark as a "priority node", you store it (or more accurately, you store a copy of the zipper tree with that node as its root) as a separate piece of state. You might store a list of them if you have multiple priority nodes.

Then, before running the current node in your normal "tick" of the tree, you check each priority node that you stored. If their priority check passes, then you switch your BT to point at that branch and run it. If it fails, you run your BT like normal from the current active node.

You'd have to make sure to remove the priority node from your state if the node as a whole gets completed.

Another similar approach that doesn't require extra state is to traverse "upwards" from your current BT node (by recursively getting its parent) until you either reach the root of the whole tree, or hit a priority node, in which case you follow a similar pattern as above. You would do this every "tick."

You can probably use a normal Select node with 2 children as a priority node. The left child is another tree with a condition to determine if it should interrupt or not (the alarm in the video example), and the right child is is the normal behavior (eating the banana in the video example). This way, even if the banana eating behavior is in a Repeat node, the alarm checking behavior will always happen first, and take priority if it passes.

I hope that makes sense and points you in a good direction! Feel free to ask for clarification, and please share how it goes for you, or if you come up with another way of doing it.

@aus70
Copy link
Contributor Author

aus70 commented May 31, 2023

Thank you for your very detailed answer! My system is event-based, so I could simply reset the tree to the start state if an important event occurs, and implement the last one of your suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants