Index: code/trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 2662)
@@ -35,4 +35,5 @@
 #include "network/Server.h"
 #include "objects/Tickable.h"
+#include "util/Sleep.h"
 
 namespace orxonox
@@ -41,4 +42,5 @@
         : GameState<GSRoot>("dedicated")
         , server_(0)
+        , timeSinceLastUpdate_(0)
     {
     }
@@ -72,7 +74,21 @@
     void GSDedicated::ticked(const Clock& time)
     {
-        GSLevel::ticked(time);
-        server_->tick(time.getDeltaTime());
-        this->tickChild(time);
+//        static float startTime = time.getSecondsPrecise();
+//        static int nrOfTicks = 0;
+        timeSinceLastUpdate_ += time.getDeltaTime();
+        if (timeSinceLastUpdate_ >= NETWORK_PERIOD)
+        {
+//            ++nrOfTicks;
+//            COUT(0) << "estimated ticks/sec: " << nrOfTicks/(time.getSecondsPrecise()-startTime) << endl;
+            timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
+            GSLevel::ticked(time);
+            server_->tick(time.getDeltaTime());
+            this->tickChild(time);
+        }
+        else
+        {
+            usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
+//            COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
+        }
     }
 }
Index: code/trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 2662)
@@ -49,4 +49,5 @@
 
         Server*      server_;
+        float        timeSinceLastUpdate_;
     };
 }
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 2662)
@@ -31,4 +31,5 @@
 
 #include <fstream>
+#include <OgreCompositorManager.h>
 #include <OgreConfigFile.h>
 #include <OgreFrameListener.h>
@@ -75,9 +76,4 @@
         , graphicsEngine_(0)
         , masterKeyBinder_(0)
-        , frameCount_(0)
-        , statisticsRefreshCycle_(0)
-        , statisticsStartTime_(0)
-        , statisticsStartCount_(0)
-        , tickTime_(0)
         , debugOverlay_(0)
     {
@@ -106,6 +102,4 @@
         SetConfigValue(ogreLogLevelCritical_, 2)
             .description("Corresponding orxonox debug level for ogre Critical");
-        SetConfigValue(statisticsRefreshCycle_, 200000)
-            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
         SetConfigValue(defaultMasterKeybindings_, "def_masterKeybindings.ini")
             .description("Filename of default master keybindings.");
@@ -155,14 +149,9 @@
         guiManager_->initialise(this->renderWindow_);
 
-        // reset frame counter
-        this->frameCount_ = 0;
-        this->tickTime_ = 0;
-        statisticsStartTime_ = 0;
-        statisticsStartCount_ = 0;
-
         // add console commands
         FunctorMember<GSGraphics>* functor1 = createFunctor(&GSGraphics::printScreen);
         functor1->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "printScreen"));
+        ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
+        CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
     }
 
