diff --git a/src/edit/include/edit/editor.hpp b/src/edit/include/edit/editor.hpp
index 63725cea286494a504c95a26c5022cd434d36a02..5a91cf6e823f388711ec5915d4e470438ccbce3a 100644
--- a/src/edit/include/edit/editor.hpp
+++ b/src/edit/include/edit/editor.hpp
@@ -77,6 +77,9 @@ public:
     bool &connector_selected;
     bool &primary_axis;
 
+    bool &is_connecting_modules;
+    rofi::cardinal &selected_cardinality;
+    std::pair<connector_ptr, connector_ptr> &selected_connectors;
     bool &is_moving_module;
     glm::vec3 &module_position;
     bool &is_rotating_module;
@@ -87,9 +90,12 @@ public:
     std::string &error_msg;
     double &error_start_second;
 
-    UIData(phase &_editor_phase, mode_I &_editor_mode_I, mode_II &_editor_mode_II, build_mode_I &_editor_build_mode_I, build_mode_II &_editor_build_mode_II, state &_control_state, bool &_ui_visible, 
-           rofi::component &_chosen_component, rofi::connector_type &_chosen_con_type, std::vector<rofi::component> &_allowed_components, std::vector<module_ptr> &_modules, module_ptr &_selected_module,
-           bool &_connector_selected, bool &_voxel_selected, bool &_is_moving_module, glm::vec3 &_module_position, bool &_is_rotating_module, glm::vec3 &_module_rotation_angles, bool &_is_rotating_component, float &_component_rotation_angle,
+    UIData(phase &_editor_phase, mode_I &_editor_mode_I, mode_II &_editor_mode_II, build_mode_I &_editor_build_mode_I, build_mode_II &_editor_build_mode_II, 
+           state &_control_state, bool &_ui_visible, rofi::component &_chosen_component, rofi::connector_type &_chosen_con_type, 
+           std::vector<rofi::component> &_allowed_components, std::vector<module_ptr> &_modules, module_ptr &_selected_module, bool &_is_connecting_modules,
+           rofi::cardinal &_selected_cardinality, std::pair<connector_ptr, connector_ptr> &_selected_connectors, bool &_connector_selected, bool &_voxel_selected, 
+           bool &_is_moving_module, glm::vec3 &_module_position, bool &_is_rotating_module, glm::vec3 &_module_rotation_angles, 
+           bool &_is_rotating_component, float &_component_rotation_angle,
            std::string &_error_msg, double &_error_start_second, bool &_primary_axis)
     :
     editor_phase{_editor_phase},
@@ -104,6 +110,9 @@ public:
     allowed_components{_allowed_components},
     modules{_modules},
     selected_module{_selected_module},
+    is_connecting_modules{_is_connecting_modules},
+    selected_cardinality{_selected_cardinality},
+    selected_connectors{_selected_connectors},
     connector_selected{_connector_selected},
     voxel_selected{_voxel_selected},
     is_moving_module{_is_moving_module},
@@ -158,7 +167,7 @@ class Editor
     char module_type_buffer[256] = {0};
 
     UIData ui = UIData{editor_phase, editor_mode_I, editor_mode_II, editor_build_mode_I, editor_build_mode_II, control_state, ui_visible, 
-                       chosen_component, chosen_con_type, allowed_components, modules, selected_module,
+                       chosen_component, chosen_con_type, allowed_components, modules, selected_module, is_connecting_modules, selected_cardinality, selected_connectors,
                        connector_selected, voxel_selected, is_moving_module, module_position, is_rotating_module, module_rotation_angles, is_rotating_component, component_rotation_angle,
                        error_msg, error_start_second, primary_axis};
 
@@ -191,6 +200,7 @@ class Editor
 
     bool rofi_invalid_state = false;
 
+    rofi::cardinal selected_cardinality = rofi::cardinal::North;
     std::pair<connector_ptr, connector_ptr> selected_connectors = {nullptr, nullptr};
     std::pair<glm::vec3, node_ptr> first_connector_highlights = {glm::vec3(0.0f), nullptr};
     std::pair<glm::vec3, node_ptr> second_connector_highlights = {glm::vec3(0.0f), nullptr};
diff --git a/src/edit/src/editor.cpp b/src/edit/src/editor.cpp
index 4950d4e0465f8b197521b2fd3ace4fe3353da7a6..f078a199fef1a92e7e3c3e9c1a354835c06c8762 100644
--- a/src/edit/src/editor.cpp
+++ b/src/edit/src/editor.cpp
@@ -1077,12 +1077,14 @@ void Editor::setModuleNodeHierarchy(voxel_graph_ptr vg, std::string type)
 
         auto rot_con = std::dynamic_pointer_cast<rofi::RotationConnector>(voxel->getRotationConnector().lock());
         auto [fst, snd] = rot_con->getBoundConnectors();
-        std::vector<node_ptr> connector_nodes = { rot_con->getNode(), fst.lock()->getNode(), snd.lock()->getNode() };
+        auto rot_con_node = rot_con->getNode();
+        std::vector<node_ptr> connector_nodes = { rot_con_node, fst.lock()->getNode(), snd.lock()->getNode() };
+        std::vector<node_ptr> parent_nodes = { voxel_node, rot_con_node, rot_con_node };
 
-        for (auto &connector_node : connector_nodes)
+        for (int i = 0; i < 3; ++i)
         {
-            if (!connector_node->getParent().expired())
-                connector_node->getParent().lock()->transferChild(connector_node, voxel_node, true);
+            if (!connector_nodes[i]->getParent().expired())
+                connector_nodes[i]->getParent().lock()->transferChild(connector_nodes[i], parent_nodes[i], true);
         }
     }
 }
