diff --git a/src/algo/src/misc.cpp b/src/algo/src/misc.cpp
index 09b372e33bc3b962be16e2e8acbb70278414ab7a..6f439169a4c72a67d2c65e778d88d7ce920d00d4 100644
--- a/src/algo/src/misc.cpp
+++ b/src/algo/src/misc.cpp
@@ -46,13 +46,16 @@ node_ptr find_node_with_rofi_object(const std::vector<node_ptr> &nodes, objectba
 glm::quat get_connector_face_rotation(glm::vec3 local_direction)
 {
     ASSUMPTION(glm::length(local_direction) == 1.0f);
+    // if (rofi::vec_to_enum(local_direction) == rofi::side::z_neg)
+    //     return glm::angleAxis(glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));
+
     return glm::rotation(rofi::enum_to_vec(rofi::side::z_neg), local_direction);
 }
 
 glm::quat get_shared_voxel_face_rotation(glm::vec3 local_direction)
 {
     ASSUMPTION(glm::length(local_direction) == 1.0f);
-    return glm::rotation(rofi::enum_to_vec(rofi::side::z_neg), -local_direction);
+    return glm::rotation(rofi::enum_to_vec(rofi::side::z_neg), -local_direction); //* glm::angleAxis(glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));
 }
 
 bool face_each_other(node_ptr fst_node, node_ptr snd_node, glm::vec3 axis)
diff --git a/src/edit/src/scene.cpp b/src/edit/src/scene.cpp
index e95213acf00295090a1e3741d687ecf9e1b2a0e1..d4bd16094bf71dd40aff4f838ba238ad4833e929 100644
--- a/src/edit/src/scene.cpp
+++ b/src/edit/src/scene.cpp
@@ -85,7 +85,7 @@ void Scene::createScene()
 
     /* ADD CAMERA */
     auto camera_node = addCameraNode(60.0f, glm::vec3(0.0f, 0.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f));
-    auto rot = glm::angleAxis(glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f));
+    auto rot = glm::angleAxis(glm::radians(-45.0f), glm::vec3(0.0f, 1.0f, 0.0f));
     camera_node->translatePosVec(glm::toMat4(rot));
     camera_node->rotateRotationQuat(rot);
     auto rot2 = glm::angleAxis(glm::radians(-20.0f), camera_node->getRotationAxisXLocal());
diff --git a/src/rofi/include/rofi/module.hpp b/src/rofi/include/rofi/module.hpp
index 34bcd433faca915078d329f1d3670053ab1d7c3a..028dcdb6b9b1f4b689bd28309ab870699e1637b3 100644
--- a/src/rofi/include/rofi/module.hpp
+++ b/src/rofi/include/rofi/module.hpp
@@ -23,9 +23,13 @@ class Module
     std::string name;
     std::string type;
 
+    // uint64_t module_id;
     std::map<uint64_t, objectbase_ptr> component_ids;
 
+    std::map<connector_ptr, std::string> connector_docks;
+
     void makeNodeTree();
+    void setConnectorDocks();
 
     Module(const Module &other);
     Module(const Module &&other);
@@ -45,6 +49,11 @@ public:
 
     const std::string &getName() const { return name; }
     const std::string &getType() const { return type; }
+
+    const std::map<uint64_t, objectbase_ptr> &getComponentIDs() const { return component_ids; }
+    const std::map<connector_ptr, std::string> &getConnectorDocks() const { return connector_docks; }
+    const objectbase_ptr &getComponentByID(uint64_t id) const { return component_ids.at(id); }
+    const std::string &getConnectorDock(connector_ptr connector) const { return connector_docks.at(connector); }
 };
 
 }
diff --git a/src/rofi/src/module.cpp b/src/rofi/src/module.cpp
index 8638145648cc4c47d94961989235336fce227f15..6c6099e461032f663a2a52fd88e88fc64048eda3 100644
--- a/src/rofi/src/module.cpp
+++ b/src/rofi/src/module.cpp
@@ -11,6 +11,40 @@ void Module::makeNodeTree()
         node->addChild(connector->getNode());
 }
 
+void Module::setConnectorDocks() // TO DO: change if connector placement gets changed
+{
+    if (type != "universal")
+        return;
+
+    using enum side;
+    std::string dock;
+    auto a_pos = glm::vec3(0.0f);
+
+    for (const auto &connector : parts->getConnections())
+    {
+        if (connector->getType(false) == connector_type::shared_rotation)
+            continue;
+
+        auto con_side = connector->getVoxelSide().first;
+        auto voxel_pos = connector->getConnection().first.lock()->getNode()->getPositionLocal();
+        switch(con_side)
+        {
+            case x_neg:
+                dock = voxel_pos == a_pos ? "A+X" : "B+X";
+                break;
+            case x_pos:
+                dock = voxel_pos == a_pos ? "A-X" : "B-X";
+                break;
+            case z_neg:
+                dock = voxel_pos == a_pos ? "A-Z" : "B-Z";
+                break;
+            default:
+                ASSUMPTION(false);
+        }
+        connector_docks.emplace(connector, dock);
+    }
+}
+
 Module::Module(const Module &other)
 {
     node = Node::copy_deep(other.node);
@@ -18,6 +52,7 @@ Module::Module(const Module &other)
     name = other.name;
     type = other.type;
     component_ids = other.component_ids;
+    setConnectorDocks();
 }
 Module::Module(const Module &&other)
 {
@@ -26,6 +61,7 @@ Module::Module(const Module &&other)
     name = std::move(other.name);
     type = std::move(other.type);
     component_ids = std::move(other.component_ids);
+    setConnectorDocks();
 }
 Module& Module::operator=(const Module &other)
 {
@@ -34,6 +70,7 @@ Module& Module::operator=(const Module &other)
     name = other.name;
     type = other.type;
     component_ids = other.component_ids;
+    setConnectorDocks();
 
     return *this;
 }
@@ -44,6 +81,7 @@ Module& Module::operator=(const Module &&other)
     name = std::move(other.name);
     type = std::move(other.type);
     component_ids = std::move(other.component_ids);
+    setConnectorDocks();
 
     return *this;
 }
@@ -53,6 +91,7 @@ Module::Module(voxel_graph_ptr _parts, std::string &_name, std::string &_type, s
 {
     ASSUMPTION(!_parts->getVoxels().empty() || !_parts->getConnections().empty());
     makeNodeTree();
+    setConnectorDocks();
 }
 
 Module::Module(voxel_graph_ptr _parts, std::string &&_name, std::string &&_type, std::map<uint64_t, objectbase_ptr> &&_component_ids)
@@ -60,6 +99,7 @@ Module::Module(voxel_graph_ptr _parts, std::string &&_name, std::string &&_type,
 {
     ASSUMPTION(!_parts->getVoxels().empty() || !_parts->getConnections().empty());
     makeNodeTree();
+    setConnectorDocks();
 }
 
 module_ptr Module::copy(const module_ptr other_module)