limbonaut / limboai

LimboAI - Behavior Trees and State Machines for Godot 4
https://limboai.readthedocs.io/
MIT License
1.25k stars 49 forks source link

Prefetch failed for nodes set directly from BlackboardPlan resource settings #207

Closed m-radzikowski closed 2 months ago

m-radzikowski commented 2 months ago

Godot version

v4.3.limboai+v1.2.1.gha [77dcf97d8]

LimboAI version

v1.2.1 [7839670]

LimboAI variant

GDExtension / AssetLib

Issue description

When setting a Node for a NodePath value under BlackboardPlan resource (and with NodePath Prefetching enabled), the prefetch fails with the error:

E 0:00:00:0604   bb_add_var_dup_with_prefetch: BlackboardPlan: Prefetch failed for variable $raycast_left with value: RayCastLeft
  <C++ Source>   blackboard\blackboard_plan.cpp:398 @ bb_add_var_dup_with_prefetch()

I've figured out it only works if I select the BTPlayer Node and there I override the default value under the BlackboardPlan. Is this the expected behavior or am I doing something wrong? It's at least very confusing...

I see the same behavior with Godot build with included C++ module and with the GDExtension added in assets.

How to reproduce

Blackboard Plan window: image

Opening BlackboardPlan and selecting the Node: image

When run, the prefetch fails.

However, if I select the BTPlayer Node and there override the blackboard param value, it works fine: image

Here is a repro project: limbo-bug-repro.zip

ydeltastar commented 2 months ago

The paths are different for each case.

When setting a NodePath from the standalone resource inspector (not from an var in a node such as BTPlayer), the root reference is the currently open scene's root, in this case "Golem", so the result is "RayCastLeft". When setting a NodePath from BTPlayer's node inspector, the root reference is BTPlayer itself. In this case, the result is "../RayCastLeft".

Prefetch uses BTPlayer as root, so the first case is the wrong path while the second is the correct relative path. This difference in root references is a behavior of Godot itself.

m-radzikowski commented 2 months ago

Okay, I see the problem. And because the BlackboardPlan inspector is not linked to the open scene tree, I can switch to completely unrelated scene and assign a NodePath from it, which will obviously be invalid...

So the solution is to either assign NodePaths from the BTPlayer's node inspector as overrides or provide them manually taking into account that they will be resolved with BTPlayer as root?

ydeltastar commented 2 months ago

So the solution is to either assign NodePaths from the BTPlayer's node inspector as overrides or provide them manually taking into account that they will be resolved with BTPlayer as root?

Yes. You can manually type it using the Edit option on the NodePath field from the tree dots menu. However, it makes more sense to set these scene-dependent things as BTPlayer's overrides since Godot automatically updates paths when things change.

limbonaut commented 2 months ago

This one is tough to crack. I was considering setting Nodepath properties read-only for blackboard plans that belong to BT resources as a solution.

m-radzikowski commented 2 months ago

What I was lacking was some info / warning - either in editor or at least documentation. Making it readonly would prevent errors but some explanation next to it would be still needed IMHO.

limbonaut commented 2 months ago

Right. Ideally, I'd like to find a way for it to just work, and if not - it's disabling editing.

limbonaut commented 2 months ago

@m-radzikowski Could you please check if #215 fixes your issue here? Builds: https://github.com/limbonaut/limboai/actions/runs/10871550010

m-radzikowski commented 2 months ago

Yes! Works great.

limbonaut commented 2 months ago

Great, thanks for the detailed report!