Index: code/branches/objecthierarchy/src/orxonox/CMakeLists.txt
===================================================================
--- code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/CMakeLists.txt	(revision 2024)
@@ -69,4 +69,6 @@
 
   objects/worldentities/pawns/Spectator.cc
+  objects/worldentities/pawns/Pawn.cc
+  objects/worldentities/pawns/SpaceShip.cc
 
   objects/controllers/Controller.cc
Index: code/branches/objecthierarchy/src/orxonox/objects/Scene.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/Scene.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/Scene.cc	(revision 2024)
@@ -85,12 +85,15 @@
     Scene::~Scene()
     {
-        if (Ogre::Root::getSingletonPtr())
+        if (this->isInitialized())
         {
-//            this->sceneManager_->destroySceneNode(this->rootSceneNode_->getName()); // TODO: remove getName() for newer versions of Ogre
-            Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
-        }
-        else if (!Core::showsGraphics())
-        {
-            delete this->sceneManager_;
+            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 if (!Core::showsGraphics())
+            {
+                delete this->sceneManager_;
+            }
         }
     }
Index: code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/controllers/HumanController.cc	(revision 2024)
@@ -67,5 +67,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->moveFrontBack(value.y);
+            HumanController::localController_s->controllableEntity_->moveFrontBack(value);
     }
 
@@ -73,5 +73,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->moveRightLeft(value.y);
+            HumanController::localController_s->controllableEntity_->moveRightLeft(value);
     }
 
@@ -79,5 +79,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->moveUpDown(value.y);
+            HumanController::localController_s->controllableEntity_->moveUpDown(value);
     }
 
@@ -85,5 +85,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->rotateYaw(value.y);
+            HumanController::localController_s->controllableEntity_->rotateYaw(value);
     }
 
@@ -91,5 +91,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->rotatePitch(value.y);
+            HumanController::localController_s->controllableEntity_->rotatePitch(value);
     }
 
@@ -97,5 +97,5 @@
     {
         if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
-            HumanController::localController_s->controllableEntity_->rotateRoll(value.y);
+            HumanController::localController_s->controllableEntity_->rotateRoll(value);
     }
 
Index: code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.cc	(revision 2024)
@@ -48,8 +48,14 @@
         RegisterObject(Gametype);
 
-        this->defaultPawn_ = Class(Spectator);
+        this->defaultControllableEntity_ = Class(Spectator);
+
         this->bStarted_ = false;
         this->bEnded_ = false;
         this->bAutoStart_ = false;
+        this->bForceSpawn_ = false;
+
+        this->initialStartCountdown_ = 3;
+        this->startCountdown_ = 0;
+        this->bStartCountdownRunning_ = false;
 
         COUT(0) << "created Gametype" << std::endl;
@@ -58,8 +64,12 @@
     void Gametype::tick(float dt)
     {
+        if (this->bStartCountdownRunning_ && !this->bStarted_)
+            this->startCountdown_ -= dt;
+
         if (!this->bStarted_)
             this->checkStart();
 
         this->assignDefaultPawnsIfNeeded();
+        this->spawnDeadPlayersIfRequested();
     }
 
@@ -69,6 +79,5 @@
         this->bStarted_ = true;
 
-        for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
-            this->spawnPlayer(*it);
+        this->spawnPlayersIfRequested();
     }
 
@@ -122,9 +131,13 @@
     }
 
-    void Gametype::playerSpawned(PlayerInfo* player)
-    {
-    }
-
-    void Gametype::playerDied(PlayerInfo* player)
+    void Gametype::pawnPreSpawn(Pawn* pawn)
+    {
+    }
+
+    void Gametype::pawnPostSpawn(Pawn* pawn)
+    {
+    }
+
+    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
     {
     }
@@ -164,7 +177,7 @@
                 {
                     // force spawn at spawnpoint with default pawn
-                    ControllableEntity* newpawn = this->defaultPawn_.fabricate(spawn);
-                    spawn->spawn(newpawn);
-                    (*it)->startControl(newpawn);
+                    ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
+                    spawn->spawn(entity);
+                    (*it)->startControl(entity);
                 }
                 else
