> A different thought I have that I couldn’t get around exploring is to implement behavior trees with channels (no go routines).

I don't think "channels without go routines" are possible. One thread can't send and simultaneously receive on a channel. I remember libraries that used go channels for control flow because the code looked better this way. They had to start a second thread to make it work which is very inefficient.

Better approaches are "functions" with internal state (generators) or the relatively new stdlib iter package.

Edit: the iter package internally uses compiler quirks to implement coroutines to be able to send and receive values on the same thread.