Calamari / BehaviorTree.js

An JavaScript implementation of Behavior Trees.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Calling step() when not done last task

tanema opened this issue · comments

Hello, This is a really awesome project you have here there is just one point that I want to question. It may not be a bug it may just be that I should use it differently.

When I call step() (which I do during my game loop) if the last step has not been completed it outputs "the BehaviorTree "name" did call step but one Task did not finish on last call of step."

In the source it shows that it outputs that message then just continues. Shouldn't step return and do nothing until success or fail has been called? I do not feel like slowing down my game loop just to make sure my behaviour has finished before I call step again.

Maybe I should be using it in a different way?

Also just going to put this out there, I needed this library for a very strict ECMA3/ECMA5 interpreter so I translated all the code to pure javascript without the base.js requirement. Is that something that you would be interested in me cleaning up and submitting a pull request?

To ensure, that every task is in a defined state and no to tasks run in parallel, every run method should do its stuff, and either call .success() if it did succeed, .fail() if it did fail or call .running() which I think should match what you are trying to do. So the next time, .step() is called the behavior tree will start off with this task and process the tree further.

Is this what you wanted, or have I misunderstood you?

About the Base requirement: If you have a refactored version without, I would really like to see it. Removing this dependency was also in my mind, although not very high in priority to be honest.

Oh, and I am curious what you are building with it, having this strict interpreter restrictions. If you am willing to tell ;-)

Okay I think you misunderstood me. There exists a use case where the last step has not finished yet but step() is called in the game loop.
Currently instead of doing nothing and waiting for the task to end it will log a warning and continue the next step on line 28
https://github.com/Calamari/BehaviorTree.js/blob/master/src/behavior_tree.js#L28-L30

I propose that it just simply return from that method and do nothing until then the current node is finished.

Also as for your question about what I am building, it is just a mmo type environment that I play around with in my spare time with a Go backend. I am using Otto(https://github.com/robertkrimen/otto) to script the npc AI. For some reason base.js wasn't working in that environment.

So it is a problem with asynchronousity, right? Your tasks do asynchronous stuff and meanwhile the game loop runs on. I must confess I have not thought about having tasks, that do async stuff. I also do not remember have read anything about people having to cope with async stuff while building behaviours.

My first thought here would be to structure the behaviour tasks a bit differently, so they do not rely on things that have to be asynchronous. Which probably might be easier said then done. ;-)
Option 2 that comes to my mind is, rewriting the step in a way, it takes a callback, when the tasks are done. So it can be omitted in game loop runs, while the last step has not run through.
Option 3 (the least preferable one) would be, to just give an option to omit the log entry. But doing this would consequently lead to a potential invalid state of the whole machinery.

I will have to think about it a bit more.

(An JavaScript parser written in Go? Interesting. No I am intrigued what the reasons are why you write the AI part in JavaScript and not in go itself. Want to changing AIs in runtime?)

I do javascript AI because I built it for flexibility, and Go does not have runtime includes. I wanted to be able to update my game world definitions without having to touch backend code.

I think in the end I might just maintain just make the change in my own fork and keep it that way after I submit the pull request

I just rewrote the bundling process. Base is still included, but maybe, it will note give problems in Go anymore, because it should be transparent now to the outside world.

Would be nice, if you would check it, if it is still necessary or a problem.

No it doesn't work still. This is more likely an issue with my environment than your code. Also I think I am going to close this issue since it has no unresolved issues.