From 000f9c15d8eef6888e249b339e06150046a314c3 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Thu, 15 Aug 2024 22:15:53 +0200 Subject: [PATCH 1/3] Fix BTState overwriting blackboard variables on init --- blackboard/blackboard.h | 1 + blackboard/blackboard_plan.cpp | 2 +- bt/bt_player.cpp | 1 + hsm/limbo_state.cpp | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/blackboard/blackboard.h b/blackboard/blackboard.h index 49288e1..5758cfb 100644 --- a/blackboard/blackboard.h +++ b/blackboard/blackboard.h @@ -49,6 +49,7 @@ public: Variant get_var(const StringName &p_name, const Variant &p_default = Variant(), bool p_complain = true) const; void set_var(const StringName &p_name, const Variant &p_value); bool has_var(const StringName &p_name) const; + _FORCE_INLINE_ bool has_local_var(const StringName &p_name) const { return data.has(p_name); } void erase_var(const StringName &p_name); void clear() { data.clear(); } TypedArray list_vars() const; diff --git a/blackboard/blackboard_plan.cpp b/blackboard/blackboard_plan.cpp index 7c61f8d..fa0234a 100644 --- a/blackboard/blackboard_plan.cpp +++ b/blackboard/blackboard_plan.cpp @@ -416,7 +416,7 @@ void BlackboardPlan::populate_blackboard(const Ref &p_blackboard, bo ERR_FAIL_COND(p_node == nullptr && prefetch_nodepath_vars); ERR_FAIL_COND(p_blackboard.is_null()); for (const Pair &p : var_list) { - if (p_blackboard->has_var(p.first) && !overwrite) { + if (p_blackboard->has_local_var(p.first) && !overwrite) { continue; } bool has_mapping = parent_scope_mapping.has(p.first); diff --git a/bt/bt_player.cpp b/bt/bt_player.cpp index 6fd6ca5..75593e9 100644 --- a/bt/bt_player.cpp +++ b/bt/bt_player.cpp @@ -183,6 +183,7 @@ void BTPlayer::_notification(int p_notification) { blackboard = Ref(memnew(Blackboard)); } if (blackboard_plan.is_valid()) { + // Don't overwrite existing blackboard values as they may be initialized from code. blackboard_plan->populate_blackboard(blackboard, false, this); } if (behavior_tree.is_valid()) { diff --git a/hsm/limbo_state.cpp b/hsm/limbo_state.cpp index 972970d..e02ed92 100644 --- a/hsm/limbo_state.cpp +++ b/hsm/limbo_state.cpp @@ -95,7 +95,8 @@ void LimboState::_initialize(Node *p_agent, const Ref &p_blackboard) blackboard = p_blackboard; } if (blackboard_plan.is_valid() && !blackboard_plan->is_empty()) { - blackboard_plan->populate_blackboard(blackboard, true, this); + // Don't overwrite existing blackboard values as they may be initialized from code. + blackboard_plan->populate_blackboard(blackboard, false, this); } _setup(); From cfacd57f15d0ae47822fe021d494048a2110dbef Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Thu, 15 Aug 2024 22:44:10 +0200 Subject: [PATCH 2/3] Warn about type mismatch when populating blackboard --- blackboard/blackboard_plan.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/blackboard/blackboard_plan.cpp b/blackboard/blackboard_plan.cpp index fa0234a..363b3e7 100644 --- a/blackboard/blackboard_plan.cpp +++ b/blackboard/blackboard_plan.cpp @@ -417,6 +417,12 @@ void BlackboardPlan::populate_blackboard(const Ref &p_blackboard, bo ERR_FAIL_COND(p_blackboard.is_null()); for (const Pair &p : var_list) { if (p_blackboard->has_local_var(p.first) && !overwrite) { + Variant::Type existing_type = p_blackboard->get_var(p.first).get_type(); + Variant::Type planned_type = p.second.get_type(); + if (existing_type != planned_type && existing_type != Variant::NIL && planned_type != Variant::NIL) { + WARN_PRINT(vformat("BlackboardPlan: Not overwriting %s as it already exists in the blackboard, but it has a different type than planned (%s vs %s). File: %s", + LimboUtility::get_singleton()->decorate_var(p.first), Variant::get_type_name(existing_type), Variant::get_type_name(planned_type), get_path())); + } continue; } bool has_mapping = parent_scope_mapping.has(p.first); @@ -425,7 +431,7 @@ void BlackboardPlan::populate_blackboard(const Ref &p_blackboard, bo if (has_mapping) { StringName target_var = parent_scope_mapping[p.first]; if (target_var != StringName()) { - ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable $%s to parent scope because the parent scope is not set.", p.first)); + ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable %s to parent scope because the parent scope is not set.", LimboUtility::get_singleton()->decorate_var(p.first))); p_blackboard->link_var(p.first, p_blackboard->get_parent(), target_var); } } From 43035839b1fd0fdb013ceef05c41b2df6e984cb6 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Fri, 16 Aug 2024 00:44:37 +0200 Subject: [PATCH 3/3] Don't warn of mismatch between Object & NodePath --- blackboard/blackboard_plan.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blackboard/blackboard_plan.cpp b/blackboard/blackboard_plan.cpp index 363b3e7..806d153 100644 --- a/blackboard/blackboard_plan.cpp +++ b/blackboard/blackboard_plan.cpp @@ -417,12 +417,14 @@ void BlackboardPlan::populate_blackboard(const Ref &p_blackboard, bo ERR_FAIL_COND(p_blackboard.is_null()); for (const Pair &p : var_list) { if (p_blackboard->has_local_var(p.first) && !overwrite) { +#ifdef DEBUG_ENABLED Variant::Type existing_type = p_blackboard->get_var(p.first).get_type(); Variant::Type planned_type = p.second.get_type(); - if (existing_type != planned_type && existing_type != Variant::NIL && planned_type != Variant::NIL) { + if (existing_type != planned_type && existing_type != Variant::NIL && planned_type != Variant::NIL && !(existing_type == Variant::OBJECT && planned_type == Variant::NODE_PATH)) { WARN_PRINT(vformat("BlackboardPlan: Not overwriting %s as it already exists in the blackboard, but it has a different type than planned (%s vs %s). File: %s", LimboUtility::get_singleton()->decorate_var(p.first), Variant::get_type_name(existing_type), Variant::get_type_name(planned_type), get_path())); } +#endif continue; } bool has_mapping = parent_scope_mapping.has(p.first);