@@ -181,5 +194,14 @@
         if (!this->bStarted_)
         {
-            if (this->players_.size() > 0)
+            if (this->bStartCountdownRunning_)
+            {
+                if (this->startCountdown_ <= 0)
+                {
+                    this->bStartCountdownRunning_ = false;
+                    this->startCountdown_ = 0;
+                    this->start();
+                }
+            }
+            else if (this->players_.size() > 0)
             {
                 if (this->bAutoStart_)
@@ -196,24 +218,39 @@
                     }
                     if (allplayersready)
-                        this->start();
-                }
-            }
-        }
+                    {
+                        this->startCountdown_ = this->initialStartCountdown_;
+                        this->bStartCountdownRunning_ = true;
+                    }
+                }
+            }
+        }
+    }
+
+    void Gametype::spawnPlayersIfRequested()
+    {
+        for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+            if ((*it)->isReadyToSpawn() || this->bForceSpawn_)
+                this->spawnPlayer(*it);
+    }
+
+    void Gametype::spawnDeadPlayersIfRequested()
+    {
+        for (std::set<PlayerInfo*>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+            if (!(*it)->getControllableEntity())
+                if ((*it)->isReadyToSpawn() || this->bForceSpawn_)
+                    this->spawnPlayer(*it);
     }
 
     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();
-            }
+        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 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/gametypes/Gametype.h	(revision 2024)
@@ -51,4 +51,9 @@
             virtual void tick(float dt);
 
+            inline bool hasStarted() const
+                { return this->bStarted_; }
+            inline bool hasEnded() const
+                { return this->bEnded_; }
+
             virtual void start();
             virtual void end();
@@ -58,7 +63,10 @@
             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);
+
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+            virtual void pawnPreSpawn(Pawn* pawn);
+            virtual void pawnPostSpawn(Pawn* pawn);
 
             inline const std::set<PlayerInfo*>& getPlayers() const
@@ -67,4 +75,9 @@
             inline void registerSpawnPoint(SpawnPoint* spawnpoint)
                 { this->spawnpoints_.insert(spawnpoint); }
+
+            inline bool isStartCountdownRunning() const
+                { return this->bStartCountdownRunning_; }
+            inline float getStartCountdown() const
+                { return this->startCountdown_; }
 
         private:
@@ -77,11 +90,19 @@
             void checkStart();
             void spawnPlayer(PlayerInfo* player);
+            void spawnPlayersIfRequested();
+            void spawnDeadPlayersIfRequested();
 
             bool bStarted_;
             bool bEnded_;
             bool bAutoStart_;
+            bool bForceSpawn_;
+
+            float initialStartCountdown_;
+            float startCountdown_;
+            bool bStartCountdownRunning_;
+
             std::set<PlayerInfo*> players_;
             std::set<SpawnPoint*> spawnpoints_;
-            SubclassIdentifier<ControllableEntity> defaultPawn_;
+            SubclassIdentifier<ControllableEntity> defaultControllableEntity_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2024)
@@ -121,4 +121,5 @@
             this->controllableEntityID_ = entity->getObjectID();
             entity->setPlayer(this);
+            this->bReadyToSpawn_ = false;
         }
         else
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.h	(revision 2024)
@@ -57,11 +57,11 @@
                 { return this->bDestroyWhenPlayerLeft_; }
 
-            virtual void moveFrontBack(float value) {}
-            virtual void moveRightLeft(float value) {}
-            virtual void moveUpDown(float value) {}
+            virtual void moveFrontBack(const Vector2& value) {}
+            virtual void moveRightLeft(const Vector2& value) {}
+            virtual void moveUpDown(const Vector2& value) {}
 
-            virtual void rotateYaw(float value) {}
-            virtual void rotatePitch(float value) {}
-            virtual void rotateRoll(float value) {}
+            virtual void rotateYaw(const Vector2& value) {}
+            virtual void rotatePitch(const Vector2& value) {}
+            virtual void rotateRoll(const Vector2& value) {}
 
             virtual void fire() {}
@@ -108,4 +108,9 @@
                 { this->acceleration_.x = x; this->acceleration_.y = y; this->acceleration_.z = z; }
 
+            inline Camera* getCamera() const
+                { return this->camera_; }
+            inline OverlayGroup* getHUD() const
+                { return this->hud_; }
+
         protected:
             virtual void startLocalControl();
@@ -117,4 +122,6 @@
             inline bool isLocallyControlled() const
                 { return this->bControlled_; }
+
+            Vector3 acceleration_;
 
         private:
@@ -136,5 +143,4 @@
 
             Vector3 velocity_;
-            Vector3 acceleration_;
 
             bool bControlled_;
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.cc	(revision 2024)
@@ -57,5 +57,5 @@
 
         XMLPortParam(SpawnPoint, "spawnclass", setSpawnClassName, getSpawnClassName, xmlelement, mode);
-        XMLPortParam(SpawnPoint, "design", setTemplateName, getTemplateName, xmlelement, mode);
+        XMLPortParam(SpawnPoint, "pawndesign", setTemplateName, getTemplateName, xmlelement, mode);
     }
 
@@ -72,12 +72,15 @@
     }
 
-    ControllableEntity* SpawnPoint::spawn()
+    Pawn* SpawnPoint::spawn()
     {
-        ControllableEntity* entity = this->spawnclass_.fabricate(this);
+        Pawn* entity = this->spawnclass_.fabricate(this);
         if (entity)
         {
+            this->getGametype()->pawnPreSpawn(entity);
             this->spawn(entity);
             if (this->template_)
                 entity->addTemplate(this->template_);
+            entity->postSpawn();
+            this->getGametype()->pawnPostSpawn(entity);
         }
         return entity;
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/SpawnPoint.h	(revision 2024)
@@ -35,5 +35,5 @@
 #include "core/Template.h"
 #include "PositionableEntity.h"
-#include "ControllableEntity.h"
+#include "objects/worldentities/pawns/Pawn.h"
 
 namespace orxonox
@@ -57,5 +57,5 @@
                 { return this->template_; }
 
-            ControllableEntity* spawn();
+            Pawn* spawn();
             void spawn(ControllableEntity* entity);
 
@@ -69,5 +69,5 @@
                 { return this->templatename_; }
 
-            SubclassIdentifier<ControllableEntity> spawnclass_;
+            SubclassIdentifier<Pawn> spawnclass_;
             std::string spawnclassname_;
             Template* template_;
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2024)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.cc	(revision 2024)
@@ -0,0 +1,134 @@
+/*
+ *   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 "Pawn.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/Math.h"
+#include "objects/infos/PlayerInfo.h"
+#include "objects/gametypes/Gametype.h"
+
+namespace orxonox
+{
+    CreateFactory(Pawn);
+
+    Pawn::Pawn(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(Pawn);
+
+        this->bAlive_ = false;
+
+        this->health_ = 0;
+        this->maxHealth_ = 0;
+        this->initialHealth_ = 0;
+
+        this->lastHitOriginator_ = 0;
+
+        this->registerVariables();
+    }
+
+    Pawn::~Pawn()
+    {
+    }
+
+    void Pawn::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Pawn, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Pawn, "health", setHealth, getHealht, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
+        XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
+    }
+
+    void Pawn::registerVariables()
+    {
+        REGISTERDATA(this->bAlive_, network::direction::toclient);
+        REGISTERDATA(this->health_, network::direction::toclient);
+    }
+
+    void Pawn::tick(float dt)
+    {
+        SUPER(Pawn, tick, dt);
+
+        if (this->health_ <= 0)
+            this->death();
+    }
+
+    void Pawn::setHealth(float health)
+    {
+        this->health_ = min(health, this->maxHealth_);
+    }
+
+    void Pawn::damage(float damage, Pawn* originator)
+    {
+        this->setHealth(this->health_ - damage);
+        this->lastHitOriginator_ = originator;
+
+        // play damage effect
+    }
+
+    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
+    {
+        this->damage(damage, originator);
+        this->setVelocity(this->getVelocity() + force);
+
+        // play hit effect
+    }
+
+    void Pawn::kill()
+    {
+        this->damage(this->health_);
+        this->death();
+    }
+
+    void Pawn::spawn()
+    {
+        // play spawn effect
+    }
+
+    void Pawn::death()
+    {
+        this->bAlive_ = false;
+        if (this->getGametype())
+            this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
+        if (this->getPlayer())
+            this->getPlayer()->stopControl(this);
+
+        delete this;
+
+        // play death effect
+    }
+
+    void Pawn::postSpawn()
+    {
+        this->setHealth(this->initialHealth_);
+        this->spawn();
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2024)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Pawn.h	(revision 2024)
@@ -0,0 +1,92 @@
+/*
+ *   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 _Pawn_H__
+#define _Pawn_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "objects/worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Pawn : public ControllableEntity
+    {
+        public:
+            Pawn(BaseObject* creator);
+            virtual ~Pawn();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+
+            inline bool isAlive() const
+                { return this->bAlive_; }
+
+            virtual void setHealth(float health);
+            inline void addHealth(float health)
+                { this->setHealth(this->health_ + health); }
+            inline void removeHealth(float health)
+                { this->setHealth(this->health_ - health); }
+            inline float getHealht() const
+                { return this->health_; }
+
+            inline void setMaxHealth(float maxhealth)
+                { this->maxHealth_ = maxhealth; this->setHealth(this->health_); }
+            inline float getMaxHealth() const
+                { return this->maxHealth_; }
+
+            inline void setInitialHealth(float initialhealth)
+                { this->initialHealth_ = initialhealth; this->setHealth(initialhealth); }
+            inline float getInitialHealth() const
+                { return this->initialHealth_; }
+
+            inline ControllableEntity* getLastHitOriginator() const
+                { return this->lastHitOriginator_; }
+
+            virtual void damage(float damage, Pawn* originator = 0);
+            virtual void hit(Pawn* originator, const Vector3& force, float damage);
+            virtual void kill();
+
+            virtual void postSpawn();
+
+        protected:
+            virtual void spawn();
+            virtual void death();
+
+            bool bAlive_;
+
+            float health_;
+            float maxHealth_;
+            float initialHealth_;
+
+            Pawn* lastHitOriginator_;
+    };
+}
+
+#endif /* _Pawn_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.cc	(revision 2024)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.cc	(revision 2024)
@@ -0,0 +1,200 @@
+/*
+ *   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 "SpaceShip.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/XMLPort.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    CreateFactory(SpaceShip);
+
+    SpaceShip::SpaceShip(BaseObject* creator) : Pawn(creator)
+    {
+        RegisterObject(SpaceShip);
+
+        this->zeroDegree_ = 0;
+
+        this->maxSpeed_ = 0;
+        this->maxSecondarySpeed_ = 0;
+        this->maxRotation_ = 0;
+        this->translationAcceleration_ = 0;
+        this->rotationAcceleration_ = 0;
+        this->translationDamping_ = 0;
+
+        this->yawRotation_ = 0;
+        this->pitchRotation_ = 0;
+        this->rollRotation_ = 0;
+
+        this->bInvertYAxis_ = false;
+
+        this->setConfigValues();
+        this->registerVariables();
+    }
+
+    SpaceShip::~SpaceShip()
+    {
+    }
+
+    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SpaceShip, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SpaceShip, "maxspeed",          setMaxSpeed,          getMaxSpeed,          xmlelement, mode);
+        XMLPortParam(SpaceShip, "maxsecondaryspeed", setMaxSecondarySpeed, getMaxSecondarySpeed, xmlelement, mode);
+        XMLPortParam(SpaceShip, "maxrotation",       setMaxRotation,       getMaxRotation,       xmlelement, mode);
+        XMLPortParam(SpaceShip, "transacc",          setTransAcc,          getTransAcc,          xmlelement, mode);
+        XMLPortParam(SpaceShip, "rotacc",            setRotAcc,            getRotAcc,            xmlelement, mode);
+        XMLPortParam(SpaceShip, "transdamp",         setTransDamp,         getTransDamp,         xmlelement, mode);
+    }
+
+    void SpaceShip::registerVariables()
+    {
+    }
+
+    void SpaceShip::setConfigValues()
+    {
+        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
+    }
+
+    void SpaceShip::tick(float dt)
+    {
+        // #####################################
+        // ############# STEERING ##############
+        // #####################################
+
+        Vector3 velocity = this->getVelocity();
+        if (velocity.x > this->maxSecondarySpeed_)
+            velocity.x = this->maxSecondarySpeed_;
+        if (velocity.x < -this->maxSecondarySpeed_)
+            velocity.x = -this->maxSecondarySpeed_;
+        if (velocity.y > this->maxSecondarySpeed_)
+            velocity.y = this->maxSecondarySpeed_;
+        if (velocity.y < -this->maxSecondarySpeed_)
+            velocity.y = -this->maxSecondarySpeed_;
+        if (velocity.z > this->maxSecondarySpeed_)
+            velocity.z = this->maxSecondarySpeed_;
+        if (velocity.z < -this->maxSpeed_)
+            velocity.z = -this->maxSpeed_;
+
+#define normalize_acc_and_vel(dimension)                                 \
+        if (this->acceleration_.dimension == 0)                          \
+        {                                                                \
+            if (velocity.dimension > 0)                                  \
+            {                                                            \
+                velocity.dimension -= (this->translationDamping_ * dt);  \
+                if (velocity.dimension < 0)                              \
+                    velocity.dimension = 0;                              \
+            }                                                            \
+            else if (velocity.dimension < 0)                             \
+            {                                                            \
+                velocity.dimension += (this->translationDamping_ * dt);  \
+                if (velocity.dimension > 0)                              \
+                    velocity.dimension = 0;                              \
+            }                                                            \
+        }
+
+        normalize_acc_and_vel(x)
+        normalize_acc_and_vel(y)
+        normalize_acc_and_vel(z)
+
+        this->setVelocity(velocity);
+
+
+        SUPER(SpaceShip, tick, dt);
+
+
+        this->yaw(this->yawRotation_ * dt);
+        if (this->bInvertYAxis_)
+            this->pitch(Degree(-this->pitchRotation_ * dt));
+        else
+            this->pitch(Degree( this->pitchRotation_ * dt));
+        this->roll(this->rollRotation_ * dt);
+
+        this->acceleration_.x = 0;
+        this->acceleration_.y = 0;
+        this->acceleration_.z = 0;
+
+        this->yawRotation_   = this->zeroDegree_;
+        this->pitchRotation_ = this->zeroDegree_;
+        this->rollRotation_  = this->zeroDegree_;
+    }
+
+    void SpaceShip::moveFrontBack(const Vector2& value)
+    {
+        this->acceleration_.z = -this->translationAcceleration_ * value.x;
+    }
+
+    void SpaceShip::moveRightLeft(const Vector2& value)
+    {
+        this->acceleration_.x = this->translationAcceleration_ * value.x;
+    }
+
+    void SpaceShip::moveUpDown(const Vector2& value)
+    {
+        this->acceleration_.y = this->translationAcceleration_ * value.x;
+    }
+
+    void SpaceShip::rotateYaw(const Vector2& value)
+    {
+        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
+        if (temp > this->maxRotation_)
+            temp = this->maxRotation_;
+        if (temp < -this->maxRotation_)
+            temp = -this->maxRotation_;
+        this->yawRotation_ = Degree(temp);
+    }
+
+    void SpaceShip::rotatePitch(const Vector2& value)
+    {
+        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
+        if (temp > this->maxRotation_)
+            temp = this->maxRotation_;
+        if (temp < -this->maxRotation_)
+            temp = -this->maxRotation_;
+        this->pitchRotation_ = Degree(temp);
+    }
+
+    void SpaceShip::rotateRoll(const Vector2& value)
+    {
+        Degree temp = value.x * value.x * sgn(value.x) * this->rotationAcceleration_;
+        if (temp > this->maxRotation_)
+            temp = this->maxRotation_;
+        if (temp < -this->maxRotation_)
+            temp = -this->maxRotation_;
+        this->rollRotation_ = Degree(temp);
+    }
+
+    void SpaceShip::fire()
+    {
+    }
+}
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.h	(revision 2024)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/SpaceShip.h	(revision 2024)
@@ -0,0 +1,103 @@
+/*
+ *   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 _SpaceShip_H__
+#define _SpaceShip_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Pawn.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SpaceShip : public Pawn
+    {
+        public:
+            SpaceShip(BaseObject* creator);
+            virtual ~SpaceShip();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+            void setConfigValues();
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            virtual void fire();
+
+            void setMaxSpeed(float value)
+                { this->maxSpeed_ = value; }
+            void setMaxSecondarySpeed(float value)
+                { this->maxSecondarySpeed_ = value; }
+            void setMaxRotation(const Degree& value)
+                { this->maxRotation_ = value; }
+            void setTransAcc(float value)
+                { this->translationAcceleration_ = value; }
+            void setRotAcc(const Degree& value)
+                { this->rotationAcceleration_ = value; }
+            void setTransDamp(float value)
+                { this->translationDamping_ = value; }
+
+            inline float getMaxSpeed() const
+                { return this->maxSpeed_; }
+            inline float getMaxSecondarySpeed() const
+                { return this->maxSecondarySpeed_; }
+            inline float getMaxRotation() const
+                { return this->maxRotation_.valueDegrees(); }
+            inline float getTransAcc() const
+                { return this->translationAcceleration_; }
+            inline float getRotAcc() const
+                { return this->rotationAcceleration_.valueDegrees(); }
+            inline float getTransDamp() const
+                { return this->translationDamping_; }
+
+        protected:
+            bool bInvertYAxis_;
+
+            float maxSpeed_;
+            float maxSecondarySpeed_;
+            float translationAcceleration_;
+            float translationDamping_;
+
+            Degree maxRotation_;
+            Degree rotationAcceleration_;
+
+            Degree zeroDegree_;
+            Degree pitchRotation_;
+            Degree yawRotation_;
+            Degree rollRotation_;
+    };
+}
+
+#endif /* _SpaceShip_H__ */
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.cc	(revision 2024)
@@ -35,5 +35,9 @@
 #include "objects/Scene.h"
 #include "objects/infos/PlayerInfo.h"
+#include "objects/gametypes/Gametype.h"
 #include "tools/BillboardSet.h"
+#include "overlays/OverlayText.h"
+#include "overlays/OverlayGroup.h"
+#include "util/Convert.h"
 
 namespace orxonox
@@ -54,23 +58,4 @@
 
         this->setDestroyWhenPlayerLeft(true);
-
-        // test test test
-        if (this->getScene()->getSceneManager())
-        {
-            this->testmesh_ = new Mesh();
-            this->testnode_ = this->getNode()->createChildSceneNode();
-            this->testmesh_->setMeshSource(this->getScene()->getSceneManager(), "assff.mesh");
-            if (this->testmesh_->getEntity())
-                this->testnode_->attachObject(this->testmesh_->getEntity());
-            this->testnode_->pitch(Degree(-90));
-            this->testnode_->roll(Degree(+90));
-            this->testnode_->scale(10, 10, 10);
-        }
-        else
-        {
-            this->testmesh_ = 0;
-            this->testnode_ = 0;
-        }
-        // test test test
 
         this->greetingFlare_ = new BillboardSet();
@@ -93,17 +78,4 @@
                 delete this->greetingFlare_;
             }
-
-            // test test test
-            {
-                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
         }
     }
@@ -130,4 +102,6 @@
         if (this->isLocallyControlled())
         {
+            this->updateHUD();
+
             Vector3 velocity = this->getVelocity();
             velocity.normalise();
@@ -159,36 +133,36 @@
     {
         ControllableEntity::startLocalControl();
-        if (this->isLocallyControlled())
-            this->testmesh_->setVisible(false);
-    }
-
-    void Spectator::moveFrontBack(float value)
-    {
-        this->setVelocity(this->getVelocity() + value * this->speed_ * WorldEntity::FRONT);
-    }
-
-    void Spectator::moveRightLeft(float value)
-    {
-        this->setVelocity(this->getVelocity() + value * this->speed_ * WorldEntity::RIGHT);
-    }
-
-    void Spectator::moveUpDown(float value)
-    {
-        this->setVelocity(this->getVelocity() + value * this->speed_ * WorldEntity::UP);
-    }
-
-    void Spectator::rotateYaw(float value)
-    {
-        this->yaw_ = value;
-    }
-
-    void Spectator::rotatePitch(float value)
-    {
-        this->pitch_ = value;
-    }
-
-    void Spectator::rotateRoll(float value)
-    {
-        this->roll_ = value;
+//        if (this->isLocallyControlled())
+//            this->testmesh_->setVisible(false);
+    }
+
+    void Spectator::moveFrontBack(const Vector2& value)
+    {
+        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::FRONT);
+    }
+
+    void Spectator::moveRightLeft(const Vector2& value)
+    {
+        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::RIGHT);
+    }
+
+    void Spectator::moveUpDown(const Vector2& value)
+    {
+        this->setVelocity(this->getVelocity() + value.y * this->speed_ * WorldEntity::UP);
+    }
+
+    void Spectator::rotateYaw(const Vector2& value)
+    {
+        this->yaw_ = value.y;
+    }
+
+    void Spectator::rotatePitch(const Vector2& value)
+    {
+        this->pitch_ = value.y;
+    }
+
+    void Spectator::rotateRoll(const Vector2& value)
+    {
+        this->roll_ = value.y;
     }
 
@@ -209,3 +183,55 @@
         }
     }
+
+    void Spectator::updateHUD()
+    {
+        // <hack>
+        if (this->getHUD())
+        {
+            std::string text;
+
+            if (this->getPlayer() && this->getGametype())
+            {
+                if (!this->getGametype()->hasStarted() && !this->getGametype()->isStartCountdownRunning())
+                {
+                    if (!this->getPlayer()->isReadyToSpawn())
+                        text = "Press [Fire] to start the match";
+                    else
+                        text = "Waiting for other players";
+                }
+                else if (!this->getGametype()->hasEnded())
+                {
+                    if (this->getGametype()->isStartCountdownRunning())
+                    {
+                        text = convertToString(ceil(this->getGametype()->getStartCountdown()));
+                    }
+                    else
+                    {
+                        text = "Press [Fire] to respawn";
+                    }
+                }
+                else
+                {
+                    text = "Game has ended";
+                }
+            }
+            else
+            {
+                return;
+            }
+
+            std::map<std::string, OrxonoxOverlay*>::const_iterator it = this->getHUD()->getOverlays().begin();
+            for (; it != this->getHUD()->getOverlays().end(); ++it)
+            {
+                if (it->second->isA(Class(OverlayText)) && it->second->getName() == "state")
+                {
+                    OverlayText* overlay = dynamic_cast<OverlayText*>(it->second);
+                    if (overlay)
+                        overlay->setCaption(text);
+                    break;
+                }
+            }
+        }
+        // </hack>
+    }
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/objects/worldentities/pawns/Spectator.h	(revision 2024)
@@ -48,11 +48,11 @@
             virtual void startLocalControl();
 
-            virtual void moveFrontBack(float value);
-            virtual void moveRightLeft(float value);
-            virtual void moveUpDown(float value);
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
 
-            virtual void rotateYaw(float value);
-            virtual void rotatePitch(float value);
-            virtual void rotateRoll(float value);
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
 
             virtual void fire();
@@ -62,4 +62,5 @@
             void changedGreeting();
             void changedFlareVisibility();
+            void updateHUD();
 
             BillboardSet* greetingFlare_;
@@ -73,9 +74,4 @@
             float pitch_;
             float roll_;
-
-            // test test test
-            Mesh* testmesh_;
-            Ogre::SceneNode* testnode_;
-            // test test test
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.cc	(revision 2024)
@@ -53,4 +53,10 @@
     {
         RegisterObject(OverlayGroup);
+    }
+
+    OverlayGroup::~OverlayGroup()
+    {
+        for (std::map<std::string, OrxonoxOverlay*>::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            delete it->second;
     }
 
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayGroup.h	(revision 2024)
@@ -56,5 +56,5 @@
         OverlayGroup(BaseObject* creator);
         //! Empty destructor.
-        ~OverlayGroup() { }
+        ~OverlayGroup();
 
         virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
@@ -63,4 +63,7 @@
         static void scaleGroup(const std::string& name, float scale);
         static void scrollGroup(const std::string& name, const Vector2& scroll);
+
+        inline const std::map<std::string, OrxonoxOverlay*>& getOverlays() const
+            { return this->hudElements_; }
 
         void changedVisibility();
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.cc	(revision 2024)
@@ -65,9 +65,9 @@
         }
 