@@ -2147,7 +2149,19 @@ void Editor::controlAddModule()
 
 void Editor::controlConnectModule()
 {
-    is_connecting_modules = keyboard.down().contains("M");
+    if (keyboard.just_pressed().contains("Escape"))
+    {
+        selected_connectors = {nullptr, nullptr};
+        first_connector_highlights = {glm::vec3(0.0f), nullptr};
+        second_connector_highlights = {glm::vec3(0.0f), nullptr};
+        scene->manageSelection(nullptr);
+        scene->manageHighlight(glm::vec3(0.0f), nullptr);
+        scene->manageSecondarySelection({first_connector_highlights.second, second_connector_highlights.second});
+        scene->manageSecondaryHighlights({first_connector_highlights});
+        return;
+    }
+    
+    is_connecting_modules = keyboard.down().contains("M") || is_connecting_modules;
 }
 
 void Editor::controlManipulateModule()
@@ -2468,13 +2482,17 @@ void Editor::teleportModulesByConnectors(const connector_ptr source_connector, c
     auto second_world_pos = destination_connector->getNode()->getPositionWorld();
     auto first_con_parent_diff = first_con_node->getPositionWorld() - first_parent->getPositionWorld();
     first_parent->setPosVec(second_world_pos - first_con_parent_diff);
+
+    // auto destination_facing = -destination_connector->getNode()->getRotationAxisZWorld();
+    // auto source_facing = -first_con_node->getRotationAxisZWorld();
+    
 }
 
 void Editor::rotateModule(module_ptr selected_module, glm::vec3 &rotation_angles)
 {
     if (rotation_angles.x != 0.0f)
     {
-        auto x_rotation = glm::angleAxis(glm::radians(rotation_angles.x),  selected_module->getNode()->getRotationAxisXLocal());
+        auto x_rotation = glm::angleAxis(glm::radians(rotation_angles.x), selected_module->getNode()->getRotationAxisXLocal());
         selected_module->getNode()->rotateRotationQuat(x_rotation);
     }
     if (rotation_angles.y != 0.0f)
diff --git a/src/gui/include/gui/ui.hpp b/src/gui/include/gui/ui.hpp
index b473817804ebd2ffdd8b357a736a6513fd2ab01a..80a66c633878c2f2c1ce3899c310770b270dd65b 100644
--- a/src/gui/include/gui/ui.hpp
+++ b/src/gui/include/gui/ui.hpp
@@ -43,6 +43,7 @@ void build_toolbar_ui(const osi::Window &window, edit::UIData &data);
 void build_toolbar_buttons(edit::UIData &data);
 void set_build_toolbar_button_colors(edit::UIData &data);
 void module_selection_ui(const osi::Window &window, edit::UIData &data);
+void module_connection_ui(const osi::Window &window, edit::UIData &data);
 void module_movement_ui(const osi::Window &window, edit::UIData &data);
 void module_rotation_ui(const osi::Window &window, edit::UIData &data);
 void component_rotation_ui(const osi::Window &window, edit::UIData &data);
diff --git a/src/gui/src/ui.cpp b/src/gui/src/ui.cpp
index f0d9e6847d354b1b100be2a602572753ba41d312..95cc0861bb644d35bdb04645faff2ab71627bcee 100644
--- a/src/gui/src/ui.cpp
+++ b/src/gui/src/ui.cpp
@@ -242,6 +242,7 @@ void mode_II_build_ui(const osi::Window &window, edit::UIData &data)
 {
     mode_II_build_selection_ui(window, data);
     module_selection_ui(window, data);
+    module_connection_ui(window, data);
     module_movement_ui(window, data);
     module_rotation_ui(window, data);
     component_rotation_ui(window, data);
@@ -511,6 +512,73 @@ void module_selection_ui(const osi::Window &window, edit::UIData &data)
     ImGui::End();
 }
 
+void module_connection_ui(const osi::Window &window, edit::UIData &data)
+{
+    using namespace rofi;
+    if (data.editor_build_mode_II != edit::build_mode_II::connect_module 
+        || data.selected_connectors.first == nullptr 
+        || data.selected_connectors.second == nullptr)
+    {
+        data.is_connecting_modules = false;
+        return;
+    }
+
+    auto fst_connector = data.selected_connectors.first;
+    auto snd_connector = data.selected_connectors.second;
+
+    float size_x = static_cast<float>(window.size().x);
+    float size_y = static_cast<float>(window.size().y);
+    ImGui::SetNextWindowPos(ImVec2(size_x, size_y - 40.0f), ImGuiCond_Always, ImVec2(1.0f, 1.0f));
+
+    ImGui::Begin("Connect##ModuleConnectionMenu", NULL, ImGuiWindowFlags_NoMove 
+                                                              | ImGuiWindowFlags_NoResize 
+                                                              | ImGuiWindowFlags_NoCollapse 
+                                                              | ImGuiWindowFlags_AlwaysAutoResize);
+
+    using enum cardinal;
+    
+    if (Connector::shares_module_link(fst_connector, snd_connector))
+    {
+        ImGui::Text("Mutual Orientation:");
+        std::string orientation;
+        switch(Connector::get_mutual_orientation(fst_connector, snd_connector))
+        {
+            case North: 
+                orientation = "North";
+                break;
+            case East:  
+                orientation = "East";
+                break;
+            case South:  
+                orientation = "South";
+                break;
+            case West:  
+                orientation = "West";
+                break;
+        }
+        ImGui::Text(orientation.c_str());
+        ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.0f, 0.0f, 1.0f));
+        data.is_connecting_modules = ImGui::Button("Disconnect");
+        ImGui::PopStyleColor();
+    }
+    else
+    {
+        int selection = static_cast<int>(data.selected_cardinality);
+        ImGui::RadioButton("North", &selection, 0);                       
+        ImGui::RadioButton("East", &selection, 1);                       
+        ImGui::RadioButton("South", &selection, 2);                       
+        ImGui::RadioButton("West", &selection, 3);
+        data.selected_cardinality = selection == 0 ? North : selection == 1 ? East : selection == 2 ? South : West;
+        
+        ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.7f, 1.0f));
+        data.is_connecting_modules = ImGui::Button("Connect");
+        ImGui::PopStyleColor();
+    }
+
+
+    ImGui::End();
+}
+
 void module_movement_ui(const osi::Window &window, edit::UIData &data)
 {
     if (data.editor_build_mode_II != edit::build_mode_II::manipulate_module || !data.selected_module)
diff --git a/src/rofi/include/rofi/connector.hpp b/src/rofi/include/rofi/connector.hpp
index 0b1c171d1b93afc03fdc7e18773c89d15b3de1e2..13cc8315a323d3022f0a6fdae475a41b1bdee601 100644
--- a/src/rofi/include/rofi/connector.hpp
+++ b/src/rofi/include/rofi/connector.hpp
@@ -19,6 +19,7 @@ using connector_weak_ptr = std::weak_ptr<rofi::Connector>;
 
     enum class side { x_pos, x_neg, y_pos, y_neg, z_pos, z_neg, undefined };
     enum class connector_type {fixed, open, rotation, shared_rotation, empty};
+    enum cardinal { North, East, South, West };
 
 class Connector : public ObjectBase
 {
@@ -46,6 +47,7 @@ public:
 
     static connector_ptr copy(connector_ptr other_connector);
     static bool shares_module_link(connector_ptr fst_connector, connector_ptr snd_connector);
+    static cardinal get_mutual_orientation(connector_ptr fst_connector, connector_ptr snd_connector);
 
     bool isFull() const { return !connection.first.expired() && !connection.second.expired(); }
     bool isEmpty() const { return connection.first.expired() && connection.second.expired(); }
diff --git a/src/rofi/include/rofi/rofiworld.hpp b/src/rofi/include/rofi/rofiworld.hpp
index 03ad704b6040d7a40491dd87a34d14a63e783b63..ba1ac0a34f0875d0326bb91c2c35af165c582d13 100644
--- a/src/rofi/include/rofi/rofiworld.hpp
+++ b/src/rofi/include/rofi/rofiworld.hpp
@@ -13,6 +13,8 @@
 namespace rofi
 {
 
+enum class slot { ApX, AnX, AnZ, BpX, BnX, BnZ };
+
 class RofiWorld
 {
     std::string name;
diff --git a/src/rofi/src/connector.cpp b/src/rofi/src/connector.cpp
index 2b02920d3c431b05ca0b13062e02e6bea8483ec5..bf78a040a6f8970611b7d3766201708a15df8bc0 100644
--- a/src/rofi/src/connector.cpp
+++ b/src/rofi/src/connector.cpp
@@ -2,6 +2,8 @@
 
 #include <rofi/voxel.hpp>
 
+#include <iostream>
+
 namespace rofi
 {
 
@@ -75,6 +77,29 @@ bool Connector::shares_module_link(connector_ptr fst_connector, connector_ptr sn
     return false;
 }
 
+cardinal Connector::get_mutual_orientation(connector_ptr fst_connector, connector_ptr snd_connector)
+{
+    auto fst_north = fst_connector->getNode()->getRotationAxisXWorld();
+    auto snd_north = snd_connector->getNode()->getRotationAxisXWorld();
+    auto oriented_angle = glm::degrees(glm::orientedAngle(fst_north, 
+                                                          snd_north, 
+                                                          fst_connector->getNode()->getRotationAxisZWorld()));
+
+    std::cout << "oriented angle: " << oriented_angle << std::endl;
+
+    float epsilon = 0.001f;
+    if (glm::epsilonEqual(oriented_angle, 0.0f, epsilon))
+        return North;
+    if (glm::epsilonEqual(oriented_angle, -90.0f, epsilon))
+        return East;
+    if (glm::epsilonEqual(oriented_angle, 180.0f, epsilon))
+        return South;
+    if (glm::epsilonEqual(oriented_angle, 90.0f, epsilon))
+        return West;
+
+    ASSUMPTION(false);    
+}
+
 bool Connector::hasModuleLink() const
 { 
     return (!connection.first.expired() && std::dynamic_pointer_cast<ModuleLink>(connection.first.lock()))
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index cb3ca9a43c0fba6cd2e70398aca25e74e9baeb24..b458edc78f80f95b2cfeb871452840ae4934bf51 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -38,8 +38,7 @@ void Simulator::update()
 
 void Simulator::present()
 {
-    /* Present the state to the user (i.e., render objects)
-     * For now, we just clear screen buffers and show some gui widget. */
+    /* Present the state to the user (i.e., render objects) */
 
     show_ui(window(), editor->getUIData());
     show_edit_error_msg(window(), editor->getUIData(), timer().passed_seconds());