@@ -170,4 +159,6 @@
     {
         using namespace Ogre;
+
+        delete this->ccPrintScreen_;
 
         // remove our WindowEventListener first to avoid bad calls after the window has been destroyed
@@ -184,4 +175,7 @@
         Loader::unload(this->debugOverlay_);
         delete this->debugOverlay_;
+
+        // unload all compositors
+        Ogre::CompositorManager::getSingleton().removeAll();
 
         // destroy render window
@@ -206,10 +200,10 @@
         delete this->ogreRoot_;
 
-#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
+//#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
         // delete the ogre log and the logManager (since we have created it).
         this->ogreLogger_->getDefaultLog()->removeListener(this);
         this->ogreLogger_->destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
         delete this->ogreLogger_;
-#endif
+//#endif
 
         delete graphicsEngine_;
@@ -219,10 +213,5 @@
 
     /**
-        Main loop of the orxonox game.
-        We use the Ogre::Timer to measure time since it uses the most precise
-        method an a platform (however the windows timer lacks time when under
-        heavy kernel load!).
-        There is a simple mechanism to measure the average time spent in our
-        ticks as it may indicate performance issues.
+    @note
         A note about the Ogre::FrameListener: Even though we don't use them,
         they still get called. However, the delta times are not correct (except
@@ -233,5 +222,6 @@
     void GSGraphics::ticked(const Clock& time)
     {
-        unsigned long long timeBeforeTick = time.getRealMicroseconds();
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
         float dt = time.getDeltaTime();
 
@@ -248,19 +238,12 @@
         }
 
-        unsigned long long timeAfterTick = time.getRealMicroseconds();
-
-        tickTime_ += (unsigned int)(timeAfterTick - timeBeforeTick);
-        if (timeAfterTick > statisticsStartTime_ + statisticsRefreshCycle_)
-        {
-            GraphicsEngine::getInstance().setAverageTickTime(
-                (float)tickTime_ * 0.001f / (frameCount_ - statisticsStartCount_));
-            float avgFPS = (float)(frameCount_ - statisticsStartCount_)
-                / (timeAfterTick - statisticsStartTime_) * 1000000.0;
-            GraphicsEngine::getInstance().setAverageFramesPerSecond(avgFPS);
-
-            tickTime_ = 0;
-            statisticsStartCount_ = frameCount_;
-            statisticsStartTime_  = timeAfterTick;
-        }
+        uint64_t timeAfterTick = time.getRealMicroseconds();
+
+        // Also add our tick time to the list in GSRoot
+        this->getParent()->addTickTime(timeAfterTick - timeBeforeTick);
+
+        // Update statistics overlay. Note that the values only change periodically in GSRoot.
+        GraphicsEngine::getInstance().setAverageFramesPerSecond(this->getParent()->getAvgFPS());
+        GraphicsEngine::getInstance().setAverageTickTime(this->getParent()->getAvgTickTime());
 
         // don't forget to call _fireFrameStarted in ogre to make sure
@@ -283,6 +266,4 @@
         // again, just to be sure ogre works fine
         ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
-
-        ++frameCount_;
     }
 
@@ -296,5 +277,5 @@
 
         // TODO: LogManager doesn't work on oli platform. The why is yet unknown.
-#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
+//#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
         // create a new logManager
         ogreLogger_ = new Ogre::LogManager();
@@ -311,5 +292,5 @@
         myLog->setLogDetail(Ogre::LL_BOREME);
         myLog->addListener(this);
-#endif
+//#endif
 
         // Root will detect that we've already created a Log
@@ -430,4 +411,7 @@
         // create a full screen default viewport
         this->viewport_ = this->renderWindow_->addViewport(0, 0);
+
+        if (this->graphicsEngine_)
+            this->graphicsEngine_->setViewport(this->viewport_);
     }
 
Index: code/trunk/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 2662)
@@ -93,11 +93,4 @@
 
         KeyBinder*            masterKeyBinder_;
-
-        // variables for time statistics
-        unsigned long         frameCount_;
-        unsigned int          statisticsRefreshCycle_;
-        unsigned long long    statisticsStartTime_;
-        unsigned long         statisticsStartCount_;
-        unsigned int          tickTime_;
         XMLFile*              debugOverlay_;
 
@@ -110,6 +103,8 @@
         int                   ogreLogLevelNormal_;       //!< Corresponding Orxonx debug level for LL_NORMAL
         int                   ogreLogLevelCritical_;     //!< Corresponding Orxonx debug level for LL_CRITICAL
-        unsigned int          detailLevelParticle_;      //!< Detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
         std::string           defaultMasterKeybindings_; //!< Filename of default master keybindings.
+
+        // console commands
+        ConsoleCommand*       ccPrintScreen_;
     };
 }
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 2662)
@@ -41,20 +41,18 @@
 #include "core/CoreIncludes.h"
 #include "core/Core.h"
-//#include "objects/Backlight.h"
 #include "objects/Tickable.h"
 #include "objects/Radar.h"
-//#include "tools/ParticleInterface.h"
 #include "CameraManager.h"
 #include "LevelManager.h"
+#include "PlayerManager.h"
 #include "Settings.h"
 
 namespace orxonox
 {
-    SetCommandLineArgument(level, "sample2.oxw").shortcut("l");
+    SetCommandLineArgument(level, "presentation.oxw").shortcut("l");
 
     GSLevel::GSLevel()
 //        : GameState<GSGraphics>(name)
-        : timeFactor_(1.0f)
-        , keyBinder_(0)
+        : keyBinder_(0)
         , inputState_(0)
         , radar_(0)
@@ -64,4 +62,8 @@
     {
         RegisterObject(GSLevel);
+
+        this->ccKeybind_ = 0;
+        this->ccTkeybind_ = 0;
+
         setConfigValues();
     }
@@ -95,11 +97,10 @@
         }
 
+        this->playerManager_ = new PlayerManager();
+
         if (Core::isMaster())
         {
             // create the global LevelManager
             this->levelManager_ = new LevelManager();
-
-            // reset game speed to normal
-            timeFactor_ = 1.0f;
 
             this->loadLevel();
@@ -114,8 +115,10 @@
             FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
             functor1->setObject(this);
-            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
+            ccKeybind_ = createConsoleCommand(functor1, "keybind");
+            CommandExecutor::addConsoleCommandShortcut(ccKeybind_);
             FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
             functor2->setObject(this);
-            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
+            ccTkeybind_ = createConsoleCommand(functor2, "tkeybind");
+            CommandExecutor::addConsoleCommandShortcut(ccTkeybind_);
             // set our console command as callback for the key detector
             InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
@@ -124,16 +127,20 @@
             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);;
-        }
     }
 
     void GSLevel::leave()
     {
+        // destroy console commands
+        if (this->ccKeybind_)
+        {
+            delete this->ccKeybind_;
+            this->ccKeybind_ = 0;
+        }
+        if (this->ccTkeybind_)
+        {
+            delete this->ccTkeybind_;
+            this->ccTkeybind_ = 0;
+        }
+
         // this call will delete every BaseObject!
         // But currently this will call methods of objects that exist no more
@@ -149,11 +156,26 @@
 
         if (this->radar_)
+        {
             delete this->radar_;
+            this->radar_ = 0;
+        }
 
         if (this->cameraManager_)
+        {
             delete this->cameraManager_;
+            this->cameraManager_ = 0;
+        }
 
         if (this->levelManager_)
+        {
             delete this->levelManager_;
+            this->levelManager_ = 0;
+        }
+
+        if (this->playerManager_)
+        {
+            delete this->playerManager_;
+            this->playerManager_ = 0;
+        }
 
         if (Core::showsGraphics())
@@ -162,5 +184,8 @@
             InputManager::getInstance().requestDestroyState("game");
             if (this->keyBinder_)
+            {
                 delete this->keyBinder_;
+                this->keyBinder_ = 0;
+            }
         }
     }
@@ -172,23 +197,4 @@
         //for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
         //    it->tick(time.getDeltaTime() * this->timeFactor_);
-    }
-
-    /**
-    @brief
-        Changes the speed of Orxonox
-    */
-    void GSLevel::setTimeFactor(float factor)
-    {
-/*
-        float change = factor / this->timeFactor_;
-*/
-        this->timeFactor_ = factor;
-/*
-        for (ObjectList<ParticleInterface>::iterator it = ObjectList<ParticleInterface>::begin(); it; ++it)
-            it->setSpeedFactor(it->getSpeedFactor() * change);
-
-        for (ObjectList<Backlight>::iterator it = ObjectList<Backlight>::begin(); it; ++it)
-            it->setTimeFactor(timeFactor_);
-*/
     }
 
Index: code/trunk/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 2662)
@@ -32,10 +32,9 @@
 #include "OrxonoxPrereqs.h"
 #include <OgrePrerequisites.h>