-        XMLPortParam(OverlayText, "font",     setFont,     getFont,     xmlElement, mode).defaultValues("Monofur");
-        XMLPortParam(OverlayText, "colour",   setColour,   getColour,   xmlElement, mode).defaultValues(ColourValue(1.0, 1.0, 1.0, 1.0));
-        XMLPortParam(OverlayText, "caption",  setCaption,  getCaption,  xmlElement, mode).defaultValues("");
-        XMLPortParam(OverlayText, "textSize", setTextSize, getTextSize, xmlElement, mode).defaultValues(1.0f);
-        XMLPortParamTemplate(OverlayText, "align", setAlignment, getAlignment, xmlElement, mode, const std::string&).defaultValues("left");
+        XMLPortParam(OverlayText, "font",     setFont,            getFont,            xmlElement, mode).defaultValues("Monofur");
+        XMLPortParam(OverlayText, "colour",   setColour,          getColour,          xmlElement, mode).defaultValues(ColourValue(1.0, 1.0, 1.0, 1.0));
+        XMLPortParam(OverlayText, "caption",  setCaption,         getCaption,         xmlElement, mode).defaultValues("");
+        XMLPortParam(OverlayText, "textSize", setTextSize,        getTextSize,        xmlElement, mode).defaultValues(1.0f);
+        XMLPortParam(OverlayText, "align",    setAlignmentString, getAlignmentString, xmlElement, mode).defaultValues("left");
     }
 
