More messing around with npc bed behavior. A nice change is a way to pass arguments along the behavior tree - so I have one behavior tree that handles navigating to and using an object. I reuse this same subtree for various types of behaviors, but can alter things about it such as how long to wait to activate the object, or how close you need to be to that object to actually activate it. Without this, npcs were having a hard time navigating to be close enough to actually use the bed when it had collision turned on.
Here's the sleep behavior:
So the _interact_object is a generic behavior that you can plug any object, action, and distance into. I can reuse it for picking up logs, dropping logs in the campfire, cooking food on the campfire, etc. Less powerful, is the only in-tree logic possible is checking flags. I have a function on the npc that checks various bits of logic and turns those flags off and on. So if the npc is tired and near a bed, he will turn on the "head_to_bed" flag.
Again, the boundary between the two types of system (python logic setting flags, and behavior trees acting on behavior) is kind of unstable and weird. I can see myself extending the capabilities of the behavior trees, so that all the logic happens in one place. But that's a lot worse for performance, and I'm not sure I want to do most of my coding in the BTs either. I'm much faster in python, my native language.
Basically it's a bunch of elegant systems, cobbled together with duck tape :) Sadly, all of the AI research I have done up to this point has been excellent at describing individual systems, but there is almost nothing on how to attach them together. And in real, complex simulations, that's where the meat really is.