-#include "core/GameState.h"
-#include "GSGraphics.h"
+#include "core/OrxonoxClass.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSLevel : public OrxonoxClass //,public GameState<GSGraphics>
+    class _OrxonoxExport GSLevel : public OrxonoxClass
     {
         friend class ClassIdentifier<GSLevel>;
@@ -43,9 +42,4 @@
         GSLevel();
         ~GSLevel();
-
-        // this has to be public because proteced triggers a bug in msvc
-        // when taking the function address.
-        void setTimeFactor(float factor);
-        float getTimeFactor() { return this->timeFactor_; }
 
     protected:
@@ -56,6 +50,4 @@
         void loadLevel();
         void unloadLevel();
-
-        float timeFactor_;       //!< A factor that sets the gamespeed. 1 is normal.
 
         // console commands
@@ -70,4 +62,5 @@
         CameraManager*        cameraManager_;
         LevelManager*         levelManager_;
+        PlayerManager*        playerManager_;
 
         //##### ConfigValues #####
@@ -75,4 +68,8 @@
         //! Filename of default keybindings.
         std::string           defaultKeybindings_;
+
+        // console commands
+        ConsoleCommand*       ccKeybind_;
+        ConsoleCommand*       ccTkeybind_;
 
     private:
Index: code/trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 2662)
@@ -32,4 +32,5 @@
 #include "util/Exception.h"
 #include "util/Debug.h"
