From 99ad06d2ae718f7f651982b908576f2b6b443a62 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 14 Oct 2025 22:00:32 +0200 Subject: [PATCH 01/10] fix: ydi::client::status now checks initialisation --- modules/you_done_it/ydi_client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/you_done_it/ydi_client.cpp b/modules/you_done_it/ydi_client.cpp index 96b9a474..be03ffc2 100644 --- a/modules/you_done_it/ydi_client.cpp +++ b/modules/you_done_it/ydi_client.cpp @@ -132,7 +132,7 @@ void disconnect() { } NetworkData::ConnectionStatus status() { - return connection->status; + return connection ? NetworkData::ConnectionStatus(connection->status) : NetworkData::CONNECTION_DISCONNECTED; } namespace send { From 4cb2b334abdc5b7933a5e7c71f6a551c0461ec71 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 14 Oct 2025 22:46:20 +0200 Subject: [PATCH 02/10] feat: added VROrigin node --- modules/you_done_it/register_types.cpp | 2 ++ modules/you_done_it/ydi_vr_origin.cpp | 43 ++++++++++++++++++++++++++ modules/you_done_it/ydi_vr_origin.h | 17 ++++++++++ vr-project/project.godot | 1 + vr-project/scenes/game_scene.tscn | 6 ++-- vr-project/vr_base.tscn | 16 ++++++++-- 6 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 modules/you_done_it/ydi_vr_origin.cpp create mode 100644 modules/you_done_it/ydi_vr_origin.h diff --git a/modules/you_done_it/register_types.cpp b/modules/you_done_it/register_types.cpp index 74139d10..1215f5aa 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -3,6 +3,7 @@ #include "client_node.h" #include "server_node.h" #include "ydi_networking.h" +#include "ydi_vr_origin.h" #include void initialize_you_done_it_module(ModuleInitializationLevel p_level) { @@ -12,6 +13,7 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_abstract_class(); + ClassDB::register_class(); } void uninitialize_you_done_it_module(ModuleInitializationLevel p_level) { diff --git a/modules/you_done_it/ydi_vr_origin.cpp b/modules/you_done_it/ydi_vr_origin.cpp new file mode 100644 index 00000000..89b4e049 --- /dev/null +++ b/modules/you_done_it/ydi_vr_origin.cpp @@ -0,0 +1,43 @@ +#include "ydi_vr_origin.h" +#include +#include +#include +#include + +void VROrigin::_bind_methods() {} + +void VROrigin::start_vr(Ref with_interface) { + if (with_interface.is_valid()) { + DisplayServer::get_singleton()->window_set_vsync_mode(DisplayServer::VSYNC_DISABLED); + get_viewport()->set_use_xr(true); + } +} + +void VROrigin::on_xr_interface_added(StringName interface) { + if (interface == "OpenXR") { + start_vr(XRServer::get_singleton()->find_interface(interface)); + XRServer::get_singleton()->disconnect("interface_added", callable_mp(this, &self_type::on_xr_interface_added)); + } +} + +void VROrigin::enter_tree() { + Ref xrint{ XRServer::get_singleton()->find_interface("OpenXR") }; + if (xrint.is_valid()) { + start_vr(xrint); + } else { + XRServer::get_singleton()->connect("interface_added", callable_mp(this, &self_type::on_xr_interface_added)); + } +} + +void VROrigin::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + case NOTIFICATION_ENTER_TREE: + enter_tree(); + return; + default: + return; + } +} diff --git a/modules/you_done_it/ydi_vr_origin.h b/modules/you_done_it/ydi_vr_origin.h new file mode 100644 index 00000000..8822177a --- /dev/null +++ b/modules/you_done_it/ydi_vr_origin.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +class VROrigin : public XROrigin3D { + GDCLASS(VROrigin, XROrigin3D); + static void _bind_methods(); + +private: + void start_vr(Ref with_interface); + void on_xr_interface_added(StringName interface); + void enter_tree(); + +protected: + void _notification(int what); +}; diff --git a/vr-project/project.godot b/vr-project/project.godot index 019bfa99..c658dcf8 100644 --- a/vr-project/project.godot +++ b/vr-project/project.godot @@ -11,6 +11,7 @@ config_version=5 [application] config/name="you_done_it" +run/main_scene="uid://b5m5h30gog3pu" config/features=PackedStringArray("4.5", "Forward Plus") config/icon="res://icon.svg" diff --git a/vr-project/scenes/game_scene.tscn b/vr-project/scenes/game_scene.tscn index 834e2643..f085aa61 100644 --- a/vr-project/scenes/game_scene.tscn +++ b/vr-project/scenes/game_scene.tscn @@ -28,6 +28,9 @@ glow_enabled = true [node name="Root" type="Node3D"] +[node name="VROrigin" parent="." instance=ExtResource("2_onqr8")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0004169941, 0, -0.95417106) + [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_bw6k5") @@ -48,8 +51,5 @@ directional_shadow_mode = 0 directional_shadow_fade_start = 0.965 directional_shadow_max_distance = 20.0 -[node name="XROrigin3D" parent="." instance=ExtResource("2_onqr8")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0004169941, 0, -0.95417106) - [node name="Block Out VR" parent="." instance=ExtResource("1_w5aja")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.27989578, 0, 1.4924412) diff --git a/vr-project/vr_base.tscn b/vr-project/vr_base.tscn index 82a64dc7..f317419c 100644 --- a/vr-project/vr_base.tscn +++ b/vr-project/vr_base.tscn @@ -1,13 +1,25 @@ -[gd_scene format=3 uid="uid://ctf3dsro4aqon"] +[gd_scene load_steps=2 format=3 uid="uid://ctf3dsro4aqon"] -[node name="XROrigin3D" type="XROrigin3D"] +[sub_resource type="CylinderMesh" id="CylinderMesh_y71p3"] +top_radius = 0.05 +bottom_radius = 0.05 +height = 0.05 + +[node name="VROrigin" type="VROrigin"] [node name="XRCamera3D" type="XRCamera3D" parent="."] +current = true [node name="LeftController" type="XRController3D" parent="."] tracker = &"left_hand" +[node name="MeshInstance3D" type="MeshInstance3D" parent="LeftController"] +mesh = SubResource("CylinderMesh_y71p3") + [node name="RightController" type="XRController3D" parent="."] tracker = &"right_hand" +[node name="MeshInstance3D" type="MeshInstance3D" parent="RightController"] +mesh = SubResource("CylinderMesh_y71p3") + [node name="ClientNode" type="ClientNode" parent="."] From dfe8cc9fcf2b0b6e2b3925177ee98ea67d0023ae Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 11:11:01 +0200 Subject: [PATCH 03/10] chore: renamed start_vr to setup_vr_interface --- modules/you_done_it/ydi_vr_origin.cpp | 6 +++--- modules/you_done_it/ydi_vr_origin.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/you_done_it/ydi_vr_origin.cpp b/modules/you_done_it/ydi_vr_origin.cpp index 89b4e049..86d31561 100644 --- a/modules/you_done_it/ydi_vr_origin.cpp +++ b/modules/you_done_it/ydi_vr_origin.cpp @@ -6,7 +6,7 @@ void VROrigin::_bind_methods() {} -void VROrigin::start_vr(Ref with_interface) { +void VROrigin::setup_vr_interface(Ref with_interface) { if (with_interface.is_valid()) { DisplayServer::get_singleton()->window_set_vsync_mode(DisplayServer::VSYNC_DISABLED); get_viewport()->set_use_xr(true); @@ -15,7 +15,7 @@ void VROrigin::start_vr(Ref with_interface) { void VROrigin::on_xr_interface_added(StringName interface) { if (interface == "OpenXR") { - start_vr(XRServer::get_singleton()->find_interface(interface)); + setup_vr_interface(XRServer::get_singleton()->find_interface(interface)); XRServer::get_singleton()->disconnect("interface_added", callable_mp(this, &self_type::on_xr_interface_added)); } } @@ -23,7 +23,7 @@ void VROrigin::on_xr_interface_added(StringName interface) { void VROrigin::enter_tree() { Ref xrint{ XRServer::get_singleton()->find_interface("OpenXR") }; if (xrint.is_valid()) { - start_vr(xrint); + setup_vr_interface(xrint); } else { XRServer::get_singleton()->connect("interface_added", callable_mp(this, &self_type::on_xr_interface_added)); } diff --git a/modules/you_done_it/ydi_vr_origin.h b/modules/you_done_it/ydi_vr_origin.h index 8822177a..75879f26 100644 --- a/modules/you_done_it/ydi_vr_origin.h +++ b/modules/you_done_it/ydi_vr_origin.h @@ -8,7 +8,7 @@ class VROrigin : public XROrigin3D { static void _bind_methods(); private: - void start_vr(Ref with_interface); + void setup_vr_interface(Ref with_interface); void on_xr_interface_added(StringName interface); void enter_tree(); From 855970b4e533556aaf5799ca3641bcea4648d2ac Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 22:53:44 +0200 Subject: [PATCH 04/10] feat: improved networkdata enum integration --- modules/you_done_it/ydi_networking.cpp | 3 -- modules/you_done_it/ydi_networking.h | 54 +++++++++++++++----------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/modules/you_done_it/ydi_networking.cpp b/modules/you_done_it/ydi_networking.cpp index 465bce8d..901326b0 100644 --- a/modules/you_done_it/ydi_networking.cpp +++ b/modules/you_done_it/ydi_networking.cpp @@ -3,9 +3,6 @@ #include #include -MAKE_TYPE_INFO(NetworkData::ClueID, Variant::INT); -MAKE_TYPE_INFO(NetworkData::ConnectionStatus, Variant::INT); - void NetworkData::_bind_methods() { BIND_ENUM_CONSTANT(CLUE_FIRST); BIND_ENUM_CONSTANT(CLUE_SECOND); diff --git a/modules/you_done_it/ydi_networking.h b/modules/you_done_it/ydi_networking.h index f922f0bf..fcb16394 100644 --- a/modules/you_done_it/ydi_networking.h +++ b/modules/you_done_it/ydi_networking.h @@ -8,36 +8,41 @@ #include #include +#define __VA_ARGS__STRING(...) String(#__VA_ARGS__) + +#define GDENUM(M_Name, ...) \ + enum M_Name { __VA_ARGS__ }; \ + static String M_Name##_hint() { \ + return __VA_ARGS__STRING(__VA_ARGS__); \ + } + class NetworkData : Object { GDCLASS(NetworkData, Object); static void _bind_methods(); public: - enum MessageType { - MSG_NONE = 0u, - // connection management messages - MSG_CONNECT = 1u, - MSG_OK, - MSG_NOK, - MSG_HEART, - MSG_BEAT, - // gameplay messages - MSG_REVEAL, - // end of messages - MSG_INVALID - }; + GDENUM(MessageType, + MSG_NONE, + // connection management messages + MSG_CONNECT, + MSG_OK, + MSG_NOK, + MSG_HEART, + MSG_BEAT, + // gameplay messages + MSG_REVEAL, + // end of messages + MSG_INVALID); - enum ClueID { - CLUE_FIRST, - CLUE_SECOND, - CLUE_MAX - }; + GDENUM(ClueID, + CLUE_FIRST, + CLUE_SECOND, + CLUE_MAX); - enum ConnectionStatus { - CONNECTION_DISCONNECTED, - CONNECTION_CONNECTED, - CONNECTION_AUTHENTICATED - }; + GDENUM(ConnectionStatus, + CONNECTION_DISCONNECTED, + CONNECTION_CONNECTED, + CONNECTION_AUTHENTICATED); enum NOKReason { NOK_UNAUTHENTICATED, //!< message sender is not known by recipient. @@ -48,6 +53,9 @@ public: }; }; +MAKE_TYPE_INFO(NetworkData::ClueID, Variant::INT); +MAKE_TYPE_INFO(NetworkData::ConnectionStatus, Variant::INT); + namespace ydi { int to_int(zmq::message_t const &msg, int failure = 0); NetworkData::MessageType to_message_type(zmq::message_t const &msg); From 380a13e904ada1da6cba545e3c16b560a9f4b2c7 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 22:54:16 +0200 Subject: [PATCH 05/10] feat: added ClueMarker and ClueFinder --- modules/you_done_it/clue_finder.cpp | 52 ++++++++++++++++++++++++++ modules/you_done_it/clue_finder.h | 24 ++++++++++++ modules/you_done_it/clue_marker.cpp | 34 +++++++++++++++++ modules/you_done_it/clue_marker.h | 17 +++++++++ modules/you_done_it/register_types.cpp | 4 ++ 5 files changed, 131 insertions(+) create mode 100644 modules/you_done_it/clue_finder.cpp create mode 100644 modules/you_done_it/clue_finder.h create mode 100644 modules/you_done_it/clue_marker.cpp create mode 100644 modules/you_done_it/clue_marker.h diff --git a/modules/you_done_it/clue_finder.cpp b/modules/you_done_it/clue_finder.cpp new file mode 100644 index 00000000..ccc0f73e --- /dev/null +++ b/modules/you_done_it/clue_finder.cpp @@ -0,0 +1,52 @@ +#include "clue_finder.h" +#include "scene/main/node.h" +#include + +ClueFinder *ClueFinder::singleton_instance{ nullptr }; + +void ClueFinder::_bind_methods() {} + +void ClueFinder::enter_tree() { + if (singleton_instance == nullptr) { + singleton_instance = this; + } +} + +void ClueFinder::exit_tree() { + if (singleton_instance == this) { + singleton_instance = nullptr; + } +} + +void ClueFinder::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + case NOTIFICATION_ENTER_TREE: + enter_tree(); + return; + case NOTIFICATION_EXIT_TREE: + exit_tree(); + return; + default: + return; + } +} + +ClueFinder *ClueFinder::get_singleton() { + return singleton_instance; +} + +ClueMarker *ClueFinder::find_current_clue() { + for (ClueMarker *marker : this->clue_markers) { + if (marker->is_visible()) { + return marker; + } + } + return nullptr; +} + +void ClueFinder::register_clue_marker(ClueMarker *marker) { + this->clue_markers.insert(marker); +} diff --git a/modules/you_done_it/clue_finder.h b/modules/you_done_it/clue_finder.h new file mode 100644 index 00000000..b33dc2b2 --- /dev/null +++ b/modules/you_done_it/clue_finder.h @@ -0,0 +1,24 @@ +#pragma once + +#include "clue_marker.h" +#include +#include + +class ClueFinder : public Node3D { + GDCLASS(ClueFinder, Node3D); + static void _bind_methods(); + static ClueFinder *singleton_instance; + void enter_tree(); + void exit_tree(); + +protected: + void _notification(int what); + +public: + static ClueFinder *get_singleton(); + ClueMarker *find_current_clue(); + void register_clue_marker(ClueMarker *marker); + +private: + HashSet clue_markers{}; +}; diff --git a/modules/you_done_it/clue_marker.cpp b/modules/you_done_it/clue_marker.cpp new file mode 100644 index 00000000..c8201423 --- /dev/null +++ b/modules/you_done_it/clue_marker.cpp @@ -0,0 +1,34 @@ +#include "clue_marker.h" +#include "macros.h" +#include "you_done_it/clue_finder.h" +#include "you_done_it/ydi_networking.h" + +void ClueMarker::_bind_methods() { + BIND_HPROPERTY(Variant::INT, clue_id, PROPERTY_HINT_ENUM, NetworkData::ClueID_hint()); +} + +bool ClueMarker::is_visible() const { + Transform3D const viewpoint{ ClueFinder::get_singleton()->get_global_transform() }; + Basis const basis{ viewpoint.get_basis() }; + Vector3 const pos_relative{ get_global_position() - viewpoint.get_origin() }; + Vector3 const pos_transformed{ basis.get_column(0).dot(pos_relative), basis.get_column(1).dot(pos_relative), basis.get_column(2).dot(pos_relative) }; + if (pos_transformed.z <= 0.5f) { + return false; + } + Vector3 const transformed_dir{ pos_transformed.normalized() }; + if (Math::abs(transformed_dir.signed_angle_to({ 0, 0, 1 }, { 0, 1, 0 })) > Math::PI / 4.0) { + return false; + } + if (Math::abs(transformed_dir.signed_angle_to({ 0, 0, 1 }, { 1, 0, 0 })) > Math::PI / 4.0) { + return false; + } + return true; +} + +void ClueMarker::set_clue_id(NetworkData::ClueID id) { + this->id = id; +} + +NetworkData::ClueID ClueMarker::get_clue_id() const { + return this->id; +} diff --git a/modules/you_done_it/clue_marker.h b/modules/you_done_it/clue_marker.h new file mode 100644 index 00000000..1494397a --- /dev/null +++ b/modules/you_done_it/clue_marker.h @@ -0,0 +1,17 @@ +#pragma once + +#include "ydi_networking.h" +#include + +class ClueMarker : public Node3D { + GDCLASS(ClueMarker, Node3D); + static void _bind_methods(); + +public: + bool is_visible() const; + void set_clue_id(NetworkData::ClueID id); + NetworkData::ClueID get_clue_id() const; + +private: + NetworkData::ClueID id{ NetworkData::CLUE_MAX }; +}; diff --git a/modules/you_done_it/register_types.cpp b/modules/you_done_it/register_types.cpp index 1215f5aa..fe1ed098 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -1,9 +1,11 @@ #include "register_types.h" #include "client_node.h" +#include "clue_marker.h" #include "server_node.h" #include "ydi_networking.h" #include "ydi_vr_origin.h" +#include "you_done_it/clue_finder.h" #include void initialize_you_done_it_module(ModuleInitializationLevel p_level) { @@ -14,6 +16,8 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_abstract_class(); ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); } void uninitialize_you_done_it_module(ModuleInitializationLevel p_level) { From a050913c30171f593bc981c833e82fcc68c894cd Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 22:55:03 +0200 Subject: [PATCH 06/10] fix: artefacts in light/shadow rendering --- vr-project/scenes/game_scene.tscn | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vr-project/scenes/game_scene.tscn b/vr-project/scenes/game_scene.tscn index f085aa61..538131c5 100644 --- a/vr-project/scenes/game_scene.tscn +++ b/vr-project/scenes/game_scene.tscn @@ -44,12 +44,13 @@ light_angular_distance = 1.0 light_specular = 5.667 light_bake_mode = 1 shadow_enabled = true -shadow_bias = 0.0 -shadow_normal_bias = 0.0 +shadow_normal_bias = 0.1 shadow_blur = 0.75 -directional_shadow_mode = 0 directional_shadow_fade_start = 0.965 directional_shadow_max_distance = 20.0 [node name="Block Out VR" parent="." instance=ExtResource("1_w5aja")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.27989578, 0, 1.4924412) + +[node name="ClueMarker" type="ClueMarker" parent="."] +clue_id = 0 From 7917edb4d0f5fc2633ce1155966e384a39978078 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 22:57:47 +0200 Subject: [PATCH 07/10] chore: moved GDENUM and __VA_ARGS__STRING to macros.h --- modules/you_done_it/macros.h | 8 ++++++++ modules/you_done_it/ydi_networking.h | 9 +-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/you_done_it/macros.h b/modules/you_done_it/macros.h index 53be3185..1a882c6b 100644 --- a/modules/you_done_it/macros.h +++ b/modules/you_done_it/macros.h @@ -17,4 +17,12 @@ ADD_PROPERTY(PropertyInfo(m_type, #m_property), "set_" #m_property, \ "get_" #m_property) +#define __VA_ARGS__STRING(...) String(#__VA_ARGS__) + +#define GDENUM(M_Name, ...) \ + enum M_Name { __VA_ARGS__ }; \ + static String M_Name##_hint() { \ + return __VA_ARGS__STRING(__VA_ARGS__); \ + } + #endif // !GODOT_EXTRA_MACROS_H diff --git a/modules/you_done_it/ydi_networking.h b/modules/you_done_it/ydi_networking.h index fcb16394..5c5a16dd 100644 --- a/modules/you_done_it/ydi_networking.h +++ b/modules/you_done_it/ydi_networking.h @@ -1,5 +1,6 @@ #pragma once +#include "macros.h" #include #include #include @@ -8,14 +9,6 @@ #include #include -#define __VA_ARGS__STRING(...) String(#__VA_ARGS__) - -#define GDENUM(M_Name, ...) \ - enum M_Name { __VA_ARGS__ }; \ - static String M_Name##_hint() { \ - return __VA_ARGS__STRING(__VA_ARGS__); \ - } - class NetworkData : Object { GDCLASS(NetworkData, Object); static void _bind_methods(); From e60cbb94b69c767e389c0545f53b4b4df6bf7f9d Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 15 Oct 2025 23:12:09 +0200 Subject: [PATCH 08/10] chore: clarified name of extend_multipart_recurse --- modules/you_done_it/ydi_networking.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/you_done_it/ydi_networking.h b/modules/you_done_it/ydi_networking.h index 5c5a16dd..b3d9ab44 100644 --- a/modules/you_done_it/ydi_networking.h +++ b/modules/you_done_it/ydi_networking.h @@ -65,19 +65,20 @@ void extend_multipart(zmq::multipart_t &mpart, std::string_view const &strv); void extend_multipart(zmq::multipart_t &mpart, char const *cstr); void extend_multipart(zmq::multipart_t &mpart, int const &arg); void extend_multipart(zmq::multipart_t &mpart, zmq::multipart_t const &right); -void extend_multipart(zmq::multipart_t &mpart); void extend_multipart(zmq::multipart_t &mpart, std::pair range); void extend_multipart(zmq::multipart_t &mpart, std::pair range); +void extend_multipart(zmq::multipart_t &mpart); + template -void extend_multipart_r(zmq::multipart_t &mpart, TArg const &arg) { +void extend_multipart_recurse(zmq::multipart_t &mpart, TArg const &arg) { extend_multipart(mpart, arg); } template -void extend_multipart_r(zmq::multipart_t &mpart, TArg const &arg, TArgs const &...args) { +void extend_multipart_recurse(zmq::multipart_t &mpart, TArg const &arg, TArgs const &...args) { extend_multipart(mpart, arg); - extend_multipart_r(mpart, args...); + extend_multipart_recurse(mpart, args...); } template @@ -90,7 +91,7 @@ zmq::multipart_t multipart(TArg const &arg) { template zmq::multipart_t multipart(TArg const &arg, TArgs const &...args) { zmq::multipart_t mpart{ multipart(arg) }; - extend_multipart_r(mpart, args...); + extend_multipart_recurse(mpart, args...); return mpart; } } //namespace ydi From 2710ae78c20a559da38e35bbc98cdde526294a52 Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 16 Oct 2025 14:25:38 +0200 Subject: [PATCH 09/10] fix: ClueFinder now deallocates if not singleton --- modules/you_done_it/clue_finder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/you_done_it/clue_finder.cpp b/modules/you_done_it/clue_finder.cpp index ccc0f73e..50afb267 100644 --- a/modules/you_done_it/clue_finder.cpp +++ b/modules/you_done_it/clue_finder.cpp @@ -9,6 +9,8 @@ void ClueFinder::_bind_methods() {} void ClueFinder::enter_tree() { if (singleton_instance == nullptr) { singleton_instance = this; + } else { + queue_free(); } } From 8aa6bd774058b8a6002f838b2a2cb10d27ad9869 Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 16 Oct 2025 22:46:47 +0200 Subject: [PATCH 10/10] fix: singleton behaviour in ClientNode and ServerNode --- modules/you_done_it/client_node.cpp | 2 ++ modules/you_done_it/server_node.cpp | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/you_done_it/client_node.cpp b/modules/you_done_it/client_node.cpp index 64516447..d131f88b 100644 --- a/modules/you_done_it/client_node.cpp +++ b/modules/you_done_it/client_node.cpp @@ -13,6 +13,8 @@ void ClientNode::enter_tree() { if (singleton_instance) { print_error("Attempt to create duplicate ClientNode, aborting"); abort(); + } else { + singleton_instance = this; } } diff --git a/modules/you_done_it/server_node.cpp b/modules/you_done_it/server_node.cpp index f56fbf65..02a16de7 100644 --- a/modules/you_done_it/server_node.cpp +++ b/modules/you_done_it/server_node.cpp @@ -17,9 +17,10 @@ void ServerNode::enter_tree() { if (singleton_instance) { print_error("Attempt to create duplicate ServerNode, aborting"); abort(); + } else { + singleton_instance = this; + ydi::server::open(); } - singleton_instance = this; - ydi::server::open(); } void ServerNode::process(double delta) {