Index: /code/branches/presentation/src/core/RootGameState.cc
===================================================================
--- /code/branches/presentation/src/core/RootGameState.cc	(revision 2548)
+++ /code/branches/presentation/src/core/RootGameState.cc	(revision 2549)
@@ -122,8 +122,13 @@
     /**
     @brief
+        Main loop of the orxonox game.
         Starts the game. The little 'while' denotes the main loop.
         Whenever the root state is selected, the game ends.
     @param name
         State to start with (usually main menu or specified by command line)
+    @note
+        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!).
     */
     void RootGameState::start()
Index: /code/branches/presentation/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSDedicated.cc	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSDedicated.cc	(revision 2549)
@@ -74,11 +74,12 @@
     void GSDedicated::ticked(const Clock& 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;
+//        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());
@@ -87,6 +88,6 @@
         else
         {
-            usleep( (int)( (NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ) );
-//             COUT(0) << "sleeping for " << (int)( (NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ) << " usec" << endl;
+            usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
+//            COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
         }
     }
Index: /code/branches/presentation/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSGraphics.cc	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSGraphics.cc	(revision 2549)
@@ -76,9 +76,4 @@
         , graphicsEngine_(0)
         , masterKeyBinder_(0)
-        , frameCount_(0)
-        , statisticsRefreshCycle_(0)
-        , statisticsStartTime_(0)
-        , statisticsStartCount_(0)
-        , tickTime_(0)
         , debugOverlay_(0)
     {
@@ -107,8 +102,4 @@
         SetConfigValue(ogreLogLevelCritical_, 2)
             .description("Corresponding orxonox debug level for ogre Critical");
-        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.");
         SetConfigValue(defaultMasterKeybindings_, "def_masterKeybindings.ini")
             .description("Filename of default master keybindings.");
@@ -158,10 +149,4 @@
         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);
@@ -228,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
@@ -243,4 +223,5 @@
     {
         uint64_t timeBeforeTick = time.getRealMicroseconds();
+
         float dt = time.getDeltaTime();
 
@@ -259,32 +240,10 @@
         uint64_t timeAfterTick = time.getRealMicroseconds();
 
-        statisticsTickInfo tickInfo = {timeAfterTick, timeAfterTick-timeBeforeTick};
-        statisticsTickTimes_.push_front( tickInfo );
-        tickTime_ += (unsigned int)(timeAfterTick - timeBeforeTick);
-        if (timeAfterTick > statisticsStartTime_ + statisticsRefreshCycle_)
-        {
-            while( (statisticsTickTimes_.size()!=0) && (statisticsTickTimes_.back().tickTime < timeAfterTick - statisticsAvgLength_ ) )
-                statisticsTickTimes_.pop_back();
-            std::deque<statisticsTickInfo>::iterator it = statisticsTickTimes_.begin();
-            uint32_t periodTickTime = 0;
-            unsigned int periodNrOfTicks = 0;
-            while ( it!=statisticsTickTimes_.end() )
-            {
-                periodTickTime += it->tickLength;
-                periodNrOfTicks++;
-                ++it;
-            }
-            float avgFPS = (float)periodNrOfTicks/(statisticsTickTimes_.front().tickTime - statisticsTickTimes_.back().tickTime)*1000000.0;
-            float avgTickTime = (float)periodTickTime/periodNrOfTicks/1000.0;
-            //float avgFPS = (float)statisticsTickTimes_.size()/statisticsAvgLength_*1000000.0;
-            GraphicsEngine::getInstance().setAverageFramesPerSecond(avgFPS);
-            //GraphicsEngine::getInstance().setAverageTickTime( 
-              //(float)tickTime_ * 0.001f / (frameCount_ - statisticsStartCount_));
-            GraphicsEngine::getInstance().setAverageTickTime( avgTickTime );
-
-            tickTime_ = 0;
-            statisticsStartCount_ = frameCount_;
-            statisticsStartTime_  = timeAfterTick;
-        }
+        // 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
@@ -307,6 +266,4 @@
         // again, just to be sure ogre works fine
         ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
-
-        ++frameCount_;
     }
 
Index: /code/branches/presentation/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSGraphics.h	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSGraphics.h	(revision 2549)
@@ -37,13 +37,6 @@
 #include "GSRoot.h"
 
-#include <deque>
-
 namespace orxonox
 {
-    struct statisticsTickInfo{
-        uint64_t    tickTime;
-        uint32_t    tickLength;
-    };
-    
     class _OrxonoxExport GSGraphics : public GameState<GSRoot>, public OrxonoxClass,
                                       public Ogre::WindowEventListener, public Ogre::LogListener
@@ -100,14 +93,4 @@
 
         KeyBinder*            masterKeyBinder_;
-
-        // variables for time statistics
-        unsigned long         frameCount_;
-        unsigned int          statisticsRefreshCycle_;
-        unsigned int          statisticsAvgLength_;
-        unsigned long long    statisticsStartTime_;
-        unsigned long         statisticsStartCount_;
-        std::deque<statisticsTickInfo>
-            statisticsTickTimes_;
-        unsigned int          tickTime_;
         XMLFile*              debugOverlay_;
 
@@ -120,5 +103,4 @@
         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.
 
Index: /code/branches/presentation/src/orxonox/gamestates/GSLevel.h
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSLevel.h	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSLevel.h	(revision 2549)
@@ -33,9 +33,8 @@
 #include <OgrePrerequisites.h>
 #include "core/GameState.h"
-#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSLevel : public OrxonoxClass //,public GameState<GSGraphics>
+    class _OrxonoxExport GSLevel : public OrxonoxClass
     {
         friend class ClassIdentifier<GSLevel>;
Index: /code/branches/presentation/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSRoot.cc	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSRoot.cc	(revision 2549)
@@ -89,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.");
     }
 
@@ -98,4 +102,12 @@
         // reset game speed to normal
         timeFactor_ = 1.0f;
+
+        // reset frame counter
+        this->frameCount_ = 0;
+        this->statisticsStartTime_ = 0;
+        this->statisticsTickTimes_.clear();
+        this->periodTickTime_ = 0;
+        this->avgFPS_ = 0.0f;
+        this->avgTickTime_ = 0.0f;
 
         // Create the lua interface
@@ -189,4 +201,6 @@
     void GSRoot::ticked(const Clock& time)
     {
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
         TclThreadManager::getInstance().tick(time.getDeltaTime());
 
@@ -206,5 +220,31 @@
         /*** HACK *** HACK ***/
 
+        uint64_t timeAfterTick = time.getRealMicroseconds();
+
+        // STATISTICS
+        statisticsTickInfo tickInfo = {timeAfterTick, timeAfterTick - timeBeforeTick};
+        statisticsTickTimes_.push_back(tickInfo);
+
+        // Ticks GSGraphics or GSDedicated
         this->tickChild(time);
+
+        // Note: tickInfo.tickLength is modified by GSGraphics or GSDedicated!
+        this->periodTickTime_ += tickInfo.tickLength;
+        if (timeAfterTick > statisticsStartTime_ + statisticsRefreshCycle_)
+        {
+            while (statisticsTickTimes_.front().tickTime < timeAfterTick - statisticsAvgLength_)
+            {
+                this->periodTickTime_ -= this->statisticsTickTimes_.front().tickLength;
+                this->statisticsTickTimes_.pop_front();
+            }
+
+            uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
+            this->avgFPS_ = (float)framesPerPeriod / (tickInfo.tickTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0;
+            this->avgTickTime_ = (float)this->periodTickTime_ / framesPerPeriod / 1000.0;
+
+            statisticsStartTime_ = timeAfterTick;
+        }
+
+        ++this->frameCount_;
     }
 
Index: /code/branches/presentation/src/orxonox/gamestates/GSRoot.h
===================================================================
--- /code/branches/presentation/src/orxonox/gamestates/GSRoot.h	(revision 2548)
+++ /code/branches/presentation/src/orxonox/gamestates/GSRoot.h	(revision 2549)
@@ -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();
@@ -52,4 +62,10 @@
         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; }
 
     private:
@@ -69,4 +85,17 @@
         Shell*                shell_;
         LuaBind*              luaBind_;
+
+        // variables for time statistics
+        uint32_t              frameCount_;
+        uint64_t              statisticsStartTime_;
+        std::list<statisticsTickInfo>
+                              statisticsTickTimes_;
+        uint32_t              periodTickTime_;
+        float                 avgFPS_;
+        float                 avgTickTime_;
+
+        // config values
+        unsigned int          statisticsRefreshCycle_;
+        unsigned int          statisticsAvgLength_;
 
         // console commands