@@ -106,5 +106,13 @@
     }
 
-    void OverlayText::setAlignment(const std::string& alignment)
+    Ogre::TextAreaOverlayElement::Alignment OverlayText::getAlignment() const
+    {
+        if (this->text_)
+            return this->text_->getAlignment();
+        else
+            return Ogre::TextAreaOverlayElement::Left;
+    }
+
+    void OverlayText::setAlignmentString(const std::string& alignment)
     {
         if (alignment == "right")
@@ -116,5 +124,5 @@
     }
 
-    std::string OverlayText::getAlignment() const
+    std::string OverlayText::getAlignmentString() const
     {
         if (this->text_)
Index: code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h	(revision 2023)
+++ code/branches/objecthierarchy/src/orxonox/overlays/OverlayText.h	(revision 2024)
@@ -47,7 +47,4 @@
         virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
 
-    protected:
-        virtual void sizeChanged();
-
         void setCaption(const std::string& caption);
         const std::string& getCaption() const       { return this->caption_; }
@@ -60,6 +57,11 @@
 
         void setAlignment(Ogre::TextAreaOverlayElement::Alignment alignment);
-        void setAlignment(const std::string& alignment);
-        std::string getAlignment() const;
+        Ogre::TextAreaOverlayElement::Alignment getAlignment() const;
+
+    protected:
+        virtual void sizeChanged();
+
+        void setAlignmentString(const std::string& alignment);
+        std::string getAlignmentString() const;
 
         void setTextSize(float size) { this->setSize(Vector2(size, size)); }