+#include "core/Core.h"
 #include "core/Factory.h"
 #include "core/ConfigValueIncludes.h"
@@ -40,9 +41,10 @@
 #include "core/TclBind.h"
 #include "core/TclThreadManager.h"
+#include "core/LuaBind.h"
 #include "tools/Timer.h"
 #include "objects/Tickable.h"
 #include "Settings.h"
 
-#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 
+#if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
 #  ifndef WIN32_LEAN_AND_MEAN
 #    define WIN32_LEAN_AND_MEAN
@@ -66,4 +68,7 @@
     GSRoot::GSRoot()
         : RootGameState("root")
+        , timeFactor_(1.0f)
+        , bPaused_(false)
+        , timeFactorPauseBackup_(1.0f)
         , settings_(0)
         , tclBind_(0)
@@ -73,4 +78,7 @@
         RegisterRootObject(GSRoot);
         setConfigValues();
+
+        this->ccSetTimeFactor_ = 0;
+        this->ccPause_ = 0;
     }
 
@@ -81,4 +89,8 @@
     void GSRoot::setConfigValues()
     {
+        SetConfigValue(statisticsRefreshCycle_, 250000)
+            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
+        SetConfigValue(statisticsAvgLength_, 1000000)
+            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
     }
 
@@ -87,4 +99,17 @@
         // creates the class hierarchy for all classes with factories
         Factory::createClassHierarchy();
+
+        // reset game speed to normal
+        timeFactor_ = 1.0f;
+
+        // reset frame counter
+        this->statisticsStartTime_ = 0;
+        this->statisticsTickTimes_.clear();
+        this->periodTickTime_ = 0;
+        this->avgFPS_ = 0.0f;
+        this->avgTickTime_ = 0.0f;
+
+        // Create the lua interface
+        this->luaBind_ = new LuaBind();
 
         // instantiate Settings class
@@ -114,18 +139,42 @@
             setThreadAffinity((unsigned int)(limitToCPU - 1));
 
