Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.cc	(revision 2023)
@@ -40,5 +40,5 @@
 
     GSClient::GSClient()
-        : GSLevel("client")
+        : GameState<GSGraphics>("client")
         , client_(0)
     {
@@ -53,6 +53,4 @@
         Core::setIsClient(true);
 
-        GSLevel::enter();
-
         this->client_ = new network::Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port"));
 
@@ -60,15 +58,12 @@
             ThrowException(InitialisationFailed, "Could not establish connection with server.");
 
+        GSLevel::enter(this->getParent()->getViewport());
+
         client_->tick(0);
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
     }
 
     void GSClient::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: How do we unload the level in client mode?
+        GSLevel::leave();
 
         client_->closeConnection();
@@ -76,6 +71,4 @@
         // destroy client
         delete this->client_;
-
-        GSLevel::leave();
 
         Core::setIsClient(false);
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSClient.h	(revision 2023)
@@ -33,8 +33,9 @@
 #include "network/NetworkPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSClient : public GSLevel
+    class _OrxonoxExport GSClient : public GameState<GSGraphics>, public GSLevel
     {
     public:
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.cc	(revision 2023)
@@ -30,15 +30,7 @@
 #include "GSDedicated.h"
 
-#include <OgreRoot.h>
-#include <OgreSceneManager.h>
-#include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
-#include "core/Loader.h"
-#include "core/XMLFile.h"
 #include "core/Core.h"
 #include "network/Server.h"
-#include "objects/Tickable.h"
-#include "Settings.h"
-#include "GraphicsEngine.h"
 
 namespace orxonox
@@ -46,8 +38,5 @@
     GSDedicated::GSDedicated()
         : GameState<GSRoot>("dedicated")
-        , timeFactor_(0)
         , server_(0)
-        , sceneManager_(0)
-        , startFile_(0)
     {
     }
@@ -61,40 +50,18 @@
         Core::setHasServer(true);
 
-        // create Ogre SceneManager for the level
-        this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
-        COUT(4) << "Created SceneManager: " << sceneManager_->getName() << std::endl;
+        this->server_ = new network::Server(CommandLine::getValue("port"));
+        COUT(0) << "Loading scene in server mode" << std::endl;
 
-        // temporary hack
-        GraphicsEngine::getInstance().setLevelSceneManager(this->sceneManager_);
-
-        // reset game speed to normal
-        timeFactor_ = 1.0f;
-
-        this->server_ = new network::Server(CommandLine::getValue("port"));
-
-        // call the loader
-        COUT(0) << "Loading level..." << std::endl;
-        startFile_ = new XMLFile(Settings::getDataPath() + "levels/sample.oxw");
-        Loader::open(startFile_);
+        GSLevel::enter(0);
 
         server_->open();
-
-        // add console commands
-        FunctorMember01<GSDedicated, float>* functor = createFunctor(&GSDedicated::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
     }
 
     void GSDedicated::leave()
     {
-        // TODO: Remove and destroy console command
-
-        Loader::unload(startFile_);
-        delete this->startFile_;
+        GSLevel::leave();
 
         this->server_->close();
         delete this->server_;
-
-        Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
 
         Core::setHasServer(false);
@@ -103,19 +70,7 @@
     void GSDedicated::ticked(const Clock& time)
     {
-        // Call the scene objects
-        for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
-            it->tick(time.getDeltaTime() * this->timeFactor_);
-
+        GSLevel::ticked(time);
         server_->tick(time.getDeltaTime());
         this->tickChild(time);
     }
-
-    /**
-    @brief
-        Changes the speed of Orxonox
-    */
-    void GSDedicated::setTimeFactor(float factor)
-    {
-        this->timeFactor_ = factor;
-    }
 }
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSDedicated.h	(revision 2023)
@@ -32,16 +32,14 @@
 #include "OrxonoxPrereqs.h"
 #include "network/NetworkPrereqs.h"
+#include "GSLevel.h"
 #include "GSRoot.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSDedicated : public GameState<GSRoot>
+    class _OrxonoxExport GSDedicated : public GameState<GSRoot>, public GSLevel
     {
     public:
         GSDedicated();
         ~GSDedicated();
-
-        void setTimeFactor(float factor);
-        float getTimeFactor() { return this->timeFactor_; }
 
     private:
@@ -50,11 +48,5 @@
         void ticked(const Clock& time);
 
-        void loadLevel();
-        void unloadLevel();
-
-        float                 timeFactor_;       //!< A factor to change the gamespeed
         network::Server*      server_;
-        Ogre::SceneManager*   sceneManager_;
-        XMLFile*              startFile_;        //!< current hard coded default level
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSGUI.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSGUI.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSGUI.cc	(revision 2023)
@@ -31,5 +31,4 @@
 
 #include <OgreViewport.h>
-#include "GraphicsEngine.h"
 #include "core/input/InputManager.h"
 #include "core/input/SimpleInputState.h"
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSGraphics.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSGraphics.cc	(revision 2023)
@@ -116,7 +116,7 @@
 
         // HACK: temporary:
-        graphicsEngine_->renderWindow_  = this->renderWindow_;
-        graphicsEngine_->root_          = this->ogreRoot_;
-        graphicsEngine_->viewport_      = this->viewport_;
+        //graphicsEngine_->renderWindow_  = this->renderWindow_;
+        //graphicsEngine_->root_          = this->ogreRoot_;
+        //graphicsEngine_->viewport_      = this->viewport_;
 
 
@@ -134,5 +134,5 @@
         // Load the InGameConsole
         console_ = new InGameConsole();
-        console_->initialise();
+        console_->initialise(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
 
         // load the CEGUI interface
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSIOConsole.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSIOConsole.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSIOConsole.cc	(revision 2023)
@@ -36,5 +36,4 @@
 
 #include "core/ConsoleCommand.h"
-#include "GraphicsEngine.h"
 
 namespace orxonox
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.cc	(revision 2023)
@@ -30,6 +30,4 @@
 #include "GSLevel.h"
 
-#include <OgreSceneManager.h>
-#include <OgreRoot.h>
 #include "core/input/InputManager.h"
 #include "core/input/SimpleInputState.h"
@@ -41,21 +39,24 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/CoreIncludes.h"
+#include "core/Core.h"
 //#include "objects/Backlight.h"
+#include "objects/CameraHandler.h"
 #include "objects/Tickable.h"
 #include "objects/Radar.h"
 //#include "tools/ParticleInterface.h"
-#include "GraphicsEngine.h"
+#include "LevelManager.h"
 #include "Settings.h"
 
 namespace orxonox
 {
-    GSLevel::GSLevel(const std::string& name)
-        : GameState<GSGraphics>(name)
-        , timeFactor_(1.0f)
-        , sceneManager_(0)
+    GSLevel::GSLevel()
+//        : GameState<GSGraphics>(name)
+        : timeFactor_(1.0f)
         , keyBinder_(0)
         , inputState_(0)
         , radar_(0)
         , startFile_(0)
+        , cameraHandler_(0)
+        , levelManager_(0)
     {
         RegisterObject(GSLevel);
@@ -72,38 +73,58 @@
     }
 
-    void GSLevel::enter()
-    {
-        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
-        keyBinder_ = new KeyBinder();
-        keyBinder_->loadBindings("keybindings.ini");
-        inputState_->setHandler(keyBinder_);
-
-        // create Ogre SceneManager for the level
-        this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
-        COUT(4) << "Created SceneManager: " << sceneManager_->getName() << std::endl;
-
-        this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
-
-        // temporary hack
-        GraphicsEngine::getInstance().setLevelSceneManager(this->sceneManager_);
-
-        // Start the Radar
-        this->radar_ = new Radar();
-
-        // reset game speed to normal
-        timeFactor_ = 1.0f;
-
-        // TODO: insert slomo console command with
-        // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
-
-        // keybind console command
-        FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
-        functor1->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
-        FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
-        functor2->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
-        // set our console command as callback for the key detector
-        InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
+    void GSLevel::enter(Ogre::Viewport* viewport)
+    {
+        if (Core::showsGraphics())
+        {
+            inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
+            keyBinder_ = new KeyBinder();
+            keyBinder_->loadBindings("keybindings.ini");
+            inputState_->setHandler(keyBinder_);
+
+            // create the global CameraHandler
+            assert(viewport);
+            this->cameraHandler_ = new CameraHandler(viewport);
+
+            // Start the Radar
+            this->radar_ = new Radar();
+        }
+
+        if (Core::isMaster())
+        {
+            // create the global LevelManager
+            this->levelManager_ = new LevelManager();
+
+            // reset game speed to normal
+            timeFactor_ = 1.0f;
+
+            this->loadLevel();
+        }
+
+        if (Core::showsGraphics())
+        {
+            // TODO: insert slomo console command with
+            // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
+
+            // keybind console command
+            FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
+            functor1->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
+            FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
+            functor2->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
+            // set our console command as callback for the key detector
+            InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
+
+            // level is loaded: we can start capturing the input
+            InputManager::getInstance().requestEnterState("game");
+        }
+
+        if (Core::isMaster())
+        {
+            // time factor console command
+            FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
+            functor->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
+        }
     }
 
@@ -116,11 +137,26 @@
         //Loader::close();
 
-        delete this->radar_;
-
-        Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
-
-        inputState_->setHandler(0);
-        InputManager::getInstance().requestDestroyState("game");
-        delete this->keyBinder_;
+        if (Core::showsGraphics())
+            InputManager::getInstance().requestLeaveState("game");
+
+        if (Core::isMaster())
+            this->unloadLevel();
+
+        if (this->radar_)
+            delete this->radar_;
+
+        if (this->cameraHandler_)
+            delete this->cameraHandler_;
+
+        if (this->levelManager_)
+            delete this->levelManager_;
+
+        if (Core::showsGraphics())
+        {
+            inputState_->setHandler(0);
+            InputManager::getInstance().requestDestroyState("game");
+            if (this->keyBinder_)
+                delete this->keyBinder_;
+        }
     }
 
@@ -185,33 +221,36 @@
     void GSLevel::keybindInternal(const std::string& command, bool bTemporary)
     {
-        static std::string bindingString = "";
-        static bool bTemporarySaved = false;
-        static bool bound = true;
-        // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
-        // Howerver there will be no real issue if it happens anyway.
-        if (command.find(keyDetectorCallbackCode_) != 0)
-        {
-            if (bound)
+        if (Core::showsGraphics())
+        {
+            static std::string bindingString = "";
+            static bool bTemporarySaved = false;
+            static bool bound = true;
+            // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
+            // Howerver there will be no real issue if it happens anyway.
+            if (command.find(keyDetectorCallbackCode_) != 0)
             {
-                COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
-                InputManager::getInstance().requestEnterState("detector");
-                bindingString = command;
-                bTemporarySaved = bTemporary;
-                bound = false;
+                if (bound)
+                {
+                    COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
+                    InputManager::getInstance().requestEnterState("detector");
+                    bindingString = command;
+                    bTemporarySaved = bTemporary;
+                    bound = false;
+                }
+                //else:  We're still in a keybind command. ignore this call.
             }
-            //else:  We're still in a keybind command. ignore this call.
-        }
-        else
-        {
-            if (!bound)
+            else
             {
-                // user has pressed the key
-                std::string name = command.substr(this->keyDetectorCallbackCode_.size());
-                COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
-                this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
-                InputManager::getInstance().requestLeaveState("detector");
-                bound = true;
+                if (!bound)
+                {
+                    // user has pressed the key
+                    std::string name = command.substr(this->keyDetectorCallbackCode_.size());
+                    COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
+                    this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
+                    InputManager::getInstance().requestLeaveState("detector");
+                    bound = true;
+                }
+                // else: A key was pressed within the same tick, ignore it.
             }
-            // else: A key was pressed within the same tick, ignore it.
         }
     }
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSLevel.h	(revision 2023)
@@ -37,10 +37,10 @@
 namespace orxonox
 {
-    class _OrxonoxExport GSLevel : public GameState<GSGraphics>, public OrxonoxClass
+    class _OrxonoxExport GSLevel : public OrxonoxClass //,public GameState<GSGraphics>
     {
         friend class ClassIdentifier<GSLevel>;
     public:
-        GSLevel(const std::string& name);
-        virtual ~GSLevel();
+        GSLevel();
+        ~GSLevel();
 
         // this has to be public because proteced triggers a bug in msvc
@@ -50,12 +50,12 @@
 
     protected:
-        virtual void enter();
-        virtual void leave();
-        virtual void ticked(const Clock& time);
+        void enter(Ogre::Viewport* viewport);
+        void leave();
+        void ticked(const Clock& time);
 
         void loadLevel();
         void unloadLevel();
 
-        float timeFactor_;       //!< A factor to change the gamespeed
+        float timeFactor_;       //!< A factor that sets the gamespeed. 1 is normal.
 
         // console commands
@@ -64,9 +64,10 @@
         void keybindInternal(const std::string& command, bool bTemporary);
 
-        Ogre::SceneManager*   sceneManager_;
         KeyBinder*            keyBinder_;        //!< tool that loads and manages the input bindings
         SimpleInputState*     inputState_;
         Radar*                radar_;            //!< represents the Radar (not the HUD part)
         XMLFile*              startFile_;        //!< current hard coded default level
+        CameraHandler*        cameraHandler_;
+        LevelManager*         levelManager_;
 
         // config values
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSRoot.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSRoot.cc	(revision 2023)
@@ -41,5 +41,4 @@
 #include "core/TclThreadManager.h"
 #include "tools/Timer.h"
-#include "GraphicsEngine.h"
 #include "Settings.h"
 
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.cc	(revision 2023)
@@ -30,6 +30,4 @@
 #include "GSServer.h"
 
-#include "core/ConsoleCommand.h"
-#include "core/input/InputManager.h"
 #include "core/CommandLine.h"
 #include "core/Core.h"
@@ -41,5 +39,5 @@
 
     GSServer::GSServer()
-        : GSLevel("server")
+        : GameState<GSGraphics>("server")
         , server_(0)
     {
@@ -54,34 +52,18 @@
         Core::setHasServer(true);
 
-        GSLevel::enter();
-
         this->server_ = new network::Server(CommandLine::getValue("port"));
         COUT(0) << "Loading scene in server mode" << std::endl;
 
-        this->loadLevel();
+        GSLevel::enter(this->getParent()->getViewport());
 
         server_->open();
-
-        // add console commands
-        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
     }
 
     void GSServer::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: Remove and destroy console command
-
-        this->unloadLevel();
+        GSLevel::leave();
 
         this->server_->close();
         delete this->server_;
-
-        GSLevel::leave();
 
         Core::setHasServer(false);
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSServer.h	(revision 2023)
@@ -33,13 +33,13 @@
 #include "network/NetworkPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSServer : public GSLevel
+    class _OrxonoxExport GSServer : public GameState<GSGraphics>, public GSLevel
     {
     public:
         GSServer();
         ~GSServer();
-
 
     private:
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.cc	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.cc	(revision 2023)
@@ -30,6 +30,4 @@
 #include "GSStandalone.h"
 
-#include "core/input/InputManager.h"
-#include "core/ConsoleCommand.h"
 #include "core/Core.h"
 
@@ -37,5 +35,5 @@
 {
     GSStandalone::GSStandalone()
-        : GSLevel("standalone")
+        : GameState<GSGraphics>("standalone")
     {
     }
@@ -47,26 +45,11 @@
     void GSStandalone::enter()
     {
-        GSLevel::enter();
+        Core::setIsStandalone(true);
 
-        Core::setIsStandalone(true);
-        this->loadLevel();
-
-        // add console commands
-        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
+        GSLevel::enter(this->getParent()->getViewport());
     }
 
     void GSStandalone::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: Remove and destroy console command
-
-        this->unloadLevel();
-
         GSLevel::leave();
 
Index: code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.h	(revision 2013)
+++ code/branches/objecthierarchy/src/orxonox/gamestates/GSStandalone.h	(revision 2023)
@@ -32,8 +32,9 @@
 #include "OrxonoxPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSStandalone : public GSLevel
+    class _OrxonoxExport GSStandalone : public GameState<GSGraphics>, public GSLevel
     {
     public:
