Index: code/branches/objecthierarchy/src/orxonox/CMakeLists.txt
===================================================================
--- code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 2019)
@@ -43,4 +43,7 @@
   tools/WindowEventListener.cc
 
+  LevelManager.cc
+
+  objects/Scene.cc
   objects/worldentities/WorldEntity.cc
   objects/worldentities/PositionableEntity.cc
@@ -63,4 +66,6 @@
   objects/DistanceTrigger.cc
 
+  objects/worldentities/SpawnPoint.cc
+
   objects/worldentities/pawns/Spectator.cc
 
@@ -71,4 +76,5 @@
   objects/infos/Level.cc
   objects/infos/PlayerInfo.cc
+  objects/infos/HumanPlayer.cc
 
   objects/gametypes/Gametype.cc
Index: code/branches/objecthierarchy/src/orxonox/LevelManager.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/LevelManager.cc	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/LevelManager.cc	(revision 2019)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+
+#include "LevelManager.h"
+
+#include "core/CoreIncludes.h"
+
+#include "objects/infos/Level.h"
+#include "objects/infos/HumanPlayer.h"
+
+namespace orxonox
+{
+    LevelManager::LevelManager()
+    {
+        RegisterRootObject(LevelManager);
+
+        this->getConnectedClients();
+    }
+
+    LevelManager& LevelManager::getInstance()
+    {
+        static LevelManager instance;
+        return instance;
+    }
+
+    void LevelManager::requestActivity(Level* level)
+    {
+        this->levels_s.push_back(level);
+        if (this->levels_s.size() == 1)
+            this->activateNextLevel();
+    }
+
+    void LevelManager::releaseActivity(Level* level)
+    {
+        if (this->levels_s.size() > 0)
+        {
+            if (this->levels_s.front() == level)
+            {
+                level->setActive(false);
+                this->levels_s.pop_front();
+                this->activateNextLevel();
+            }
+            else
+            {
+                for (std::list<Level*>::iterator it = this->levels_s.begin(); it != this->levels_s.end(); ++it)
+                    if ((*it) == level)
+                        this->levels_s.erase(it);
+            }
+        }
+    }
+
+    Level* LevelManager::getActiveLevel()
+    {
+        if (this->levels_s.size() > 0)
+            return this->levels_s.front();
+        else
+            return 0;
+    }
+
+    void LevelManager::activateNextLevel()
+    {
+        if (this->levels_s.size() > 0)
+        {
+            this->levels_s.front()->setActive(true);
+            for (std::map<unsigned int, PlayerInfo*>::iterator it = this->clients_.begin(); it != this->clients_.end(); ++it)
+                this->levels_s.front()->playerEntered(it->second);
+        }
+    }
+
+
+    void LevelManager::clientConnected(unsigned int clientID)
+    {
+        COUT(0) << "client connected" << std::endl;
+
+        // create new HumanPlayer instance
+        HumanPlayer* player = new HumanPlayer(0);
+        player->setClientID(clientID);
+
+        // add to clients-map
+        assert(!this->clients_[clientID]);
+        this->clients_[clientID] = player;
+    }
+
+    void LevelManager::clientDisconnected(unsigned int clientID)
+    {
+        COUT(0) << "client disconnected" << std::endl;
+
+        // remove from clients-map
+        PlayerInfo* player = this->clients_[clientID];
+        this->clients_.erase(clientID);
+
+        // delete PlayerInfo instance
+        if (player)
+            delete player;
+    }
+
+
+    PlayerInfo* LevelManager::getClient(unsigned int clientID) const
+    {
+        std::map<unsigned int, PlayerInfo*>::const_iterator it = this->clients_.find(clientID);
+        if (it != this->clients_.end())
+            return it->second;
+        else
+            return 0;
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/LevelManager.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/LevelManager.h	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/LevelManager.h	(revision 2019)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LevelManager_H__
+#define _LevelManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <map>
+
+#include "network/ClientConnectionListener.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport LevelManager : public network::ClientConnectionListener
+    {
+        public:
+            static LevelManager& getInstance();
+
+            void requestActivity(Level* level);
+            void releaseActivity(Level* level);
+            Level* getActiveLevel();
+
+            PlayerInfo* getClient(unsigned int clientID) const;
+            inline const std::map<unsigned int, PlayerInfo*>& getClients() const
+                { return this->clients_; }
+
+        private:
+            LevelManager();
+            virtual ~LevelManager() {}
+
+            void clientConnected(unsigned int clientID);
+            void clientDisconnected(unsigned int clientID);
+
+            void activateNextLevel();
+
+            std::list<Level*> levels_s;
+            std::map<unsigned int, PlayerInfo*> clients_;
+    };
+}
+
+#endif /* _LevelManager_H__ */
Index: code/branches/objecthierarchy/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/OrxonoxPrereqs.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/OrxonoxPrereqs.h	(revision 2019)
@@ -80,13 +80,26 @@
     class RadarListener;
 
+    class LevelManager;
+
     // objects
+    class Scene;
+
     class WorldEntity;
     class PositionableEntity;
     class MovableEntity;
     class ControllableEntity;
+    class Sublevel;
 
     class Model;
+    class Billboard;
+    class Light;
+    class DirectionalLight;
+
+    class Camera;
+    class SpawnPoint;
 
     class Spectator;
+    class Pawn;
+    class SpaceShip;
 
     class Controller;
@@ -94,5 +107,4 @@
 
     class Backlight;
-    class Camera;
     class ParticleSpawner;
 
@@ -100,6 +112,9 @@
     class Level;
     class PlayerInfo;
+    class HumanPlayer;
 
     class Gametype;
+
+    class Scores;
 
     // tools
Index: code/branches/objecthierarchy/src/orxonox/objects/Camera.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Camera.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Camera.cc	(revision 2019)
@@ -32,4 +32,5 @@
 
 #include <string>
+#include <cassert>
 
 #include <OgreSceneManager.h>
@@ -41,73 +42,91 @@
 #include "util/SubString.h"
 #include "util/Math.h"
+#include "util/String.h"
 #include "util/Debug.h"
 #include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
 #include "GraphicsEngine.h"
+#include "objects/Scene.h"
 
 namespace orxonox
 {
-  CreateUnloadableFactory(Camera);
+    CreateFactory(Camera);
 
-  Camera::Camera()
-  {
-    RegisterObject(Camera);
+    Camera::Camera(BaseObject* creator) : PositionableEntity(creator)
+    {
+        RegisterObject(Camera);
 
-    this->bHasFocus_ = false;
-    this->bDrag_ = false;
-    this->cameraNode_ = GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode();
-    this->setObjectMode(0x0);
-  }
+        assert(this->getScene());
+        assert(this->getScene()->getSceneManager());
 
-  Camera::~Camera()
-  {
-    if (this->isInitialized())
+        this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
+        this->getNode()->attachObject(this->camera_);
+
+        this->bHasFocus_ = false;
+        this->bDrag_ = false;
+        this->nearClipDistance_ = 1;
+
+        this->setObjectMode(0x0);
+
+        this->setConfigValues();
+        this->configvaluecallback_changedNearClipDistance();
+
+        this->requestFocus(); // ! HACK ! REMOVE THIS !
+    }
+
+    Camera::~Camera()
     {
-      CameraHandler::getInstance()->releaseFocus(this);
-      GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->removeAndDestroyChild(this->cameraNode_->getName());
+        if (this->isInitialized())
+        {
+            this->releaseFocus();
+        }
     }
-  }
 
-  void Camera::tick(float dt)
-  {
-      // this stuff here may need some adjustments
-      float coeff = (this->bDrag_) ? min(1.0f, 15.0f * dt) : (1.0f);
+    void Camera::setConfigValues()
+    {
+        SetConfigValue(nearClipDistance_, 1.0f).callback(this, &Camera::configvaluecallback_changedNearClipDistance);
+    }
 
-      Vector3 offset = this->getNode()->getWorldPosition() - this->cameraNode_->getWorldPosition();
-      this->cameraNode_->translate(coeff * offset);
+    void Camera::configvaluecallback_changedNearClipDistance()
+    {
+        this->camera_->setNearClipDistance(this->nearClipDistance_);
+    }
 
-      this->cameraNode_->setOrientation(Quaternion::Slerp(coeff, this->cameraNode_->getWorldOrientation(), this->getWorldOrientation(), false));
-  }
+    void Camera::tick(float dt)
+    {
+/*
+        // this stuff here may need some adjustments
+        float coeff = (this->bDrag_) ? min(1.0f, 15.0f * dt) : (1.0f);
 
-  /**
-    don't move anything before here! here the Ogre camera is set to values of this camera
-    always call update after changes
-  */
-  void Camera::update()
-  {
-      this->cameraNode_->setPosition(this->getWorldPosition());
-      this->cameraNode_->setOrientation(this->getWorldOrientation());
-  }
+        Vector3 offset = this->getNode()->getWorldPosition() - this->cameraNode_->getWorldPosition();
+        this->cameraNode_->translate(coeff * offset);
 
-  /**
-    what to do when camera loses focus (do not request focus in this function!!)
-    this is called by the CameraHandler singleton class to notify the camera
-  */
-  void Camera::removeFocus()
-  {
-    this->bHasFocus_ = false;
-    this->cameraNode_->detachObject(this->cam_);
-  }
+        this->cameraNode_->setOrientation(Quaternion::Slerp(coeff, this->cameraNode_->getWorldOrientation(), this->getWorldOrientation(), false));
+*/
+    }
 
-  void Camera::setFocus(Ogre::Camera* ogreCam)
-  {
-    this->bHasFocus_ = true;
-    this->cam_ = ogreCam;
-    this->cam_->setOrientation(this->cameraNode_->getWorldOrientation());
-    this->cameraNode_->attachObject(this->cam_);
-  }
+    void Camera::requestFocus()
+    {
+        CameraHandler::getInstance().requestFocus(this);
+    }
 
-  void Camera::requestFocus()
-  {
-    CameraHandler::getInstance()->requestFocus(this);
-  }
+    void Camera::releaseFocus()
+    {
+        CameraHandler::getInstance().releaseFocus(this);
+    }
+
+    /**
+        what to do when camera loses focus (do not request focus in this function!!)
+        this is called by the CameraHandler singleton class to notify the camera
+    */
+    void Camera::removeFocus()
+    {
+        this->bHasFocus_ = false;
+    }
+
+    void Camera::setFocus(Ogre::Viewport* viewport)
+    {
+        this->bHasFocus_ = true;
+        viewport->setCamera(this->camera_);
+    }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/Camera.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Camera.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Camera.h	(revision 2019)
@@ -42,31 +42,33 @@
     class _OrxonoxExport Camera : public PositionableEntity, public Tickable
     {
-      friend class CameraHandler;
+        friend class CameraHandler;
 
-      public:
-        Camera();
-        virtual ~Camera();
+        public:
+            Camera(BaseObject* creator);
+            virtual ~Camera();
 
-        virtual void tick(float dt);
-        void update();
+            void setConfigValues();
+            virtual void tick(float dt);
 
-        void requestFocus();
-        inline bool hasFocus()
-            { return this->bHasFocus_; }
+            void requestFocus();
+            void releaseFocus();
 
-        inline void setDrag(bool bDrag)
-            { this->bDrag_ = bDrag; }
-        inline bool getDrag() const
-            { return this->bDrag_; }
+            inline bool hasFocus()
+                { return this->bHasFocus_; }
 
-      private:
-        void removeFocus();
-        void setFocus(Ogre::Camera* ogreCam);
+            inline void setDrag(bool bDrag)
+                { this->bDrag_ = bDrag; }
+            inline bool getDrag() const
+                { return this->bDrag_; }
 
-        Ogre::Camera* cam_;
-        Ogre::SceneNode* cameraNode_;
-        Ogre::Vector3 oldPos;
-        bool bHasFocus_;
-        bool bDrag_;
+        private:
+            void removeFocus();
+            void setFocus(Ogre::Viewport* viewport);
+            void configvaluecallback_changedNearClipDistance();
+
+            Ogre::Camera*   camera_;
+            float           nearClipDistance_;
+            bool            bHasFocus_;
+            bool            bDrag_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.cc	(revision 2019)
@@ -33,4 +33,5 @@
 
 #include "core/ObjectList.h"
+#include "core/Core.h"
 #include "Camera.h"
 #include "GraphicsEngine.h"
@@ -38,60 +39,58 @@
 #include <OgreCamera.h>
 
-namespace orxonox {
+namespace orxonox
+{
+    CameraHandler::CameraHandler()
+    {
+//        GraphicsEngine::getInstance().getViewport()->setCamera(this->cam_);
+    }
 
-  CameraHandler* CameraHandler::singletonRef = NULL;
+    CameraHandler& CameraHandler::getInstance()
+    {
+        static CameraHandler instance;
+        return instance;
+    }
 
-  CameraHandler::CameraHandler()
-  {
-    this->cam_ = GraphicsEngine::getInstance().getLevelSceneManager()->createCamera("Cam");
-    GraphicsEngine::getInstance().getViewport()->setCamera(this->cam_);
-    this->cam_->setNearClipDistance(1);
-    //GraphicsEngine::getInstance().getRenderWindow()->addViewport(this->cam_, 2, 0.4, 0.4, 0.2, 0.2);
-    /*this->activeCamera_ = *ObjectList<Camera>::begin();
-    this->activeCamera_->cam_ = this->cam_;*/
-  }
+    Camera* CameraHandler::getActiveCamera() const
+    {
+        if (this->cameraList_.size() > 0)
+            return this->cameraList_.front();
+        else
+            return 0;
+    }
 
-  void CameraHandler::requestFocus(Camera* requestCam)
-  {
-    // notify old camera (if it exists)
-    if(focusList_.size() > 0)
-      focusList_.back()->removeFocus();
-    // add to list
-    focusList_.push_back(requestCam);
-    // set focus to new camera and update (if necessary)
-    if(!requestCam->hasFocus()) {
-      requestCam->setFocus(this->cam_);
-      requestCam->update();
+    void CameraHandler::requestFocus(Camera* camera)
+    {
+        if (!Core::showsGraphics())
+            return;
+
+        // notify old camera (if it exists)
+        if (this->cameraList_.size() > 0)
+            this->cameraList_.front()->removeFocus();
+
+        // add to list
+        this->cameraList_.push_front(camera);
+        camera->setFocus(GraphicsEngine::getInstance().getViewport());
     }
-    // delete dublicates
-    focusList_.unique();
-  }
 
-  void CameraHandler::releaseFocus(Camera* cam)
-  {
-    // notify the cam of releasing the focus
-    if(cam->hasFocus())
-      cam->removeFocus();
-    // delete camera from list
-    focusList_.remove(cam);
-    // set new focus if necessary
-    if(focusList_.size() > 0 && !(focusList_.back()->hasFocus()))
-      focusList_.back()->setFocus(this->cam_);
-  }
-/*
-  void CameraHandler::changeActiveCamera(Camera* setCam)
-  {
-    cam_->getParentSceneNode()->detachObject(cam_);
-    //setCam->attachCamera(cam_);
-    activeCamera_ = setCam;
-  }
-*/
-/*  bool isInVector(Camera* cam)
-  {
-    for(std::vector<Camera*>::iterator it = cams_.begin(); it != cams_.end(); it++)
+    void CameraHandler::releaseFocus(Camera* camera)
     {
-      if (*it == cam) return true;
+        if (!Core::showsGraphics())
+            return;
+
+        // notify the cam of releasing the focus
+        if (this->cameraList_.front() == camera)
+        {
+            camera->removeFocus();
+            this->cameraList_.pop_front();
+
+            // set new focus if necessary
+            if (cameraList_.size() > 0)
+                cameraList_.front()->setFocus(GraphicsEngine::getInstance().getViewport());
+        }
+        else
+        {
+            this->cameraList_.remove(camera);
+        }
     }
-    return false;
-  }*/
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/CameraHandler.h	(revision 2019)
@@ -36,9 +36,8 @@
 #define _Camera_Handler_H__
 
+#include "OrxonoxPrereqs.h"
+
 #include <list>
-
 #include <OgreCamera.h>
-
-#include "OrxonoxPrereqs.h"
 
 #include "core/BaseObject.h"
@@ -46,27 +45,20 @@
 namespace orxonox
 {
-  class _OrxonoxExport CameraHandler
-  {
+    class _OrxonoxExport CameraHandler
+    {
+        public:
+            static CameraHandler& getInstance();
 
-    public:
-      inline static CameraHandler* getInstance() { if (!CameraHandler::singletonRef) CameraHandler::singletonRef = new CameraHandler(); return CameraHandler::singletonRef; }
-      inline ~CameraHandler() { CameraHandler::singletonRef = NULL; }
-      inline Camera* getActiveCamera() { return this->focusList_.back(); }
-      /*void registerCamera(Camera* newCam);
-      void changeActiveCamera(Camera* setCam);*/
-      void requestFocus(Camera* requestCam);
-      void releaseFocus(Camera* cam);
+            Camera* getActiveCamera() const;
 
-    private:
-      CameraHandler();
-      //bool isInVector(Camera* cam);
+            void requestFocus(Camera* camera);
+            void releaseFocus(Camera* camera);
 
-    private:
-      static CameraHandler* singletonRef;
-      Ogre::Camera* cam_;
-      std::list<Camera*> focusList_;
-      //std::vector<Camera*> cams_;
+        private:
+            CameraHandler();
+            ~CameraHandler() {}
 
-  };
+            std::list<Camera*> cameraList_;
+    };
 }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.cc	(revision 2019)
@@ -37,5 +37,5 @@
   CreateFactory(DistanceTrigger);
 
-  DistanceTrigger::DistanceTrigger()
+  DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator)
   {
     RegisterObject(DistanceTrigger);
Index: code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/DistanceTrigger.h	(revision 2019)
@@ -44,5 +44,5 @@
   {
     public:
-      DistanceTrigger();
+      DistanceTrigger(BaseObject* creator);
       ~DistanceTrigger();
       void addTarget(Ogre::Node* targetNode);
Index: code/branches/objecthierarchy/src/orxonox/objects/ParticleSpawner.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/ParticleSpawner.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/ParticleSpawner.cc	(revision 2019)
@@ -80,5 +80,5 @@
         this->setPosition(this->getNode()->getParent()->getPosition());
         this->getNode()->getParent()->removeChild(this->getNode());
-        GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->addChild(this->getNode());
+        this->detachFromParent();
         if (this->particle_)
             this->particle_->setEnabled(false);
Index: code/branches/objecthierarchy/src/orxonox/objects/Scene.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Scene.cc	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/Scene.cc	(revision 2019)
@@ -0,0 +1,150 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "Scene.h"
+
+#include <OgreRoot.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+#include <OgreLight.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(Scene);
+
+    Scene::Scene(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Scene);
+
+        this->setScene(this);
+        this->bShadows_ = false;
+
+        if (Ogre::Root::getSingletonPtr())
+        {
+            this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
+            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
+        }
+        else
+        {
+            this->sceneManager_ = 0;
+            this->rootSceneNode_ = 0;
+        }
+
+        // test test test
+        if (this->sceneManager_)
+        {
+            Ogre::Light* light;
+            light = this->sceneManager_->createLight("Light0");
+            light->setType(Ogre::Light::LT_DIRECTIONAL);
+            light->setDiffuseColour(ColourValue(1.0, 0.9, 0.6, 1.0));
+            light->setSpecularColour(ColourValue(1.0, 0.9, 0.6, 1.0));
+            light->setDirection(1, -0.2, 0.2);
+        }
+        // test test test
+    }
+
+    Scene::~Scene()
+    {
+        if (Ogre::Root::getSingletonPtr())
+        {
+//            this->sceneManager_->destroySceneNode(this->rootSceneNode_->getName()); // TODO: remove getName() for newer versions of Ogre
+            Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
+        }
+        else
+        {
+        }
+    }
+
+    void Scene::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Scene, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Scene, "skybox", setSkybox, getSkybox, xmlelement, mode);
+        XMLPortParam(Scene, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2, 0.2, 0.2, 1));
+        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
+
+        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
+    }
+
+    void Scene::registerVariables()
+    {
+        REGISTERSTRING(this->skybox_,     network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
+        REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
+    }
+
+    void Scene::setSkybox(const std::string& skybox)
+    {
+        if (this->sceneManager_)
+            this->sceneManager_->setSkyBox(true, skybox);
+
+        this->skybox_ = skybox;
+    }
+
+    void Scene::setAmbientLight(const ColourValue& colour)
+    {
+        if (this->sceneManager_)
+            this->sceneManager_->setAmbientLight(colour);
+
+        this->ambientLight_ = colour;
+    }
+
+    void Scene::setShadow(bool bShadow)
+    {
+        if (this->sceneManager_)
+        {
+            if (bShadow)
+                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
+            else
+                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
+        }
+
+        this->bShadows_ = bShadow;
+    }
+
+    void Scene::addObject(BaseObject* object)
+    {
+        this->objects_.push_back(object);
+        object->setScene(this);
+    }
+
+    BaseObject* Scene::getObject(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/Scene.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Scene.h	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/Scene.h	(revision 2019)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Scene_H__
+#define _Scene_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "network/Synchronisable.h"
+#include "core/BaseObject.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Scene : public BaseObject, public network::Synchronisable
+    {
+        public:
+            Scene(BaseObject* creator);
+            virtual ~Scene();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->sceneManager_; }
+            inline Ogre::SceneNode* getRootSceneNode() const
+                { return this->rootSceneNode_; }
+
+            void setSkybox(const std::string& skybox);
+            inline const std::string& getSkybox() const
+                { return this->skybox_; }
+
+            void setAmbientLight(const ColourValue& colour);
+            inline const ColourValue& getAmbientLight() const
+                { return this->ambientLight_; }
+
+            void setShadow(bool bShadow);
+            inline bool getShadow() const
+                { return this->bShadows_; }
+
+        private:
+            void addObject(BaseObject* object);
+            BaseObject* getObject(unsigned int index) const;
+
+            void networkcallback_applySkybox()
+                { this->setSkybox(this->skybox_); }
+            void networkcallback_applyAmbientLight()
+                { this->setAmbientLight(this->ambientLight_); }
+
+            Ogre::SceneManager*    sceneManager_;
+            Ogre::SceneNode*       rootSceneNode_;
+            std::string            skybox_;
+            ColourValue            ambientLight_;
+            std::list<BaseObject*> objects_;
+            bool                   bShadows_;
+    };
+}
+
+#endif /* _Scene_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/Script.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Script.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Script.cc	(revision 2019)
@@ -39,5 +39,5 @@
   CreateFactory(Script);
 
-  Script::Script()
+  Script::Script(BaseObject* creator) : BaseObject(creator)
   {
     RegisterObject(Script);
Index: code/branches/objecthierarchy/src/orxonox/objects/Script.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Script.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Script.h	(revision 2019)
@@ -39,5 +39,5 @@
   {
     public:
-      Script();
+      Script(BaseObject* creator);
       ~Script();
       void XMLPort(Element& xmlelement, XMLPort::Mode mode);
Index: code/branches/objecthierarchy/src/orxonox/objects/Test.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Test.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Test.cc	(revision 2019)
@@ -36,5 +36,5 @@
 	CreateFactory ( Test );
 
-	Test::Test()
+	Test::Test(BaseObject* creator) : BaseObject(creator)
 	{
 		RegisterObject ( Test );
Index: code/branches/objecthierarchy/src/orxonox/objects/Test.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Test.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Test.h	(revision 2019)
@@ -39,14 +39,14 @@
   {
     public:
-      Test();
+      Test(BaseObject* creator);
       virtual ~Test();
 
       void setConfigValues();
       void registerVariables();
-      
+
       void setV1(unsigned int value){ v1 = value; }
       void setV2(unsigned int value){ v2 = value; }
       void setV3(unsigned int value){ v3 = value; }
-      
+
       void checkV1();
       void checkV2();
Index: code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc	(revision 2019)
@@ -35,4 +35,5 @@
 #include "core/ConsoleCommand.h"
 #include "core/XMLPort.h"
+#include "objects/Scene.h"
 
 namespace orxonox
@@ -43,5 +44,5 @@
   CreateFactory(Trigger);
 
-  Trigger::Trigger()
+  Trigger::Trigger(BaseObject* creator) : PositionableEntity(creator)
   {
     RegisterObject(Trigger);
@@ -57,6 +58,9 @@
     latestState_ = 0x0;
 
-    debugBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
-    debugBillboard_.setVisible(false);
+    if (this->getScene() && this->getScene()->getSceneManager())
+    {
+      debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
+      debugBillboard_.setVisible(false);
+    }
 
     this->getNode()->attachObject(debugBillboard_.getBillboardSet());
Index: code/branches/objecthierarchy/src/orxonox/objects/Trigger.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Trigger.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/Trigger.h	(revision 2019)
@@ -50,5 +50,5 @@
   {
     public:
-      Trigger();
+      Trigger(BaseObject* creator);
       ~Trigger();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.cc	(revision 2019)
@@ -36,10 +36,10 @@
     CreateUnloadableFactory(Controller);
 
-    Controller::Controller()
+    Controller::Controller(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(Controller);
 
         this->player_ = 0;
-        this->pawn_ = 0;
+        this->controllableEntity_ = 0;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/controllers/Controller.h	(revision 2019)
@@ -39,5 +39,5 @@
     {
         public:
-            Controller();
+            Controller(BaseObject* creator);
             virtual ~Controller();
 
@@ -47,12 +47,12 @@
                 { return this->player_; }
 
-            inline void setPawn(ControllableEntity* pawn)
-                { this->pawn_ = pawn; }
-            inline ControllableEntity* getPawn() const
-                { return this->pawn_; }
+            virtual inline void setControllableEntity(ControllableEntity* entity)
+                { this->controllableEntity_ = entity; }
+            virtual inline ControllableEntity* getControllableEntity() const
+                { return this->controllableEntity_; }
 
         protected:
             PlayerInfo* player_;
-            ControllableEntity* pawn_;
+            ControllableEntity* controllableEntity_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2019)
@@ -52,5 +52,5 @@
     HumanController* HumanController::localController_s = 0;
 
-    HumanController::HumanController()
+    HumanController::HumanController(BaseObject* creator) : Controller(creator)
     {
         RegisterObject(HumanController);
@@ -66,66 +66,66 @@
     void HumanController::moveFrontBack(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveFrontBack(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveFrontBack(value.y);
     }
 
     void HumanController::moveRightLeft(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveRightLeft(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveRightLeft(value.y);
     }
 
     void HumanController::moveUpDown(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->moveUpDown(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveUpDown(value.y);
     }
 
     void HumanController::rotateYaw(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotateYaw(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotateYaw(value.y);
     }
 
     void HumanController::rotatePitch(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotatePitch(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotatePitch(value.y);
     }
 
     void HumanController::rotateRoll(const Vector2& value)
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->rotateRoll(value.y);
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotateRoll(value.y);
     }
 
     void HumanController::fire()
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->fire();
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->fire();
     }
 
     void HumanController::altFire()
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->altFire();
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->altFire();
     }
 
     void HumanController::greet()
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->greet();
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->greet();
     }
 
     void HumanController::use()
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->use();
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->use();
     }
 
     void HumanController::switchCamera()
     {
-        if (HumanController::localController_s && HumanController::localController_s->pawn_)
-            HumanController::localController_s->pawn_->switchCamera();
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->switchCamera();
     }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.h	(revision 2019)
@@ -40,5 +40,5 @@
     {
         public:
-            HumanController();
+            HumanController(BaseObject* creator);
             virtual ~HumanController();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc	(revision 2019)
@@ -30,7 +30,11 @@
 #include "Gametype.h"
 
+#include <cstdlib>
+#include <ctime>
+
 #include "core/CoreIncludes.h"
 #include "objects/infos/PlayerInfo.h"
 #include "objects/worldentities/pawns/Spectator.h"
+#include "objects/worldentities/SpawnPoint.h"
 
 #include "network/Host.h"
@@ -40,34 +44,43 @@
     CreateUnloadableFactory(Gametype);
 
-    Gametype::Gametype()
+    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(Gametype);
 
         this->defaultPawn_ = Class(Spectator);
+        this->bStarted_ = false;
+        this->bEnded_ = false;
+        this->bAutoStart_ = false;
 
         COUT(0) << "created Gametype" << std::endl;
     }
 
-    void Gametype::addPlayer(PlayerInfo* player)
+    void Gametype::tick(float dt)
+    {
+        if (!this->bStarted_)
+            this->checkStart();
+
+        this->assignDefaultPawnsIfNeeded();
+    }
+
+    void Gametype::start()
+    {
+        COUT(0) << "game started" << std::endl;
+        this->bStarted_ = true;
+
+        for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+            this->spawnPlayer(*it);
+    }
+
+    void Gametype::end()
+    {
+        COUT(0) << "game ended" << std::endl;
+        this->bEnded_ = true;
+    }
+
+    void Gametype::playerEntered(PlayerInfo* player)
     {
         this->players_.insert(player);
-        this->playerJoined(player);
-
-        ControllableEntity* newpawn = this->defaultPawn_.fabricate();
-        player->startControl(newpawn);
-    }
-
-    void Gametype::removePlayer(PlayerInfo* player)
-    {
-        if (this->players_.find(player) != this->players_.end())
-        {
-            player->stopControl();
-            this->players_.erase(player);
-            this->playerLeft(player);
-        }
-    }
-
-    void Gametype::playerJoined(PlayerInfo* player)
-    {
+
         std::string message = player->getName() + " entered the game";
         COUT(0) << message << std::endl;
@@ -77,7 +90,21 @@
     void Gametype::playerLeft(PlayerInfo* player)
     {
-        std::string message = player->getName() + " left the game";
-        COUT(0) << message << std::endl;
-        network::Host::Broadcast(message);
+        std::set<PlayerInfo*>::iterator it = this->players_.find(player);
+        if (it != this->players_.end())
+        {
+            this->players_.erase(it);
+
+            std::string message = player->getName() + " left the game";
+            COUT(0) << message << std::endl;
+            network::Host::Broadcast(message);
+        }
+    }
+
+    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
+    {
+    }
+
+    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
+    {
     }
 
@@ -94,3 +121,100 @@
         }
     }
+
+    void Gametype::playerSpawned(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerDied(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerScored(PlayerInfo* player)
+    {
+    }
+
+    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
+    {
+        if (this->spawnpoints_.size() > 0)
+        {
+            srand(time(0));
+            rnd();
+
+            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
+            unsigned int index = 0;
+            for (std::set<SpawnPoint*>::iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
+            {
+                if (index == randomspawn)
+                    return (*it);
+
+                ++index;
+            }
+        }
+        return 0;
+    }
+
+    void Gametype::assignDefaultPawnsIfNeeded() const
+    {
+        for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+        {
+            if (!(*it)->getControllableEntity() && (!(*it)->isReadyToSpawn() || !this->bStarted_))
+            {
+                SpawnPoint* spawn = this->getBestSpawnPoint(*it);
+                if (spawn)
+                {
+                    // force spawn at spawnpoint with default pawn
+                    ControllableEntity* newpawn = this->defaultPawn_.fabricate(spawn);
+                    spawn->spawn(newpawn);
+                    (*it)->startControl(newpawn);
+                }
+                else
+                {
+                    COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
+                    abort();
+                }
+            }
+        }
+    }
+
+    void Gametype::checkStart()
+    {
+        if (!this->bStarted_)
+        {
+            if (this->players_.size() > 0)
+            {
+                if (this->bAutoStart_)
+                {
+                    this->start();
+                }
+                else
+                {
+                    bool allplayersready = true;
+                    for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+                    {
+                        if (!(*it)->isReadyToSpawn())
+                            allplayersready = false;
+                    }
+                    if (allplayersready)
+                        this->start();
+                }
+            }
+        }
+    }
+
+    void Gametype::spawnPlayer(PlayerInfo* player)
+    {
+        if (player->isReadyToSpawn())
+        {
+            SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
+            if (spawnpoint)
+            {
+                player->startControl(spawnpoint->spawn());
+            }
+            else
+            {
+                COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
+                abort();
+            }
+        }
+    }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.h	(revision 2019)
@@ -37,29 +37,50 @@
 #include "core/Identifier.h"
 #include "objects/worldentities/ControllableEntity.h"
+#include "objects/Tickable.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Gametype : public BaseObject
+    class _OrxonoxExport Gametype : public BaseObject, public Tickable
     {
         friend class PlayerInfo;
 
         public:
-            Gametype();
+            Gametype(BaseObject* creator);
             virtual ~Gametype() {}
+
+            virtual void tick(float dt);
+
+            virtual void start();
+            virtual void end();
+            virtual void playerEntered(PlayerInfo* player);
+            virtual void playerLeft(PlayerInfo* player);
+            virtual void playerSwitched(PlayerInfo* player, Gametype* newgametype);
+            virtual void playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype);
+            virtual void playerChangedName(PlayerInfo* player);
+            virtual void playerSpawned(PlayerInfo* player);
+            virtual void playerDied(PlayerInfo* player);
+            virtual void playerScored(PlayerInfo* player);
 
             inline const std::set<PlayerInfo*>& getPlayers() const
                 { return this->players_; }
 
-        protected:
-            virtual void playerJoined(PlayerInfo* player);
-            virtual void playerLeft(PlayerInfo* player);
-
-            virtual void playerChangedName(PlayerInfo* player);
+            inline void registerSpawnPoint(SpawnPoint* spawnpoint)
+                { this->spawnpoints_.insert(spawnpoint); }
 
         private:
+            virtual SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
+
             void addPlayer(PlayerInfo* player);
             void removePlayer(PlayerInfo* player);
 
+            void assignDefaultPawnsIfNeeded() const;
+            void checkStart();
+            void spawnPlayer(PlayerInfo* player);
+
+            bool bStarted_;
+            bool bEnded_;
+            bool bAutoStart_;
             std::set<PlayerInfo*> players_;
+            std::set<SpawnPoint*> spawnpoints_;
             SubclassIdentifier<ControllableEntity> defaultPawn_;
     };
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.cc	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.cc	(revision 2019)
@@ -0,0 +1,142 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "HumanPlayer.h"
+
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "network/ClientInformation.h"
+#include "network/Host.h"
+#include "objects/controllers/HumanController.h"
+#include "objects/gametypes/Gametype.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(HumanPlayer);
+
+    HumanPlayer::HumanPlayer(BaseObject* creator) : PlayerInfo(creator)
+    {
+        RegisterObject(HumanPlayer);
+
+        this->server_ready_ = Core::isMaster();
+        this->client_ready_ = false;
+
+        this->bHumanPlayer_ = true;
+        this->defaultController_ = Class(HumanController);
+
+        this->setConfigValues();
+        this->registerVariables();
+
+        COUT(0) << "HumanPlayer created" << std::endl;
+    }
+
+    HumanPlayer::~HumanPlayer()
+    {
+    }
+
+    void HumanPlayer::setConfigValues()
+    {
+        SetConfigValue(nick_, "Player").callback(this, &HumanPlayer::configvaluecallback_changednick);
+    }
+
+    void HumanPlayer::registerVariables()
+    {
+        REGISTERSTRING(this->synchronize_nick_, network::direction::toserver, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_changednick));
+
+        REGISTERDATA(this->clientID_,     network::direction::toclient, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_clientIDchanged));
+        REGISTERDATA(this->server_ready_, network::direction::toclient, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_server_ready));
+        REGISTERDATA(this->client_ready_, network::direction::toserver, new network::NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_client_ready));
+    }
+
+    void HumanPlayer::configvaluecallback_changednick()
+    {
+        if (this->isLocalPlayer())
+        {
+            this->synchronize_nick_ = this->nick_;
+
+            if (Core::isMaster())
+                this->setName(this->nick_);
+        }
+    }
+
+    void HumanPlayer::networkcallback_changednick()
+    {
+        this->setName(this->synchronize_nick_);
+    }
+
+    void HumanPlayer::networkcallback_clientIDchanged()
+    {
+        if (this->clientID_ == network::Host::getPlayerID())
+        {
+            this->bLocalPlayer_ = true;
+            this->synchronize_nick_ = this->nick_;
+            this->client_ready_ = true;
+
+            if (!Core::isMaster())
+                this->setObjectMode(network::direction::bidirectional);
+            else
+                this->setName(this->nick_);
+
+            this->createController();
+        }
+    }
+
+    void HumanPlayer::networkcallback_server_ready()
+    {
+        this->client_ready_ = true;
+    }
+
+    void HumanPlayer::networkcallback_client_ready()
+    {
+        if (this->getGametype())
+            this->getGametype()->playerEntered(this);
+    }
+
+    bool HumanPlayer::isReady() const
+    {
+        return (this->server_ready_ && this->client_ready_);
+    }
+
+    float HumanPlayer::getPing() const
+    {
+        return network::ClientInformation::findClient(this->getClientID())->getRTT();
+    }
+
+    float HumanPlayer::getPacketLossRatio() const
+    {
+        return network::ClientInformation::findClient(this->getClientID())->getPacketLoss();
+    }
+
+    void HumanPlayer::setClientID(unsigned int clientID)
+    {
+        this->clientID_ = clientID;
+        this->networkcallback_clientIDchanged();
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.h	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/HumanPlayer.h	(revision 2019)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HumanPlayer_H__
+#define _HumanPlayer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "PlayerInfo.h"
+#include "core/Identifier.h"
+#include "objects/controllers/Controller.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport HumanPlayer : public PlayerInfo
+    {
+        public:
+            HumanPlayer(BaseObject* creator);
+            virtual ~HumanPlayer();
+
+            void registerVariables();
+            void setConfigValues();
+
+            bool isReady() const;
+            float getPing() const;
+            float getPacketLossRatio() const;
+
+            void setClientID(unsigned int clientID);
+
+        protected:
+            void configvaluecallback_changednick();
+            void networkcallback_changednick();
+            void networkcallback_clientIDchanged();
+            void networkcallback_server_ready();
+            void networkcallback_client_ready();
+
+            std::string nick_;
+            std::string synchronize_nick_;
+            bool server_ready_;
+            bool client_ready_;
+    };
+}
+
+#endif /* _HumanPlayer_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/Info.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/Info.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/Info.cc	(revision 2019)
@@ -34,5 +34,5 @@
 namespace orxonox
 {
-    Info::Info()
+    Info::Info(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(Info);
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/Info.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/Info.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/Info.h	(revision 2019)
@@ -40,5 +40,5 @@
     {
         public:
-            Info();
+            Info(BaseObject* creator);
             virtual ~Info() {}
     };
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/Level.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/Level.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/Level.cc	(revision 2019)
@@ -30,18 +30,14 @@
 #include "Level.h"
 
-#include <OgreSceneManager.h>
-#include <OgreLight.h>
-
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
-#include "core/Core.h"
-#include "core/ConsoleCommand.h"
 #include "core/Loader.h"
 #include "core/XMLFile.h"
 #include "core/Template.h"
 
-#include "GraphicsEngine.h"
 #include "Settings.h"
+#include "LevelManager.h"
 #include "PlayerInfo.h"
+#include "objects/gametypes/Gametype.h"
 
 #include "util/Math.h"
@@ -49,97 +45,25 @@
 namespace orxonox
 {
-    SetConsoleCommand(Level, listPlayers, true);
-
     CreateFactory(Level);
 
-    Level::Level()
+    Level::Level(BaseObject* creator) : Info(creator)
     {
         RegisterObject(Level);
 
-        this->rootGametype_ = 0;
         this->registerVariables();
-
-        // test test test
-        {
-            Ogre::Light* light;
-            light = GraphicsEngine::getInstance().getLevelSceneManager()->createLight("Light0");
-            light->setType(Ogre::Light::LT_DIRECTIONAL);
-            light->setDiffuseColour(ColourValue(1.0, 0.9, 0.6, 1.0));
-            light->setSpecularColour(ColourValue(1.0, 0.9, 0.6, 1.0));
-            light->setDirection(1, -0.2, 0.2);
-        }
-        // test test test
+        this->xmlfilename_ = this->getFilename();
 
         COUT(0) << "created Level" << std::endl;
     }
 
-    Level* Level::getActiveLevel()
+    Level::~Level()
     {
-        for (ObjectList<Level>::iterator it = ObjectList<Level>::begin(); it != ObjectList<Level>::end(); ++it)
-            if (it->isActive())
-                return (*it);
+        if (this->isInitialized())
+        {
+            LevelManager::getInstance().releaseActivity(this);
 
-        return 0;
-    }
-
-    PlayerInfo* Level::getClient(unsigned int clientID)
-    {
-        Level* level = Level::getActiveLevel();
-
-        if (level)
-        {
-            std::map<unsigned int, PlayerInfo*>::const_iterator it = level->clients_.find(clientID);
-            if (it != level->clients_.end())
-                return it->second;
+            if (this->xmlfile_)
+                Loader::unload(this->xmlfile_);
         }
-        else
-        {
-            for (ObjectList<PlayerInfo>::iterator it = ObjectList<PlayerInfo>::begin(); it != ObjectList<PlayerInfo>::end(); ++it)
-                if (it->getClientID() == clientID)
-                    return (*it);
-        }
-        return 0;
-    }
-
-    void Level::listPlayers()
-    {
-        Level* level = Level::getActiveLevel();
-
-        if (level->getGametype())
-        {
-            for (std::set<PlayerInfo*>::const_iterator it = level->getGametype()->getPlayers().begin(); it != level->getGametype()->getPlayers().end(); ++it)
-                COUT(0) << "ID: " << (*it)->getClientID() << ", Name: " << (*it)->getName() << std::endl;
-        }
-        else
-        {
-            for (ObjectList<PlayerInfo>::iterator it = ObjectList<PlayerInfo>::begin(); it != ObjectList<PlayerInfo>::end(); ++it)
-                COUT(0) << "ID: " << (*it)->getClientID() << ", Name: " << (*it)->getName() << std::endl;
-        }
-    }
-
-    void Level::clientConnected(unsigned int clientID)
-    {
-        COUT(0) << "client connected" << std::endl;
-
-        // create new PlayerInfo instance
-        PlayerInfo* player = new PlayerInfo();
-        player->setGametype(this->getGametype());
-        player->setClientID(clientID);
-
-        // add to clients-map
-        assert(!this->clients_[clientID]);
-        this->clients_[clientID] = player;
-    }
-
-    void Level::clientDisconnected(unsigned int clientID)
-    {
-        COUT(0) << "client disconnected" << std::endl;
-
-        // remove from clients-map
-        PlayerInfo* player = this->clients_[clientID];
-        this->clients_.erase(clientID);
-
-        // delete PlayerInfo instance
-        delete player;
     }
 
@@ -150,22 +74,18 @@
         XMLPortParam(Level, "description", setDescription, getDescription, xmlelement, mode);
         XMLPortParam(Level, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
-        XMLPortParam(Level, "skybox", setSkybox, getSkybox, xmlelement, mode);
-        XMLPortParam(Level, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2, 0.2, 0.2, 1));
 
-        this->xmlfile_ = this->getFilename();
+        XMLPortObjectExtended(Level, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
     }
 
     void Level::registerVariables()
     {
-        REGISTERSTRING(this->xmlfile_,     network::direction::toclient, new network::NetworkCallback<Level>(this, &Level::networkcallback_applyXMLFile));
+        REGISTERSTRING(this->xmlfilename_, network::direction::toclient, new network::NetworkCallback<Level>(this, &Level::networkcallback_applyXMLFile));
         REGISTERSTRING(this->name_,        network::direction::toclient, new network::NetworkCallback<Level>(this, &Level::changedName));
         REGISTERSTRING(this->description_, network::direction::toclient);
-        REGISTERSTRING(this->skybox_,      network::direction::toclient, new network::NetworkCallback<Level>(this, &Level::networkcallback_applySkybox));
-        REGISTERDATA(this->ambientLight_,  network::direction::toclient, new network::NetworkCallback<Level>(this, &Level::networkcallback_applyAmbientLight));
     }
 
     void Level::networkcallback_applyXMLFile()
     {
-        COUT(0) << "Loading level \"" << this->xmlfile_ << "\"..." << std::endl;
+        COUT(0) << "Loading level \"" << this->xmlfilename_ << "\"..." << std::endl;
 
         ClassTreeMask mask;
@@ -173,24 +93,7 @@
         mask.include(Class(Template));
 
-        XMLFile* file = new XMLFile(Settings::getDataPath() + this->xmlfile_, mask);
+        this->xmlfile_ = new XMLFile(Settings::getDataPath() + this->xmlfilename_, mask);
 
-        Loader::open(file);
-    }
-
-    void Level::setSkybox(const std::string& skybox)
-    {
-        if (Core::showsGraphics())
-            if (GraphicsEngine::getInstance().getLevelSceneManager())
-                GraphicsEngine::getInstance().getLevelSceneManager()->setSkyBox(true, skybox);
-
-        this->skybox_ = skybox;
-    }
-
-    void Level::setAmbientLight(const ColourValue& colour)
-    {
-        if (Core::showsGraphics())
-            GraphicsEngine::getInstance().getLevelSceneManager()->setAmbientLight(colour);
-
-        this->ambientLight_ = colour;
+        Loader::open(this->xmlfile_);
     }
 
@@ -198,11 +101,46 @@
     {
         Identifier* identifier = ClassByString(gametype);
-        if (identifier)
+        if (identifier && identifier->isA(Class(Gametype)))
         {
             this->gametype_ = gametype;
-            this->gametypeIdentifier_ = identifier;
-            this->rootGametype_ = this->gametypeIdentifier_.fabricate();
-            this->getConnectedClients();
+
+            Gametype* rootgametype = dynamic_cast<Gametype*>(identifier->fabricate(this));
+            this->setGametype(rootgametype);
+
+            for (std::list<BaseObject*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+                (*it)->setGametype(rootgametype);
+
+            LevelManager::getInstance().requestActivity(this);
         }
     }
+
+
+    void Level::addObject(BaseObject* object)
+    {
+        this->objects_.push_back(object);
+        object->setGametype(this->getGametype());
+    }
+
+    BaseObject* Level::getObject(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    void Level::playerEntered(PlayerInfo* player)
+    {
+        COUT(0) << "player entered level" << std::endl;
+        player->setGametype(this->getGametype());
+    }
+
+    void Level::playerLeft(PlayerInfo* player)
+    {
+        player->setGametype(0);
+    }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/Level.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/Level.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/Level.h	(revision 2019)
@@ -33,23 +33,15 @@
 
 #include "Info.h"
-#include "util/Math.h"
-#include "core/Identifier.h"
-
-#include "objects/gametypes/Gametype.h"
-#include "network/ClientConnectionListener.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport Level : public Info, public network::ClientConnectionListener
+    class _OrxonoxExport Level : public Info
     {
         public:
-            Level();
-            virtual ~Level() {}
+            Level(BaseObject* creator);
+            virtual ~Level();
 
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             void registerVariables();
-
-            inline const std::map<unsigned int, PlayerInfo*>& getClients() const
-                { return this->clients_; }
 
             inline void setDescription(const std::string& description)
@@ -58,41 +50,22 @@
                 { return this->description_; }
 
-            void setSkybox(const std::string& skybox);
-            inline const std::string& getSkybox() const
-                { return this->skybox_; }
+            void playerEntered(PlayerInfo* player);
+            void playerLeft(PlayerInfo* player);
 
-            void setAmbientLight(const ColourValue& colour);
-            inline const ColourValue& getAmbientLight() const
-                { return this->ambientLight_; }
+        private:
+            void addObject(BaseObject* object);
+            BaseObject* getObject(unsigned int index) const;
 
             void setGametypeString(const std::string& gametype);
             inline const std::string& getGametypeString() const
                 { return this->gametype_; }
-            inline Gametype* getGametype() const
-                { return this->rootGametype_; }
-
-            static Level* getActiveLevel();
-            static void listPlayers();
-            static PlayerInfo* getClient(unsigned int clientID);
-
-        private:
-            virtual void clientConnected(unsigned int clientID);
-            virtual void clientDisconnected(unsigned int clientID);
 
             void networkcallback_applyXMLFile();
 
-            void networkcallback_applySkybox()
-                { this->setSkybox(this->skybox_); }
-            void networkcallback_applyAmbientLight()
-                { this->setAmbientLight(this->ambientLight_); }
-
-            std::map<unsigned int, PlayerInfo*> clients_;
-            std::string description_;
-            std::string skybox_;
-            ColourValue ambientLight_;
-            std::string gametype_;
-            SubclassIdentifier<Gametype> gametypeIdentifier_;
-            Gametype* rootGametype_;
-            std::string xmlfile_;
+            std::string            description_;
+            std::string            gametype_;
+            std::string            xmlfilename_;
+            XMLFile*               xmlfile_;
+            std::list<BaseObject*> objects_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2019)
@@ -27,43 +27,27 @@
  */
 
+#include <cassert>
+
 #include "OrxonoxStableHeaders.h"
 #include "PlayerInfo.h"
 
-#include <OgreSceneManager.h>
-
 #include "core/CoreIncludes.h"
-#include "core/ConfigValueIncludes.h"
-#include "core/XMLPort.h"
-#include "core/Core.h"
-
-#include "network/Host.h"
 #include "network/ClientInformation.h"
-
-#include "GraphicsEngine.h"
 #include "objects/gametypes/Gametype.h"
-#include "objects/worldentities/ControllableEntity.h"
-#include "objects/controllers/HumanController.h"
 
 namespace orxonox
 {
-    CreateUnloadableFactory(PlayerInfo);
-
-    PlayerInfo::PlayerInfo()
+    PlayerInfo::PlayerInfo(BaseObject* creator) : Info(creator)
     {
         RegisterObject(PlayerInfo);
 
-        this->ping_ = -1;
         this->clientID_ = network::CLIENTID_UNKNOWN;
+        this->bHumanPlayer_ = false;
         this->bLocalPlayer_ = false;
-        this->bHumanPlayer_ = false;
-        this->bFinishedSetup_ = false;
-        this->gametype_ = 0;
+        this->bReadyToSpawn_ = false;
+        this->controller_ = 0;
+        this->controllableEntity_ = 0;
+        this->controllableEntityID_ = network::CLIENTID_UNKNOWN;
 
-        this->pawn_ = 0;
-        this->pawnID_ = network::OBJECTID_UNKNOWN;
-        this->controller_ = 0;
-        this->setDefaultController(Class(HumanController));
-
-        this->setConfigValues();
         this->registerVariables();
     }
@@ -73,119 +57,105 @@
         if (this->isInitialized())
         {
-            if (this->gametype_)
-                this->gametype_->removePlayer(this);
+            this->stopControl(this->controllableEntity_);
 
             if (this->controller_)
+            {
                 delete this->controller_;
-
-            if (this->pawn_)
-                this->pawn_->removePlayer();
+                this->controller_ = 0;
+            }
         }
     }
 
-    void PlayerInfo::setConfigValues()
+    void PlayerInfo::registerVariables()
     {
-        SetConfigValue(nick_, "Player").callback(this, &PlayerInfo::checkNick);
-    }
-
-    void PlayerInfo::checkNick()
-    {
-        if (this->bLocalPlayer_)
-        {
-            this->playerName_ = this->nick_;
-
-            if (Core::isMaster())
-                this->setName(this->playerName_);
-        }
+        REGISTERSTRING(this->name_,                 network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName));
+        REGISTERDATA  (this->controllableEntityID_, network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedcontrollableentityID));
     }
 
     void PlayerInfo::changedName()
     {
-        if (this->gametype_)
-            this->gametype_->playerChangedName(this);
+        if (this->isReady() && this->getGametype())
+            this->getGametype()->playerChangedName(this);
     }
 
-    void PlayerInfo::registerVariables()
+    void PlayerInfo::changedGametype()
     {
-        REGISTERSTRING(name_,         network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName));
-        REGISTERSTRING(playerName_,   network::direction::toserver, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::clientChangedName));
-        REGISTERDATA(clientID_,       network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::checkClientID));
-        REGISTERDATA(ping_,           network::direction::toclient);
-        REGISTERDATA(bHumanPlayer_,   network::direction::toclient);
-        REGISTERDATA(pawnID_,         network::direction::toclient, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::updatePawn));
-        REGISTERDATA(bFinishedSetup_, network::direction::bidirectional, new network::NetworkCallback<PlayerInfo>(this, &PlayerInfo::finishedSetup));
-    }
+        if (this->isReady())
+        {
+            if (this->getOldGametype())
+            {
+                if (this->getGametype())
+                    this->getOldGametype()->playerSwitched(this, this->getGametype());
+                else
+                    this->getOldGametype()->playerLeft(this);
+            }
 
-    void PlayerInfo::clientChangedName()
-    {
-        this->setName(this->playerName_);
-    }
-
-    void PlayerInfo::checkClientID()
-    {
-        this->bHumanPlayer_ = true;
-
-        if (this->clientID_ == network::Host::getPlayerID())
-        {
-            this->takeLocalControl();
-
-            if (Core::isClient())
-                this->setObjectMode(network::direction::bidirectional);
-            else
+            if (this->getGametype())
             {
-                this->clientChangedName();
-                this->bFinishedSetup_ = true;
-                this->finishedSetup();
+                if (this->getOldGametype())
+                    this->getGametype()->playerSwitchedBack(this, this->getOldGametype());
+                else
+                    this->getGametype()->playerEntered(this);
             }
         }
     }
 
-    void PlayerInfo::finishedSetup()
+    void PlayerInfo::createController()
     {
-        if (Core::isClient())
-            this->bFinishedSetup_ = true;
-        else if (this->bFinishedSetup_)
+        this->controller_ = this->defaultController_.fabricate(this);
+        assert(this->controller_);
+        this->controller_->setPlayer(this);
+        if (this->controllableEntity_)
+            this->controller_->setControllableEntity(this->controllableEntity_);
+    }
+
+    void PlayerInfo::startControl(ControllableEntity* entity)
+    {
+        if (this->controllableEntity_)
+            this->stopControl(this->controllableEntity_);
+
+        this->controllableEntity_ = entity;
+
+        if (entity)
         {
-            if (this->gametype_)
-                this->gametype_->addPlayer(this);
+            this->controllableEntityID_ = entity->getObjectID();
+            entity->setPlayer(this);
+        }
+        else
+        {
+            this->controllableEntityID_ = network::OBJECTID_UNKNOWN;
+        }
+
+        if (this->controller_)
+            this->controller_->setControllableEntity(entity);
+    }
+
+    void PlayerInfo::stopControl(ControllableEntity* entity)
+    {
+        if (entity && this->controllableEntity_ == entity)
+        {
+            this->controllableEntity_ = 0;
+            this->controllableEntityID_ = network::OBJECTID_UNKNOWN;
+
+            if (this->controller_)
+                this->controller_->setControllableEntity(0);
+
+            entity->removePlayer();
         }
     }
 
-    void PlayerInfo::startControl(ControllableEntity* pawn)
+    void PlayerInfo::networkcallback_changedcontrollableentityID()
     {
-        pawn->setPlayer(this);
-        this->pawn_ = pawn;
-        this->pawnID_ = pawn->getObjectID();
+        if (this->controllableEntityID_ != network::OBJECTID_UNKNOWN)
+        {
+            Synchronisable* temp = Synchronisable::getSynchronisable(this->controllableEntityID_);
+            ControllableEntity* entity = dynamic_cast<ControllableEntity*>(temp);
 
-        if (this->controller_)
-            this->controller_->setPawn(this->pawn_);
-    }
-
-    void PlayerInfo::stopControl()
-    {
-        if (this->pawn_)
-            this->pawn_->removePlayer();
-        this->pawn_ = 0;
-        this->pawnID_ = network::OBJECTID_UNKNOWN;
-    }
-
-    void PlayerInfo::takeLocalControl()
-    {
-        this->bLocalPlayer_ = true;
-        this->playerName_ = this->nick_;
-        this->createController();
-    }
-
-    void PlayerInfo::createController()
-    {
-        this->controller_ = this->defaultController_.fabricate();
-        this->controller_->setPawn(this->pawn_);
-    }
-
-    void PlayerInfo::updatePawn()
-    {
-        this->pawn_ = dynamic_cast<ControllableEntity*>(network::Synchronisable::getSynchronisable(this->pawnID_));
-        if (this->pawn_ && (this->pawn_->getPlayer() != this))
-            this->pawn_->setPlayer(this);
+            this->startControl(entity);
+        }
+        else
+        {
+            this->stopControl(this->controllableEntity_);
+        }
     }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h	(revision 2019)
@@ -41,67 +41,46 @@
     {
         public:
-            PlayerInfo();
+            PlayerInfo(BaseObject* creator);
             virtual ~PlayerInfo();
 
-            void setConfigValues();
             void registerVariables();
 
             virtual void changedName();
-
-            inline void setClientID(unsigned int clientID)
-                { this->clientID_ = clientID; this->checkClientID(); }
-            inline unsigned int getClientID() const
-                { return this->clientID_; }
+            virtual void changedGametype();
 
             inline bool isHumanPlayer() const
                 { return this->bHumanPlayer_; }
-
             inline bool isLocalPlayer() const
                 { return this->bLocalPlayer_; }
+            inline unsigned int getClientID() const
+                { return this->clientID_; }
+            inline bool isReadyToSpawn() const
+                { return this->bReadyToSpawn_; }
 
-            virtual void startControl(ControllableEntity* pawn);
-            virtual void stopControl();
+            virtual bool isReady() const = 0;
+            virtual float getPing() const = 0;
+            virtual float getPacketLossRatio() const = 0;
 
-            inline ControllableEntity* getPawn() const
-                { return this->pawn_; }
-/*
-            inline void setController(Controller* controller)
-                { this->controller_ = controller; }
-            inline Controller* getController() const
-                { return this->controller_; }
-*/
-            inline void setGametype(Gametype* gametype)
-                { this->gametype_ = gametype; }
-            inline Gametype* getGametype() const
-                { return this->gametype_; }
+            inline void setReadyToSpawn(bool bReady)
+                { this->bReadyToSpawn_ = bReady; }
+
+            void startControl(ControllableEntity* entity);
+            void stopControl(ControllableEntity* entity);
+
+            inline ControllableEntity* getControllableEntity() const
+                { return this->controllableEntity_; }
 
         protected:
-            inline void setDefaultController(Identifier* identifier)
-                { this->defaultController_ = identifier; }
+            void createController();
+            void networkcallback_changedcontrollableentityID();
 
-        private:
-            virtual void createController();
-            virtual void takeLocalControl();
-
-            void checkClientID();
-            void finishedSetup();
-            void checkNick();
-            void clientChangedName();
-            void updatePawn();
-
+            bool bHumanPlayer_;
+            bool bLocalPlayer_;
+            bool bReadyToSpawn_;
+            SubclassIdentifier<Controller> defaultController_;
+            Controller* controller_;
+            ControllableEntity* controllableEntity_;
+            unsigned int controllableEntityID_;
             unsigned int clientID_;
-            float ping_;
-            bool bLocalPlayer_;
-            bool bHumanPlayer_;
-            bool bFinishedSetup_;
-
-            std::string playerName_;
-            std::string nick_;
-
-            ControllableEntity* pawn_;
-            unsigned int pawnID_;
-            Controller* controller_;
-            SubclassIdentifier<Controller> defaultController_;
-            Gametype* gametype_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.cc	(revision 2019)
@@ -43,5 +43,5 @@
     CreateFactory(ControllableEntity);
 
-    ControllableEntity::ControllableEntity()
+    ControllableEntity::ControllableEntity(BaseObject* creator) : WorldEntity(creator)
     {
         RegisterObject(ControllableEntity);
@@ -71,6 +71,15 @@
     ControllableEntity::~ControllableEntity()
     {
-        if (this->isInitialized() && this->bControlled_)
-            this->stopLocalControl();
+        if (this->isInitialized())
+        {
+            if (this->bControlled_)
+                this->stopLocalControl();
+
+            if (this->hud_)
+                delete this->hud_;
+
+            if (this->camera_)
+                delete this->camera_;
+        }
     }
 
@@ -92,10 +101,12 @@
         this->player_ = player;
         this->playerID_ = player->getObjectID();
-        this->bControlled_ = player->isLocalPlayer();
+        this->bControlled_ = (player->isLocalPlayer() && player->isHumanPlayer());
 
         if (this->bControlled_)
         {
             this->startLocalControl();
-            this->setObjectMode(network::direction::bidirectional);
+
+            if (!Core::isMaster())
+                this->setObjectMode(network::direction::bidirectional);
         }
     }
@@ -115,10 +126,11 @@
     }
 
-    void ControllableEntity::updatePlayer()
-    {
+    void ControllableEntity::networkcallback_changedplayerID()
+    {
+        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
         if (this->playerID_ != network::OBJECTID_UNKNOWN)
         {
             this->player_ = dynamic_cast<PlayerInfo*>(network::Synchronisable::getSynchronisable(this->playerID_));
-            if (this->player_ && (this->player_->getPawn() != this))
+            if (this->player_ && (this->player_->getControllableEntity() != this))
                 this->player_->startControl(this);
         }
@@ -128,5 +140,5 @@
     {
         std::cout << this->getObjectID() << " ###### start local control" << std::endl;
-        this->camera_ = new Camera();
+        this->camera_ = new Camera(this);
         this->camera_->requestFocus();
         this->attach(this->camera_);
@@ -134,5 +146,5 @@
         if (this->hudtemplate_ != "")
         {
-            this->hud_ = new OverlayGroup();
+            this->hud_ = new OverlayGroup(this);
             this->hud_->addTemplate(this->hudtemplate_);
         }
@@ -184,5 +196,5 @@
         REGISTERDATA(this->client_overwrite_,   network::direction::toserver);
 
-        REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::updatePlayer));
+        REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
     }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2019)
@@ -40,5 +40,5 @@
     {
         public:
-            ControllableEntity();
+            ControllableEntity(BaseObject* creator);
             virtual ~ControllableEntity();
 
@@ -56,7 +56,4 @@
             inline bool getDestroyWhenPlayerLeft() const
                 { return this->bDestroyWhenPlayerLeft_; }
-
-            virtual void startLocalControl();
-            virtual void stopLocalControl();
 
             virtual void moveFrontBack(float value) {}
@@ -82,5 +79,4 @@
                 { return this->hudtemplate_; }
 
-        protected:
             using WorldEntity::setPosition;
             using WorldEntity::translate;
@@ -112,4 +108,8 @@
                 { this->acceleration_.x = x; this->acceleration_.y = y; this->acceleration_.z = z; }
 
+        protected:
+            virtual void startLocalControl();
+            virtual void stopLocalControl();
+
             inline void setHudTemplate(const std::string& name)
                 { this->hudtemplate_ = name; }
@@ -130,5 +130,5 @@
             void processClientOrientation();
 
-            void updatePlayer();
+            void networkcallback_changedplayerID();
 
             unsigned int server_overwrite_;
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.cc	(revision 2019)
@@ -32,4 +32,5 @@
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
+#include "objects/Scene.h"
 
 namespace orxonox
@@ -37,5 +38,5 @@
     CreateFactory(Model);
 
-    Model::Model()
+    Model::Model(BaseObject* creator) : PositionableEntity(creator)
     {
         RegisterObject(Model);
@@ -69,5 +70,5 @@
             this->getNode()->detachObject(this->mesh_.getEntity());
 
-        this->mesh_.setMeshSource(this->meshSrc_);
+        this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
 
         if (this->mesh_.getEntity())
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/Model.h	(revision 2019)
@@ -39,5 +39,5 @@
     {
         public:
-            Model();
+            Model(BaseObject* creator);
             virtual ~Model();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.cc	(revision 2019)
@@ -41,5 +41,5 @@
     CreateFactory(MovableEntity);
 
-    MovableEntity::MovableEntity()
+    MovableEntity::MovableEntity(BaseObject* creator) : WorldEntity(creator)
     {
         RegisterObject(MovableEntity);
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/MovableEntity.h	(revision 2019)
@@ -41,5 +41,5 @@
     {
         public:
-            MovableEntity();
+            MovableEntity(BaseObject* creator);
             virtual ~MovableEntity();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.cc	(revision 2019)
@@ -35,5 +35,5 @@
     CreateFactory(PositionableEntity);
 
-    PositionableEntity::PositionableEntity()
+    PositionableEntity::PositionableEntity(BaseObject* creator) : WorldEntity(creator)
     {
         RegisterObject(PositionableEntity);
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/PositionableEntity.h	(revision 2019)
@@ -38,5 +38,5 @@
     {
         public:
-            PositionableEntity();
+            PositionableEntity(BaseObject* creator);
             virtual ~PositionableEntity();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2019)
@@ -0,0 +1,91 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "SpawnPoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "objects/gametypes/Gametype.h"
+
+namespace orxonox
+{
+    CreateFactory(SpawnPoint);
+
+    SpawnPoint::SpawnPoint(BaseObject* creator) : PositionableEntity(creator)
+    {
+        RegisterObject(SpawnPoint);
+
+        this->template_ = 0;
+
+        if (this->getGametype())
+            this->getGametype()->registerSpawnPoint(this);
+        else
+            COUT(1) << "Error: SpawnPoint has no Gametype" << std::endl;
+
+        this->setObjectMode(0x0);
+    }
+
+    void SpawnPoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SpawnPoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SpawnPoint, "spawnclass", setSpawnClassName, getSpawnClassName, xmlelement, mode);
+        XMLPortParam(SpawnPoint, "design", setTemplateName, getTemplateName, xmlelement, mode);
+    }
+
+    void SpawnPoint::setSpawnClassName(const std::string& name)
+    {
+        this->spawnclassname_ = name;
+        this->spawnclass_ = ClassByString(name);
+    }
+
+    void SpawnPoint::setTemplateName(const std::string& name)
+    {
+        this->templatename_ = name;
+        this->template_ = Template::getTemplate(name);
+    }
+
+    ControllableEntity* SpawnPoint::spawn()
+    {
+        ControllableEntity* entity = this->spawnclass_.fabricate(this);
+        if (entity)
+        {
+            this->spawn(entity);
+            if (this->template_)
+                entity->addTemplate(this->template_);
+        }
+        return entity;
+    }
+
+    void SpawnPoint::spawn(ControllableEntity* entity)
+    {
+        entity->setPosition(this->getPosition());
+        entity->setOrientation(this->getOrientation());
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2019)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2019)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SpawnPoint_H__
+#define _SpawnPoint_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/Identifier.h"
+#include "core/Template.h"
+#include "PositionableEntity.h"
+#include "ControllableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SpawnPoint : public PositionableEntity
+    {
+        public:
+            SpawnPoint(BaseObject* creator);
+            virtual ~SpawnPoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setSpawnClass(Identifier* identifier)
+                { this->spawnclass_ = identifier; this->spawnclassname_ = identifier->getName(); }
+            inline Identifier* getSpawnClass() const
+                { return this->spawnclass_; }
+
+            inline void setTemplate(Template* temp)
+                { this->template_ = temp; this->templatename_ = temp->getName(); }
+            inline Template* getTemplate() const
+                { return this->template_; }
+
+            ControllableEntity* spawn();
+            void spawn(ControllableEntity* entity);
+
+        public:
+            void setSpawnClassName(const std::string& name);
+            inline const std::string& getSpawnClassName() const
+                { return this->spawnclassname_; }
+
+            void setTemplateName(const std::string& name);
+            inline const std::string& getTemplateName() const
+                { return this->templatename_; }
+
+            SubclassIdentifier<ControllableEntity> spawnclass_;
+            std::string spawnclassname_;
+            Template* template_;
+            std::string templatename_;
+    };
+}
+
+#endif /* _SpawnPoint_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.cc	(revision 2019)
@@ -30,4 +30,5 @@
 #include "WorldEntity.h"
 
+#include <cassert>
 #include <OgreSceneManager.h>
 
@@ -37,4 +38,5 @@
 
 #include "GraphicsEngine.h"
+#include "objects/Scene.h"
 
 namespace orxonox
@@ -47,9 +49,13 @@
     const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
 
-    WorldEntity::WorldEntity()
+    WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(WorldEntity);
 
-        this->node_ = GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->createChildSceneNode();
+        assert(this->getScene());
+        assert(this->getScene()->getRootSceneNode());
+
+        this->node_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+
         this->parent_ = 0;
         this->parentID_ = (unsigned int)-1;
@@ -66,8 +72,8 @@
         {
             this->node_->detachAllObjects();
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroySceneNode(this->node_->getName());
+            if (this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
         }
     }
-
 
     void WorldEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
@@ -131,5 +137,5 @@
         object->parentID_ = (unsigned int)-1;
 
-        GraphicsEngine::getInstance().getLevelSceneManager()->getRootSceneNode()->addChild(object->node_);
+        this->getScene()->getRootSceneNode()->addChild(object->node_);
     }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/WorldEntity.h	(revision 2019)
@@ -45,5 +45,5 @@
     {
         public:
-            WorldEntity();
+            WorldEntity(BaseObject* creator);
             virtual ~WorldEntity();
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2019)
@@ -33,4 +33,6 @@
 #include "core/Core.h"
 #include "objects/worldentities/Model.h"
+#include "objects/Scene.h"
+#include "objects/infos/PlayerInfo.h"
 #include "tools/BillboardSet.h"
 
@@ -39,5 +41,5 @@
     CreateFactory(Spectator);
 
-    Spectator::Spectator()
+    Spectator::Spectator(BaseObject* creator) : ControllableEntity(creator)
     {
         RegisterObject(Spectator);
@@ -54,8 +56,9 @@
 
         // test test test
+        if (this->getScene()->getSceneManager())
         {
             this->testmesh_ = new Mesh();
             this->testnode_ = this->getNode()->createChildSceneNode();
-            this->testmesh_->setMeshSource("assff.mesh");
+            this->testmesh_->setMeshSource(this->getScene()->getSceneManager(), "assff.mesh");
             if (this->testmesh_->getEntity())
                 this->testnode_->attachObject(this->testmesh_->getEntity());
@@ -64,8 +67,13 @@
             this->testnode_->scale(10, 10, 10);
         }
+        else
+        {
+            this->testmesh_ = 0;
+            this->testnode_ = 0;
+        }
         // test test test
 
         this->greetingFlare_ = new BillboardSet();
-        this->greetingFlare_->setBillboardSet("Examples/Flare", ColourValue(1.0, 1.0, 0.8), Vector3(0, 20, 0), 1);
+        this->greetingFlare_->setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 1.0, 0.8), Vector3(0, 20, 0), 1);
         this->getNode()->attachObject(this->greetingFlare_->getBillboardSet());
         this->greetingFlare_->setVisible(false);
@@ -80,10 +88,20 @@
         if (this->isInitialized())
         {
-            delete this->greetingFlare_;
+            if (this->greetingFlare_)
+            {
+                this->getNode()->detachObject(this->greetingFlare_->getBillboardSet());
+                delete this->greetingFlare_;
+            }
 
             // test test test
             {
-                delete this->testmesh_;
-                delete this->testnode_;
+                if (this->testmesh_ && this->testnode_)
+                    this->testnode_->detachObject(this->testmesh_->getEntity());
+
+                if (this->testmesh_)
+                    delete this->testmesh_;
+
+                if (this->testnode_)
+                    this->getNode()->removeAndDestroyChild(this->testnode_->getName());
             }
             // test test test
@@ -177,4 +195,6 @@
     void Spectator::fire()
     {
+        if (this->getPlayer())
+            this->getPlayer()->setReadyToSpawn(true);
     }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2019)
@@ -39,5 +39,5 @@
     {
         public:
-            Spectator();
+            Spectator(BaseObject* creator);
             virtual ~Spectator();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 2019)
@@ -55,6 +55,7 @@
     SetConsoleCommand(OrxonoxOverlay, rotateOverlay, false).accessLevel(AccessLevel::User);
 
-    OrxonoxOverlay::OrxonoxOverlay()
-        : overlay_(0)
+    OrxonoxOverlay::OrxonoxOverlay(BaseObject* creator)
+        : BaseObject(creator)
+        , overlay_(0)
         , background_(0)
     {
@@ -148,5 +149,5 @@
             return this->background_->getMaterialName();
         else
-            return blankString;
+            return BLANKSTRING;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OrxonoxOverlay.h	(revision 2019)
@@ -84,5 +84,5 @@
 
     public:
-        OrxonoxOverlay();
+        OrxonoxOverlay(BaseObject* creator);
         virtual ~OrxonoxOverlay();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc	(revision 2019)
@@ -50,5 +50,5 @@
     SetConsoleCommand(OverlayGroup, scrollGroup, false).accessLevel(AccessLevel::User);
 
-    OverlayGroup::OverlayGroup()
+    OverlayGroup::OverlayGroup(BaseObject* creator) : BaseObject(creator)
     {
         RegisterObject(OverlayGroup);
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h	(revision 2019)
@@ -54,5 +54,5 @@
     {
     public:
-        OverlayGroup();
+        OverlayGroup(BaseObject* creator);
         //! Empty destructor.
         ~OverlayGroup() { }
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc	(revision 2019)
@@ -41,6 +41,5 @@
     CreateFactory(OverlayText);
 
-    OverlayText::OverlayText()
-        : text_(0)
+    OverlayText::OverlayText(BaseObject* creator) : OrxonoxOverlay(creator), text_(0)
     {
         RegisterObject(OverlayText);
@@ -60,5 +59,5 @@
         {
             this->text_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("TextArea", "OverlayText_text_" + getUniqueNumberStr()));
+                .createOverlayElement("TextArea", "OverlayText_text_" + getUniqueNumberString()));
             this->text_->setCharHeight(1.0);
 
@@ -84,5 +83,5 @@
             return this->text_->getFontName();
         else
-            return blankString;
+            return BLANKSTRING;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h	(revision 2019)
@@ -42,5 +42,5 @@
     {
     public:
-        OverlayText();
+        OverlayText(BaseObject* creator);
         virtual ~OverlayText();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.cc	(revision 2019)
@@ -38,5 +38,5 @@
     CreateFactory(DebugFPSText);
 
-    DebugFPSText::DebugFPSText()
+    DebugFPSText::DebugFPSText(BaseObject* creator) : OverlayText(creator)
     {
         RegisterObject(DebugFPSText);
Index: code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugFPSText.h	(revision 2019)
@@ -40,5 +40,5 @@
     {
     public:
-        DebugFPSText();
+        DebugFPSText(BaseObject* creator);
         ~DebugFPSText();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.cc	(revision 2019)
@@ -38,5 +38,5 @@
     CreateFactory(DebugRTRText);
 
-    DebugRTRText::DebugRTRText()
+    DebugRTRText::DebugRTRText(BaseObject* creator) : OverlayText(creator)
     {
         RegisterObject(DebugRTRText);
Index: code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/debug/DebugRTRText.h	(revision 2019)
@@ -40,5 +40,5 @@
     {
     public:
-        DebugRTRText();
+        DebugRTRText(BaseObject* creator);
         ~DebugRTRText();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.cc	(revision 2019)
@@ -39,5 +39,5 @@
 
 #include "GraphicsEngine.h"
-#include "objects/infos/Level.h"
+#include "LevelManager.h"
 #include "objects/infos/PlayerInfo.h"
 #include "overlays/console/InGameConsole.h"
@@ -50,5 +50,5 @@
     CreateFactory(ChatOverlay);
 
-    ChatOverlay::ChatOverlay()
+    ChatOverlay::ChatOverlay(BaseObject* creator) : OverlayText(creator)
     {
         RegisterObject(ChatOverlay);
@@ -76,5 +76,5 @@
             std::string name = "unknown";
 
-            PlayerInfo* player = Level::getClient(senderID);
+            PlayerInfo* player = LevelManager::getInstance().getClient(senderID);
             if (player)
                 name = player->getName();
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/ChatOverlay.h	(revision 2019)
@@ -42,5 +42,5 @@
     {
         public:
-            ChatOverlay();
+            ChatOverlay(BaseObject* creator);
             ~ChatOverlay();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.cc	(revision 2019)
@@ -38,4 +38,5 @@
 
 #include "util/Convert.h"
+#include "util/String.h"
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
@@ -45,6 +46,5 @@
     CreateFactory(BarColour);
 
-    BarColour::BarColour()
-        : position_(0.0)
+    BarColour::BarColour(BaseObject* creator) : BaseObject(creator), position_(0.0)
     {
         RegisterObject(BarColour);
@@ -63,7 +63,5 @@
     unsigned int HUDBar::materialcount_s = 0;
 
-    HUDBar::HUDBar()
-        : bar_(0)
-        , textureUnitState_(0)
+    HUDBar::HUDBar(BaseObject* creator) : OrxonoxOverlay(creator), bar_(0), textureUnitState_(0)
     {
         RegisterObject(HUDBar);
@@ -92,5 +90,5 @@
 
             this->bar_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("Panel", "HUDBar_bar_" + getUniqueNumberStr()));
+                .createOverlayElement("Panel", "HUDBar_bar_" + getUniqueNumberString()));
             this->bar_->setMaterialName(materialname);
             this->background_->addChild(bar_);
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDBar.h	(revision 2019)
@@ -44,5 +44,5 @@
     {
     public:
-        BarColour();
+        BarColour(BaseObject* creator);
         ~BarColour() { }
 
@@ -64,5 +64,5 @@
     {
     public:
-        HUDBar();
+        HUDBar(BaseObject* creator);
         virtual ~HUDBar();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.cc	(revision 2019)
@@ -46,6 +46,7 @@
     CreateFactory(HUDNavigation);
 
-    HUDNavigation::HUDNavigation()
-        : navMarker_(0)
+    HUDNavigation::HUDNavigation(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+        , navMarker_(0)
         , aimMarker_(0)
         , navText_(0)
@@ -72,9 +73,9 @@
             // create nav text
             navText_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberStr()));
+                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
 
             // create nav marker
             navMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberStr()));
+                .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
             navMarker_->setMaterialName("Orxonox/NavArrows");
             wasOutOfView_ = true; // just to ensure the material is changed right the first time..
@@ -82,5 +83,5 @@
             // create aim marker
             aimMarker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("Panel", "HUDNavigation_aimMarker_" + getUniqueNumberStr()));
+                .createOverlayElement("Panel", "HUDNavigation_aimMarker_" + getUniqueNumberString()));
             aimMarker_->setMaterialName("Orxonox/NavCrosshair");
 
@@ -112,5 +113,5 @@
             return this->navText_->getFontName();
         else
-            return blankString;
+            return BLANKSTRING;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDNavigation.h	(revision 2019)
@@ -41,5 +41,5 @@
     {
     public:
-        HUDNavigation();
+        HUDNavigation(BaseObject* creator);
         ~HUDNavigation();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.cc	(revision 2019)
@@ -35,4 +35,5 @@
 
 #include "util/Math.h"
+#include "util/String.h"
 #include "core/ConsoleCommand.h"
 #include "core/CoreIncludes.h"
@@ -45,6 +46,5 @@
     CreateFactory(HUDRadar);
 
-    HUDRadar::HUDRadar()
-        : marker_(0)
+    HUDRadar::HUDRadar(BaseObject* creator) : OrxonoxOverlay(creator), marker_(0)
     {
         RegisterObject(HUDRadar);
@@ -69,5 +69,5 @@
         {
             marker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
-                .createOverlayElement("Panel", "HUDRadar_marker_" + getUniqueNumberStr()));
+                .createOverlayElement("Panel", "HUDRadar_marker_" + getUniqueNumberString()));
             marker_->setMaterialName("Orxonox/RadarMarker");
             overlay_->add2D(marker_);
@@ -107,5 +107,5 @@
             // we have to create a new entry
             panel = static_cast<Ogre::PanelOverlayElement*>(
-                Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "RadarDot" + getUniqueNumberStr()));
+                Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "RadarDot" + getUniqueNumberString()));
             radarDots_.push_back(panel);
             // get right material
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDRadar.h	(revision 2019)
@@ -45,5 +45,5 @@
     {
     public:
-        HUDRadar();
+        HUDRadar(BaseObject* creator);
         ~HUDRadar();
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.cc	(revision 2019)
@@ -36,5 +36,5 @@
     CreateFactory(HUDSpeedBar);
 
-    HUDSpeedBar::HUDSpeedBar()
+    HUDSpeedBar::HUDSpeedBar(BaseObject* creator) : HUDBar(creator)
     {
         RegisterObject(HUDSpeedBar);
Index: code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/overlays/hud/HUDSpeedBar.h	(revision 2019)
@@ -41,5 +41,5 @@
     {
     public:
-        HUDSpeedBar();
+        HUDSpeedBar(BaseObject* creator);
         ~HUDSpeedBar();
 
Index: code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.cc	(revision 2019)
@@ -31,5 +31,5 @@
 
 #include <sstream>
-
+#include <cassert>
 #include <OgreSceneManager.h>
 
@@ -46,44 +46,60 @@
     }
 
-    void BillboardSet::setBillboardSet(const std::string& file, int count)
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count)
     {
+        assert(scenemanager);
+
         std::ostringstream name;
         name << (BillboardSet::billboardSetCounter_s++);
-        this->billboardSet_ = GraphicsEngine::getInstance().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
+        this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + name.str(), count);
         this->billboardSet_->createBillboard(Vector3::ZERO);
         this->billboardSet_->setMaterialName(file);
+
+        this->scenemanager_ = scenemanager;
     }
 
-    void BillboardSet::setBillboardSet(const std::string& file, const ColourValue& colour, int count)
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count)
     {
+        assert(scenemanager);
+
         std::ostringstream name;
         name << (BillboardSet::billboardSetCounter_s++);
-        this->billboardSet_ = GraphicsEngine::getInstance().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
+        this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + name.str(), count);
         this->billboardSet_->createBillboard(Vector3::ZERO, colour);
         this->billboardSet_->setMaterialName(file);
+
+        this->scenemanager_ = scenemanager;
     }
 
-    void BillboardSet::setBillboardSet(const std::string& file, const Vector3& position, int count)
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count)
     {
+        assert(scenemanager);
+
         std::ostringstream name;
         name << (BillboardSet::billboardSetCounter_s++);
-        this->billboardSet_ = GraphicsEngine::getInstance().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
+        this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + name.str(), count);
         this->billboardSet_->createBillboard(position);
         this->billboardSet_->setMaterialName(file);
+
+        this->scenemanager_ = scenemanager;
     }
 
-    void BillboardSet::setBillboardSet(const std::string& file, const ColourValue& colour, const Vector3& position, int count)
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count)
     {
+        assert(scenemanager);
+
         std::ostringstream name;
         name << (BillboardSet::billboardSetCounter_s++);
-        this->billboardSet_ = GraphicsEngine::getInstance().getLevelSceneManager()->createBillboardSet("Billboard" + name.str(), count);
+        this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + name.str(), count);
         this->billboardSet_->createBillboard(position, colour);
         this->billboardSet_->setMaterialName(file);
+
+        this->scenemanager_ = scenemanager;
     }
 
     BillboardSet::~BillboardSet()
     {
-        if (this->billboardSet_)
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroyBillboardSet(this->billboardSet_);
+        if (this->billboardSet_ && this->scenemanager_)
+            this->scenemanager_->destroyBillboardSet(this->billboardSet_);
     }
 }
Index: code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/BillboardSet.h	(revision 2019)
@@ -44,8 +44,8 @@
             BillboardSet();
             ~BillboardSet();
-            void setBillboardSet(const std::string& file, int count = 1);
-            void setBillboardSet(const std::string& file, const ColourValue& colour, int count = 1);
-            void setBillboardSet(const std::string& file, const Vector3& position, int count = 1);
-            void setBillboardSet(const std::string& file, const ColourValue& colour, const Vector3& position, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count = 1);
 
             inline Ogre::BillboardSet* getBillboardSet()
@@ -63,4 +63,5 @@
             static unsigned int billboardSetCounter_s;
             Ogre::BillboardSet* billboardSet_;
+            Ogre::SceneManager* scenemanager_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/tools/Light.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/Light.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/Light.cc	(revision 2019)
@@ -31,4 +31,5 @@
 
 #include <sstream>
+#include <cassert>
 
 #include <OgreSceneManager.h>
@@ -45,18 +46,22 @@
     }
 
-    void Light::setLight(Ogre::Light::LightTypes type, const ColourValue& diffuse, const ColourValue& specular)
+    void Light::setLight(Ogre::SceneManager* scenemanager, Ogre::Light::LightTypes type, const ColourValue& diffuse, const ColourValue& specular)
     {
+        assert(scenemanager);
+
         std::ostringstream name;
         name << (Light::lightCounter_s++);
-        this->light_ = GraphicsEngine::getInstance().getLevelSceneManager()->createLight("Light" + name.str());
+        this->light_ = scenemanager->createLight("Light" + name.str());
         this->light_->setType(type);
         this->light_->setDiffuseColour(diffuse);
         this->light_->setSpecularColour(specular);
+
+        this->scenemanager_ = scenemanager;
     }
 
     Light::~Light()
     {
-        if (this->light_)
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroyLight(this->light_);
+        if (this->light_ && this->scenemanager_)
+            this->scenemanager_->destroyLight(this->light_);
     }
 }
Index: code/branches/objecthierarchy/src/orxonox/tools/Light.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/Light.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/Light.h	(revision 2019)
@@ -45,5 +45,5 @@
             Light();
             ~Light();
-            void setLight(Ogre::Light::LightTypes type = Ogre::Light::LT_POINT, const ColourValue& diffuse = ColourValue(1.0, 1.0, 1.0), const ColourValue& specular = ColourValue(1.0, 1.0, 1.0));
+            void setLight(Ogre::SceneManager* scenemanager, Ogre::Light::LightTypes type = Ogre::Light::LT_POINT, const ColourValue& diffuse = ColourValue(1.0, 1.0, 1.0), const ColourValue& specular = ColourValue(1.0, 1.0, 1.0));
 
             inline Ogre::Light* getLight()
@@ -56,4 +56,5 @@
             static unsigned int lightCounter_s;
             Ogre::Light* light_;
+            Ogre::SceneManager* scenemanager_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/tools/Mesh.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/Mesh.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/Mesh.cc	(revision 2019)
@@ -32,4 +32,5 @@
 #include <sstream>
 #include <OgreSceneManager.h>
+#include <cassert>
 
 #include "core/Core.h"
@@ -50,24 +51,25 @@
     Mesh::~Mesh()
     {
-        if (this->entity_ && Core::showsGraphics())
-            GraphicsEngine::getInstance().getLevelSceneManager()->destroyEntity(this->entity_);
+        if (this->entity_ && this->scenemanager_)
+            this->scenemanager_->destroyEntity(this->entity_);
     }
 
-    void Mesh::setMeshSource(const std::string& meshsource)
+    void Mesh::setMeshSource(Ogre::SceneManager* scenemanager, const std::string& meshsource)
     {
-        if (Core::showsGraphics())
+        assert(scenemanager);
+
+        this->scenemanager_ = scenemanager;
+
+        if (this->entity_)
+            this->scenemanager_->destroyEntity(this->entity_);
+
+        try
         {
-            if (this->entity_)
-                GraphicsEngine::getInstance().getLevelSceneManager()->destroyEntity(this->entity_);
-
-            try
-            {
-                this->entity_ = GraphicsEngine::getInstance().getLevelSceneManager()->createEntity("Mesh" + convertToString(Mesh::meshCounter_s++), meshsource);
-                this->entity_->setCastShadows(this->bCastShadows_);
-            }
-            catch (...)
-            {
-                COUT(1) << "Error: Couln't load mesh \"" << meshsource << "\"" << std::endl;
-            }
+            this->entity_ = this->scenemanager_->createEntity("Mesh" + convertToString(Mesh::meshCounter_s++), meshsource);
+            this->entity_->setCastShadows(this->bCastShadows_);
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load mesh \"" << meshsource << "\"" << std::endl;
         }
     }
@@ -85,5 +87,5 @@
             return this->entity_->getName();
         else
-            return blankString;
+            return BLANKSTRING;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/tools/Mesh.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/Mesh.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/Mesh.h	(revision 2019)
@@ -43,5 +43,5 @@
             ~Mesh();
 
-            void setMeshSource(const std::string& file);
+            void setMeshSource(Ogre::SceneManager* scenemanager, const std::string& file);
 
             inline Ogre::Entity* getEntity()
@@ -61,4 +61,5 @@
             Ogre::Entity* entity_;
             bool bCastShadows_;
+            Ogre::SceneManager* scenemanager_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.cc	(revision 2019)
@@ -37,4 +37,5 @@
 #include <OgreParticleEmitter.h>
 #include <OgreSceneManager.h>
+#include <cassert>
 
 #include "GraphicsEngine.h"
@@ -47,12 +48,15 @@
   ParticleInterface* ParticleInterface::currentParticleInterface_s = 0;
 
-  ParticleInterface::ParticleInterface(const std::string& templateName, LODParticle::LOD detaillevel)
+  ParticleInterface::ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::LOD detaillevel)
   {
     RegisterRootObject(ParticleInterface);
 
+    assert(scenemanager);
+
+    this->scenemanager_ = scenemanager;
     this->sceneNode_ = 0;
     this->bEnabled_ = true;
     this->detaillevel_ = (unsigned int)detaillevel;
-    this->particleSystem_ = GraphicsEngine::getInstance().getLevelSceneManager()->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName);
+    this->particleSystem_ = this->scenemanager_->createParticleSystem("particles" + getConvertedValue<unsigned int, std::string>(ParticleInterface::counter_s++), templateName);
     //this->particleSystem_->setSpeedFactor(Orxonox::getInstance().getTimeFactor());
     this->particleSystem_->setSpeedFactor(1.0f);
@@ -72,5 +76,5 @@
   {
     this->particleSystem_->removeAllEmitters();
-    GraphicsEngine::getInstance().getLevelSceneManager()->destroyParticleSystem(particleSystem_);
+    this->scenemanager_->destroyParticleSystem(particleSystem_);
   }
 
Index: code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/tools/ParticleInterface.h	(revision 2019)
@@ -48,5 +48,5 @@
   {
     public:
-      ParticleInterface(const std::string& templateName, LODParticle::LOD detaillevel);
+      ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::LOD detaillevel);
       ~ParticleInterface();
 
@@ -92,4 +92,5 @@
       bool bEnabled_;
       unsigned int detaillevel_;                            //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
+      Ogre::SceneManager* scenemanager_;
   };
 }