-        // add console commands
-        FunctorMember<GSRoot>* functor1 = createFunctor(&GSRoot::exitGame);
-        functor1->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "exit"));
-
-        // add console commands
-        FunctorMember01<GameStateBase, const std::string&>* functor2 = createFunctor(&GameStateBase::requestState);
-        functor2->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "selectGameState"));
+        {
+            // add console commands
+            FunctorMember<GSRoot>* functor = createFunctor(&GSRoot::exitGame);
+            functor->setObject(this);
+            this->ccExit_ = createConsoleCommand(functor, "exit");
+            CommandExecutor::addConsoleCommandShortcut(this->ccExit_);
+        }
+
+        {
+            // add console commands
+            FunctorMember01<GameStateBase, const std::string&>* functor = createFunctor(&GameStateBase::requestState);
+            functor->setObject(this);
+            this->ccSelectGameState_ = createConsoleCommand(functor, "selectGameState");
+            CommandExecutor::addConsoleCommandShortcut(this->ccSelectGameState_);
+        }
+
+        {
+            // time factor console command
+            FunctorMember<GSRoot>* functor = createFunctor(&GSRoot::setTimeFactor);
+            functor->setObject(this);
+            this->ccSetTimeFactor_ = createConsoleCommand(functor, "setTimeFactor");
+            CommandExecutor::addConsoleCommandShortcut(this->ccSetTimeFactor_).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);
+        }
+
+        {
+            // time factor console command
+            FunctorMember<GSRoot>* functor = createFunctor(&GSRoot::pause);
+            functor->setObject(this);
+            this->ccPause_ = createConsoleCommand(functor, "pause");
+            CommandExecutor::addConsoleCommandShortcut(this->ccPause_).accessLevel(AccessLevel::Offline);
+        }
     }
 
     void GSRoot::leave()
     {
-        // TODO: remove and destroy console commands
+        // destroy console commands
+        delete this->ccExit_;
+        delete this->ccSelectGameState_;
 
         delete this->shell_;
@@ -133,10 +182,24 @@
         delete this->tclBind_;
 
-        delete settings_;
-
+        delete this->settings_;
+        delete this->luaBind_;
+
+        if (this->ccSetTimeFactor_)
+        {
+            delete this->ccSetTimeFactor_;
+            this->ccSetTimeFactor_ = 0;
+        }
+
+        if (this->ccPause_)
+        {
+            delete this->ccPause_;
+            this->ccPause_ = 0;
+        }
     }
 
     void GSRoot::ticked(const Clock& time)
     {
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
         TclThreadManager::getInstance().tick(time.getDeltaTime());
 
@@ -146,9 +209,50 @@
         /*** HACK *** HACK ***/
         // Call the Tickable objects
+        float leveldt = time.getDeltaTime();
+        if (leveldt > 1.0f)
+        {
+            // just loaded
+            leveldt = 0.0f;
+        }
         for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
-            it->tick(time.getDeltaTime());
+            it->tick(leveldt * this->timeFactor_);
         /*** HACK *** HACK ***/
 
+        uint64_t timeAfterTick = time.getRealMicroseconds();
+
+        // STATISTICS
+        assert(timeAfterTick - timeBeforeTick >= 0 );
+        statisticsTickInfo tickInfo = {timeAfterTick, timeAfterTick - timeBeforeTick};
+        statisticsTickTimes_.push_back(tickInfo);
+        assert(statisticsTickTimes_.back().tickLength==tickInfo.tickLength);
+        this->periodTickTime_ += tickInfo.tickLength;
+
+        // Ticks GSGraphics or GSDedicated
         this->tickChild(time);
+
+        if (timeAfterTick > statisticsStartTime_ + statisticsRefreshCycle_)
+        {
+            std::list<statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
+            assert(it != this->statisticsTickTimes_.end());
+            int64_t lastTime = timeAfterTick - statisticsAvgLength_;
+            if ((int64_t)it->tickTime < lastTime)
+            {
+                do
+                {
+                    assert(this->periodTickTime_ > it->tickLength);
+                    this->periodTickTime_ -= it->tickLength;
+                    ++it;
+                    assert(it != this->statisticsTickTimes_.end());
+                } while ((int64_t)it->tickTime < lastTime);
+                this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
+            }
+
+            uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
+            this->avgFPS_ = (float)framesPerPeriod / (timeAfterTick - this->statisticsTickTimes_.front().tickTime) * 1000000.0;
+            this->avgTickTime_ = (float)this->periodTickTime_ / framesPerPeriod / 1000.0;
+
+            statisticsStartTime_ = timeAfterTick;
+        }
+
     }
 
@@ -160,5 +264,5 @@
 
         Copyright (c) 2000-2008 Torus Knot Software Ltd
-        
+
         OGRE is licensed under the LGPL. For more info, see OGRE license.
     */
@@ -167,16 +271,16 @@
 #if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32
         // Get the current process core mask
-	    DWORD procMask;
-	    DWORD sysMask;
+        DWORD procMask;
+        DWORD sysMask;
 #  if _MSC_VER >= 1400 && defined (_M_X64)
-	    GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
+        GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
 #  else
-	    GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask);
+        GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask);
 #  endif
 
-	    // If procMask is 0, consider there is only one core available
-	    // (using 0 as procMask will cause an infinite loop below)
-	    if (procMask == 0)
-		    procMask = 1;
+        // If procMask is 0, consider there is only one core available
+        // (using 0 as procMask will cause an infinite loop below)
+        if (procMask == 0)
+            procMask = 1;
 
         // if the core specified with limitToCPU is not available, take the lowest one
@@ -184,12 +288,62 @@
             limitToCPU = 0;
 
-	    // Find the lowest core that this process uses and limitToCPU suggests
+        // Find the lowest core that this process uses and limitToCPU suggests
         DWORD threadMask = 1;
-	    while ((threadMask & procMask) == 0 || (threadMask < (1u << limitToCPU)))
-		    threadMask <<= 1;
-
-	    // Set affinity to the first core
-	    SetThreadAffinityMask(GetCurrentThread(), threadMask);
+        while ((threadMask & procMask) == 0 || (threadMask < (1u << limitToCPU)))
+            threadMask <<= 1;
+
+        // Set affinity to the first core
+        SetThreadAffinityMask(GetCurrentThread(), threadMask);
 #endif
     }
+
+    /**
+    @brief
+        Changes the speed of Orxonox
+    */
+    void GSRoot::setTimeFactor(float factor)
+    {
+        if (Core::isMaster())
+        {
+            if (!this->bPaused_)
+            {
+                TimeFactorListener::timefactor_s = factor;
+
+                for (ObjectList<TimeFactorListener>::iterator it = ObjectList<TimeFactorListener>::begin(); it != ObjectList<TimeFactorListener>::end(); ++it)
+                    it->changedTimeFactor(factor, this->timeFactor_);
+
+                this->timeFactor_ = factor;
+            }
+            else
+                this->timeFactorPauseBackup_ = factor;
+        }
+    }
+
+    void GSRoot::pause()
+    {
+        if (Core::isMaster())
+        {
+            if (!this->bPaused_)
+            {
+                this->timeFactorPauseBackup_ = this->timeFactor_;
+                this->setTimeFactor(0.0f);
+                this->bPaused_ = true;
+            }
+            else
+            {
+                this->bPaused_ = false;
+                this->setTimeFactor(this->timeFactorPauseBackup_);
+            }
+        }
+    }
+
+    ////////////////////////
+    // TimeFactorListener //
+    ////////////////////////
+    float TimeFactorListener::timefactor_s = 1.0f;
+
+    TimeFactorListener::TimeFactorListener()
+    {
+        RegisterRootObject(TimeFactorListener);
+    }
 }
Index: code/trunk/src/orxonox/gamestates/GSRoot.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.h	(revision 2171)
+++ code/trunk/src/orxonox/gamestates/GSRoot.h	(revision 2662)
@@ -31,4 +31,6 @@
 
 #include "OrxonoxPrereqs.h"
+
+#include <list>
 #include <OgreLog.h>
 #include "core/RootGameState.h"
@@ -40,4 +42,12 @@
     {
         friend class ClassIdentifier<GSRoot>;
+
+    public:
+        struct statisticsTickInfo
+        {
+            uint64_t    tickTime;
+            uint32_t    tickLength;
+        };
+    
     public:
         GSRoot();
@@ -46,4 +56,17 @@
         void exitGame()
         { requestState("root"); }
+
+        // this has to be public because proteced triggers a bug in msvc
+        // when taking the function address.
+        void setTimeFactor(float factor);
+        void pause();
+        float getTimeFactor() { return this->timeFactor_; }
+
+        float getAvgTickTime() { return this->avgTickTime_; }
+        float getAvgFPS()      { return this->avgFPS_; }
+
+        inline void addTickTime(uint32_t length)
+            { assert(!this->statisticsTickTimes_.empty()); this->statisticsTickTimes_.back().tickLength += length;
+              this->periodTickTime_+=length; }
 
     private:
@@ -55,8 +78,47 @@
         void setThreadAffinity(unsigned int limitToCPU);
 
+        float                 timeFactor_;       //!< A factor that sets the gamespeed. 1 is normal.
+        bool                  bPaused_;
+        float                 timeFactorPauseBackup_;
         Settings*             settings_;
         TclBind*              tclBind_;
         TclThreadManager*     tclThreadManager_;
         Shell*                shell_;
+        LuaBind*              luaBind_;
+
+        // variables for time statistics
+        uint64_t              statisticsStartTime_;
+        std::list<statisticsTickInfo>
+                              statisticsTickTimes_;
+        uint32_t              periodTickTime_;
+        float                 avgFPS_;
+        float                 avgTickTime_;
+
+        // config values
+        unsigned int          statisticsRefreshCycle_;
+        unsigned int          statisticsAvgLength_;
+
+        // console commands
+        ConsoleCommand*       ccExit_;
+        ConsoleCommand*       ccSelectGameState_;
+        ConsoleCommand*       ccSetTimeFactor_;
+        ConsoleCommand*       ccPause_;
+    };
+
+    class _OrxonoxExport TimeFactorListener : virtual public OrxonoxClass
+    {
+        friend class GSRoot;
+
+        public:
+            TimeFactorListener();
+            virtual ~TimeFactorListener() {}
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old) {}
+            inline float getTimeFactor() const
+                { return TimeFactorListener::timefactor_s; }
+
+        private:
+            static float timefactor_s;
     };
 }
