Index: code/branches/OrxoBlox_FS19/data/levels/OrxoBlox.oxw
===================================================================
--- code/branches/OrxoBlox_FS19/data/levels/OrxoBlox.oxw	(revision 12210)
+++ code/branches/OrxoBlox_FS19/data/levels/OrxoBlox.oxw	(revision 12210)
@@ -0,0 +1,240 @@
+<LevelInfo
+ name = "Pong"
+ description = "Pong in space!"
+ tags = "minigame"
+ screenshot = "pong.png"
+/>
+
+<?lua
+  include("HUDTemplates3.oxo")
+  include("stats.oxo")
+  include("pongHUD.oxo")
+  include("templates/lodInformation.oxt")
+?>
+
+<Template name=pongbatcameras defaults=0>
+  <PongBat>
+    <camerapositions>
+      <CameraPosition position="0,150,0" pitch=-90 absolute=true />
+      <CameraPosition position="0,50,160" drag=true mouselook=true />
+      <CameraPosition position="0,40,125" drag=true mouselook=true />
+      <CameraPosition position="0,30, 90" drag=true mouselook=true />
+    </camerapositions>
+  </PongBat>
+</Template>
+
+<Template name=pongbat>
+  <PongBat camerapositiontemplate=pongbatcameras>
+    <attached>
+      <Model position="0,0,3" mesh="cube.mesh" scale3D="14,2,2" />
+      <!--Model roll=180 mesh="pongbat.mesh" scale=0.045 /-->
+    </attached>
+  </PongBat>
+</Template>
+
+<Template name=pongball>
+  <PongBall 
+   defScoreSound = "sounds/PlayerWinScore_cut.ogg"
+   defBatSound = "sounds/Button.ogg"
+   defBoundarySound = "sounds/Button.ogg">
+    <attached>
+      <Model mesh="sphere.mesh" scale=2 />
+      <!--Billboard scale=0.2 colour="1.0, 1.0, 0.5" material="Examples/Flare" /-->
+      <Backlight scale=0.2 colour="1.0, 1.0, 0.5" width=7 length=500 lifetime=0.3 elements=20 trailmaterial="Trail/backlighttrail" material="Examples/Flare" />
+      <Light type=point diffuse="1.0, 1.0, 0.5" specular="1.0, 1.0, 0.5" attenuation="1200, 1.0, 0.0035, 0.00005" />
+      <ParticleSpawner name=hiteffect position="0,0,0" source="Orxonox/sparks2" lifetime=0.01 autostart=0 mainstate=spawn />
+    </attached>
+    <eventlisteners>
+      <EventTarget target=hiteffect />
+    </eventlisteners>
+  </PongBall>
+</Template>
+
+
+<Level
+ plugins = "pong"
+ gametype = "Pong"
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+  <?lua include("includes/notifications.oxi") ?>
+
+  <WorldAmbientSound source="Ganymede.ogg" looping="true" playOnLoad="true"/>
+  <PongBot />
+
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skyBoxBasic"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <SpawnPoint position="991.729, -110.11, 435.404" orientation="0.534038, 0.563456, 0.212168, 0.593553" />
+
+    <MovableEntity rotationrate=5 rotationaxis="0,0,1">
+      <attached>
+        <PongCenterpoint name=pongcenter dimension="200,120" balltemplate=pongball battemplate=pongbat ballspeed=200 ballaccfactor=1.0 batspeed=130 batlength=0.25>
+          <attached>
+            <Model position="0,0,60" mesh="cube.mesh" scale3D="105,1,1" />
+            <Model position="0,0,-60" mesh="cube.mesh" scale3D="105,1,1" />
+
+            <ParticleSpawner name=scoreeffect_right position="120,0, 45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0, 30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0, 15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0,  0" source="Orxonox/BigExplosion1part2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0,-15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+            <ParticleSpawner name=scoreeffect_right position="120,0,-45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+
+            <ParticleSpawner name=scoreeffect_left position="-120,0, 45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0, 30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0, 15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0,  0" source="Orxonox/BigExplosion1part2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0,-15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+            <ParticleSpawner name=scoreeffect_left position="-120,0,-45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+
+<!-- TODO: Create a Pong Score Sound and include it here.
+This WorldSound works, but doesn't make sense, since it is played together with ambient/moodDependedDirectory/Ganymede.ogg -->
+            <!--WorldSound name="scoreSound" position="0,0,0" source="sounds/PongScore_cut.ogg" >
+              <events>
+                <play>
+                  <EventListener event=pongcenter />
+                </play>
+              </events>
+            </WorldSound-->
+
+            <?lua
+              for i = 1, 15, 1 do
+            ?>
+              <ParticleSpawner name=scoreeffect_center position="<?lua print(math.random() * 200 - 100) ?>,0,<?lua print(math.random() * 120 - 60) ?>" source="Orxonox/sparks2" lifetime=0.02 autostart=0 startdelay=<?lua print(math.random() * 0.7) ?> />
+            <?lua end ?>
+
+          </attached>
+        </PongCenterpoint>
+      </attached>
+    </MovableEntity>
+
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=scoreeffect_right />
+        <EventTarget target=scoreeffect_center />
+      </targets>
+      <events>
+        <spawn>
+          <EventFilter>
+            <names>
+              <EventName name=right />
+            </names>
+            <EventListener event=pongcenter />
+          </EventFilter>
+        </spawn>
+      </events>
+    </EventDispatcher>
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=scoreeffect_left />
+        <EventTarget target=scoreeffect_center />
+      </targets>
+      <events>
+        <spawn>
+          <EventFilter>
+            <names>
+              <EventName name=left />
+            </names>
+            <EventListener event=pongcenter />
+          </EventFilter>
+        </spawn>
+      </events>
+    </EventDispatcher>
+
+    <?lua
+      dofile("includes/CuboidSpaceStation.lua")
+    ?>
+
+    <StaticEntity pitch=15>
+      <attached>
+        <MovableEntity rotationrate="-4.15786" rotationaxis="0,0,1">
+          <attached>
+            <StaticEntity position="-2500,0,0" yaw=90 pitch=90>
+              <attached>
+                <?lua
+                  createSpaceStationPar(0,2,1,2,1,4,1,50)
+                ?>
+              </attached>
+            </StaticEntity>
+          </attached>
+        </MovableEntity>
+      </attached>
+    </StaticEntity>
+
+    <StaticEntity position="0,1200,-200" yaw=50 pitch=60 roll=45>
+      <attached>
+        <Model scale=10 mesh="Carrier.mesh" />
+        <Model position="0,30,20" scale=10 mesh="pirate.mesh" roll="180" />
+        <Model position="-80,-30,20" scale=10 mesh="pirate.mesh" roll="180" />
+      </attached>
+    </StaticEntity>
+
+    <StaticEntity pitch=70>
+      <attached>
+        <MovableEntity rotationaxis="0,0,1" rotationrate=8.5974>
+          <attached>
+            <StaticEntity yaw=-90 pitch=0 roll=90 position="800,0,0">
+              <attached>
+                <Model position="0,0,0" scale=10 mesh="satellite.mesh" />
+                <MovableEntity position="-4,0,20" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=50>
+                  <attached>
+                    <Model position="0,0,0" scale=10 mesh="satellitedish.mesh"/>
+                  </attached>
+                </MovableEntity>
+                <ParticleEmitter pitch=-135 roll=30 position="-14, 3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+                <ParticleEmitter pitch=135 roll=30 position="-14, 3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+                <ParticleEmitter pitch=-45 roll=30 position="-14,-3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+                <ParticleEmitter pitch=45 roll=30 position="-14,-3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+              </attached>
+            </StaticEntity>
+          </attached>
+        </MovableEntity>
+      </attached>
+    </StaticEntity>
+
+    <?lua
+      for i = 1, 10, 1 do
+    ?>
+      <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 100 + 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+      <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * -100 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+
+      <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 100 + 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+      <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * -100 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+
+      <MovableEntity position="<?lua print(math.random() * 100 + 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+      <MovableEntity position="<?lua print(math.random() * -100 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+        <attached>
+          <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+        </attached>
+      </MovableEntity>
+    <?lua end ?>
+
+  </Scene>
+</Level>
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/CMakeLists.txt
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/CMakeLists.txt	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/CMakeLists.txt	(revision 12210)
@@ -0,0 +1,20 @@
+SET_SOURCE_FILES(PONG_SRC_FILES
+BUILD_UNIT PongBuildUnit.cc
+  Pong.cc
+  PongAI.cc
+  PongBall.cc
+  PongBat.cc
+  PongBot.cc
+  PongCenterpoint.cc
+  PongScore.cc
+END_BUILD_UNIT
+)
+
+ORXONOX_ADD_LIBRARY(pong
+  PLUGIN
+  FIND_HEADER_FILES
+  LINK_LIBRARIES
+    orxonox
+    overlays
+  SOURCE_FILES ${PONG_SRC_FILES}
+)
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.cc	(revision 12210)
@@ -0,0 +1,347 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file Pong.cc
+    @brief Implementation of the Pong class.
+*/
+
+#include "Pong.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/command/Executor.h"
+#include "core/config/ConfigValueIncludes.h"
+
+#include "gamestates/GSLevel.h"
+#include "chat/ChatManager.h"
+
+#include "PongCenterpoint.h"
+#include "PongBall.h"
+#include "PongBat.h"
+#include "PongBot.h"
+#include "PongAI.h"
+
+namespace orxonox
+{
+    // Events to allow to react to scoring of a player, in the level-file.
+    CreateEventName(PongCenterpoint, right);
+    CreateEventName(PongCenterpoint, left);
+
+    RegisterUnloadableClass(Pong);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    Pong::Pong(Context* context) : Deathmatch(context)
+    {
+        RegisterObject(Pong);
+
+        this->center_ = nullptr;
+        this->ball_ = nullptr;
+        this->bat_[0] = nullptr;
+        this->bat_[1] = nullptr;
+
+        this->setHUDTemplate("PongHUD");
+
+        // Pre-set the timer, but don't start it yet.
+        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Pong::startBall, this)));
+        this->starttimer_.stopTimer();
+
+        // Set the type of Bots for this particular Gametype.
+        this->botclass_ = Class(PongBot);
+
+        this->scoreLimit_ = 10;
+        this->setConfigValues();
+    }
+
+    /**
+    @brief
+        Destructor. Cleans up, if initialized.
+    */
+    Pong::~Pong()
+    {
+        if (this->isInitialized())
+            this->cleanup();
+    }
+
+    void Pong::setConfigValues()
+    {
+        SetConfigValue(scoreLimit_, 10).description("The player first reaching those points wins.");
+    }
+
+    /**
+    @brief
+        Cleans up the Gametype by destroying the ball and the bats.
+    */
+    void Pong::cleanup()
+    {
+        if (this->ball_ != nullptr) // Destroy the ball, if present.
+        {
+            this->ball_->destroy();
+            this->ball_ = nullptr;
+        }
+
+        // Destroy both bats, if present.
+        for (size_t i = 0; i < 2; ++i)
+        {
+            if (this->bat_[0] != nullptr)
+            {
+                this->bat_[0]->destroy();
+                this->bat_[0] = nullptr;
+            }
+        }
+
+    }
+
+    /**
+    @brief
+        Starts the Pong minigame.
+    */
+    void Pong::start()
+    {
+        if (this->center_ != nullptr) // There needs to be a PongCenterpoint, i.e. the area the game takes place.
+        {
+            if (this->ball_ == nullptr) // If there is no ball, create a new ball.
+            {
+                this->ball_ = new PongBall(this->center_->getContext());
+                // Apply the template for the ball specified by the centerpoint.
+                this->ball_->addTemplate(this->center_->getBalltemplate());
+            }
+
+            // Attach the ball to the centerpoint and set the parameters as specified in the centerpoint, the ball is attached to.
+            this->center_->attach(this->ball_);
+            this->ball_->setPosition(0, 0, 0);
+            this->ball_->setFieldDimension(this->center_->getFieldDimension());
+            this->ball_->setSpeed(0);
+            this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
+            this->ball_->setBatLength(this->center_->getBatLength());
+
+            // If one of the bats is missing, create it. Apply the template for the bats as specified in the centerpoint.
+            for (WeakPtr<orxonox::PongBat>& bat : this->bat_)
+            {
+                if (bat == nullptr)
+                {
+                    bat = new PongBat(this->center_->getContext());
+                    bat->addTemplate(this->center_->getBattemplate());
+                }
+            }
+
+            // Attach the bats to the centerpoint and set the parameters as specified in the centerpoint, the bats are attached to.
+            this->center_->attach(this->bat_[0]);
+            this->center_->attach(this->bat_[1]);
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[0]->yaw(Degree(-90));
+            this->bat_[1]->yaw(Degree(90));
+            this->bat_[0]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[1]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[0]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[1]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[0]->setLength(this->center_->getBatLength());
+            this->bat_[1]->setLength(this->center_->getBatLength());
+
+            // Set the bats for the ball.
+            this->ball_->setBats(this->bat_);
+        }
+        else // If no centerpoint was specified, an error is thrown and the level is exited.
+        {
+            orxout(internal_error) << "Pong: No Centerpoint specified." << endl;
+            GSLevel::startMainMenu();
+            return;
+        }
+
+        // Start the timer. After it has expired the ball is started.
+        this->starttimer_.startTimer();
+
+        // Set variable to temporarily force the player to spawn.
+        bool temp = this->bForceSpawn_;
+        this->bForceSpawn_ = true;
+
+        // Call start for the parent class.
+        Deathmatch::start();
+
+        // Reset the variable.
+        this->bForceSpawn_ = temp;
+    }
+
+    /**
+    @brief
+        Ends the Pong minigame.
+    */
+    void Pong::end()
+    {
+        this->cleanup();
+
+        // Call end for the parent class.
+        Deathmatch::end();
+    }
+
+    /**
+    @brief
+        Spawns players, and fills the rest up with bots.
+    */
+    void Pong::spawnPlayersIfRequested()
+    {
+        // first spawn human players to assign always the left bat to the player in singleplayer
+        for (const auto& mapEntry : this->players_)
+            if (mapEntry.first->isHumanPlayer() && (mapEntry.first->isReadyToSpawn() || this->bForceSpawn_))
+                this->spawnPlayer(mapEntry.first);
+        // now spawn bots
+        for (const auto& mapEntry : this->players_)
+            if (!mapEntry.first->isHumanPlayer() && (mapEntry.first->isReadyToSpawn() || this->bForceSpawn_))
+                this->spawnPlayer(mapEntry.first);
+    }
+
+    /**
+    @brief
+        Spawns the input player.
+    @param player
+        The player to be spawned.
+    */
+    void Pong::spawnPlayer(PlayerInfo* player)
+    {
+        assert(player);
+
+        // If the first (left) bat has no player.
+        if (this->bat_[0]->getPlayer() == nullptr)
+        {
+            player->startControl(this->bat_[0]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+        // If the second (right) bat has no player.
+        else if (this->bat_[1]->getPlayer() == nullptr)
+        {
+            player->startControl(this->bat_[1]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+        // If both bats are taken.
+        else
+            return;
+
+        // If the player is an AI, it receives a pointer to the ball.
+        if (player->getController() != nullptr && player->getController()->isA(Class(PongAI)))
+        {
+            PongAI* ai = orxonox_cast<PongAI*>(player->getController());
+            ai->setPongBall(this->ball_);
+        }
+    }
+
+    /**
+    @brief
+        Is called when the player scored.
+    */
+    void Pong::playerScored(PlayerInfo* player, int score)
+    {
+        Deathmatch::playerScored(player, score);
+
+        if (this->center_ != nullptr) // If there is a centerpoint.
+        {
+            // Fire an event for the player that has scored, to be able to react to it in the level, e.g. by displaying fireworks.
+            if (player == this->getRightPlayer())
+                this->center_->fireEvent(FireEventName(PongCenterpoint, right));
+            else if (player == this->getLeftPlayer())
+                this->center_->fireEvent(FireEventName(PongCenterpoint, left));
+
+            // Also announce, that the player has scored.
+            if (player != nullptr)
+                this->gtinfo_->sendAnnounceMessage(player->getName() + " scored");
+        }
+
+        // If there is a ball present, reset its position, velocity and acceleration.
+        if (this->ball_ != nullptr)
+        {
+            this->ball_->setPosition(Vector3::ZERO);
+            this->ball_->setVelocity(Vector3::ZERO);
+            this->ball_->setAcceleration(Vector3::ZERO);
+            this->ball_->setSpeed(0);
+        }
+
+        // If there are bats reset them to the middle position.
+        if (this->bat_[0] != nullptr && this->bat_[1] != nullptr)
+        {
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+        }
+
+        // If a player gets enough points, he won the game -> end of game
+        PlayerInfo* winningPlayer = nullptr;
+        if (this->getLeftPlayer() && this->getScore(this->getLeftPlayer()) >= scoreLimit_)
+            winningPlayer = this->getLeftPlayer();
+        else if (this->getRightPlayer() && this->getScore(this->getRightPlayer()) >= scoreLimit_)
+            winningPlayer = this->getRightPlayer();
+
+        if (winningPlayer)
+        {
+             ChatManager::message(winningPlayer->getName() + " has won!");
+             this->end();
+        }
+
+        // Restart the timer to start the ball.
+        this->starttimer_.startTimer();
+    }
+
+    /**
+    @brief
+        Starts the ball with some default speed.
+    */
+    void Pong::startBall()
+    {
+        if (this->ball_ != nullptr && this->center_ != nullptr)
+            this->ball_->setSpeed(this->center_->getBallSpeed());
+    }
+
+    /**
+    @brief
+        Get the left player.
+    @return
+        Returns a pointer to the player playing on the left. If there is no left player, nullptr is returned.
+    */
+    PlayerInfo* Pong::getLeftPlayer() const
+    {
+        if (this->bat_[0] != nullptr)
+            return this->bat_[0]->getPlayer();
+        else
+            return nullptr;
+    }
+
+    /**
+    @brief
+        Get the right player.
+    @return
+        Returns a pointer to the player playing on the right. If there is no right player, nullptr is returned.
+    */
+    PlayerInfo* Pong::getRightPlayer() const
+    {
+        if (this->bat_[1] != nullptr)
+            return this->bat_[1]->getPlayer();
+        else
+            return nullptr;
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBlox.h	(revision 12210)
@@ -0,0 +1,102 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file OrxoBlox.h
+    @brief Declaration of the OrxoBlox class.
+    @ingroup OrxoBlox
+*/
+
+#ifndef _OrxoBlox_H__
+#define _OrxoBlox_H__
+
+#include "OrxoBlox/OrxoBloxPrereqs.h"
+
+#include "tools/Timer.h"
+
+#include "gametypes/Deathmatch.h"
+#include "PongCenterpoint.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Implements a Pong minigame (<a href="http://en.wikipedia.org/wiki/Pong">Wikipedia::Pong</a>).
+        It connects the different entities present in a game of Pong.
+
+        - The @ref orxonox::PongCenterpoint "PongCenterpoint" is the playing field for the Pong minigame, it allows for configuration of the minigame, e.g. by setting the size of the playing field, or the length of the @ref orxonox::PongBat "PongBats". The playing field is always in the x,y-plane, the x-axis being the horizontal and the z-axis being the vertical axis.<br />
+        The Pong class redistributes the important parameters defined in @ref orxonox::PongCenterpoint "PongCenterpoint" to the other entities, that need to know them, e.g. the @ref orxonox::PongBall "PongBall" and the @ref orxonox::PongBat "PongBats".<br />
+        The @ref orxonox::PongCenterpoint "PongCenterpoint" needs to exist in a level with the @ref orxonox::Gametype "Gametype" <em>Pong</em>.
+        - The @ref orxonox::PongBall "PongBall" is the ball both players play with. The @ref orxonox::PongBall "PongBall" both implements the movement of the ball, as well as the influence of the boundaries and consequently, also the bouncing (off the upper and lower delimiters, and as off the @ref orxonox::PongBat "PongBats") of the ball and the effects of the failure of a player to catch the ball (i.e. the scoring of the other player).
+        - The two @ref orxonox::PongBat "PongBats" are the entities through which the players can actively participate in the game, by controlling them. The @ref orxonox::PongBat "PongBat" class manages the movement (and restrictions thereof) and the influence of the players on the bats.
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup Pong
+    */
+    class _PongExport Pong : public Deathmatch
+    {
+        public:
+            Pong(Context* context); //!< Constructor. Registers and initializes the object.
+            virtual ~Pong(); //!< Destructor. Cleans up, if initialized.
+
+            virtual void start() override; //!< Starts the Pong minigame.
+            virtual void end() override; ///!< Ends the Pong minigame.
+
+            virtual void spawnPlayer(PlayerInfo* player) override; //!< Spawns the input player.
+
+            virtual void playerScored(PlayerInfo* player, int score = 1) override; //!< Is called when the player scored.
+
+            /**
+            @brief Set the PongCenterpoint (the playing field).
+            @param center A pointer to the PongCenterpoint to be set.
+            */
+            void setCenterpoint(PongCenterpoint* center)
+                { this->center_ = center; }
+            void setConfigValues(); //!< Makes scoreLimit configurable.
+
+            PlayerInfo* getLeftPlayer() const; //!< Get the left player.
+            PlayerInfo* getRightPlayer() const; //!< Get the right player.
+
+        protected:
+            virtual void spawnPlayersIfRequested() override; //!< Spawns players, and fills the rest up with bots.
+
+            void startBall(); //!< Starts the ball with some default speed.
+            void cleanup(); //!< Cleans up the Gametype by destroying the ball and the bats.
+
+            WeakPtr<PongCenterpoint> center_; //!< The playing field.
+            WeakPtr<PongBall> ball_; //!< The Pong ball.
+            WeakPtr<PongBat> bat_[2]; //!< The two bats.
+            Timer starttimer_; //!< A timer to delay the start of the game.
+            int scoreLimit_; //!< If a player scored that much points, the game is ended.
+    };
+}
+
+#endif /* _Pong_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.cc	(revision 12210)
@@ -0,0 +1,305 @@
+
+//TODO: Sounds (all the sounds are still from the pong module...)
+//TODO: Blocks (the Ball-Block comunication is based on how the blocks are implemented)
+//TODO: The bottom boundary/ the Ball collecter
+//TODO: Ability to shoot the ball (the ball is still constructed like the pong ball)
+
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file OrxoBloxBall.cc
+    @brief Implementation of the OrxoBloxBall class.
+*/
+
+#include "OrxoBloxBall.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+
+#include "gametypes/Gametype.h"
+
+#include "OrxoBloxBlocks.h"
+
+#include "sound/WorldSound.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    RegisterClass(OrxoBloxBall);
+
+    const float OrxoBloxBall::MAX_REL_Z_VELOCITY = 1.5;
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    OrxoBloxBall::OrxoBloxBall(Context* context)
+        : MovableEntity(context)
+    {
+        RegisterObject(OrxoBloxBall);
+
+        this->speed_ = 0;
+        this->accelerationFactor_ = 1.0f;
+        this->block_ = nullptr;
+        this->bDeleteBlock_ = false;
+        this->blockID_ = new unsigned int[100];
+	for (int i = 0; i < 100; i++) {
+		this->blockID_[i] = OBJECTID_UNKNOWN;
+	}
+
+        this->registerVariables();
+
+        //initialize sound
+        if (GameMode::isMaster())
+             {
+                 this->defScoreSound_ = new WorldSound(this->getContext());
+                 this->defScoreSound_->setVolume(1.0f);
+                 this->defBatSound_ = new WorldSound(this->getContext());
+                 this->defBatSound_->setVolume(0.4f);
+                 this->defBoundarySound_ = new WorldSound(this->getContext());
+                 this->defBoundarySound_->setVolume(0.5f);
+             }
+             else
+             {
+                 this->defScoreSound_ = nullptr;
+                 this->defBatSound_ = nullptr;
+                 this->defBoundarySound_ = nullptr;
+             }
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    OrxoBloxBall::~OrxoBloxBall()
+    {
+        if (this->isInitialized())
+        {
+            if (this->bDeleteBlock_)
+                delete[] this->block_;
+
+            delete[] this->blockID_;
+        }
+    }
+
+    //xml port for loading sounds
+    void OrxoBloxBall::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(OrxoBloxBall, XMLPort, xmlelement, mode);
+        XMLPortParam(OrxoBloxBall, "defScoreSound",  setDefScoreSound,  getDefScoreSound,  xmlelement, mode);
+        XMLPortParam(OrxoBloxBall, "defBatSound",  setDefBatSound,  getDefBatSound,  xmlelement, mode);
+        XMLPortParam(OrxoBloxBall, "defBoundarySound",  setDefBoundarySound,  getDefBoundarySound,  xmlelement, mode);
+    }
+
+    /**
+    @brief
+        Register variables to synchronize over the network.
+    */
+    void OrxoBloxBall::registerVariables()
+    {
+        registerVariable( this->fieldWidth_ );
+        registerVariable( this->fieldHeight_ );
+        registerVariable( this->blocklength_ );
+        registerVariable( this->speed_ );
+        registerVariable( this->blockID_[0] );
+        registerVariable( this->blockID_[1], VariableDirection::ToClient, new NetworkCallback<OrxoBloxBall>( this, &OrxoBloxBall::applyBlock) );
+    }
+
+    /**
+    @brief
+        Is called every tick.
+        Handles the movement of the ball and its interaction with the boundaries and blocks.
+    @param dt
+        The time since the last tick.
+    */
+    void OrxoBloxBall::tick(float dt)
+    {
+        SUPER(OrxoBloxBall, tick, dt);
+
+        // Get the current position, velocity and acceleration of the ball.
+        Vector3 position = this->getPosition();
+        Vector3 velocity = this->getVelocity();
+        Vector3 acceleration = this->getAcceleration();
+
+        // If the ball has hit the boundaries on either the right side or the left 
+        if (position.x > this->fieldWidth_ / 2 || position.x < -this->fieldWidth_ / 2)
+        {
+            defBoundarySound_->play(); //play boundary sound
+            // Its velocity in x-direction is inverted (i.e. it bounces off).
+            velocity.x = -velocity.x;
+            // And its position is set as to not overstep the boundary it has just crossed.
+            if (position.x > this->fieldWidth_ / 2)
+                position.x = this->fieldWidth_ / 2;
+            if (position.x < -this->fieldWidth_ / 2)
+                position.x = -this->fieldWidth_ / 2;
+
+            this->fireEvent();
+        }
+
+	// If the ball has hit the boundary on the top
+        if (position.z > this->fieldHeight_ / 2)
+        {
+            defBoundarySound_->play(); //play boundary sound
+            // Its velocity in z-direction is inverted (i.e. it bounces off).
+            velocity.z = -velocity.z;
+            // And its position is set as to not overstep the boundary it has just crossed.
+            position.z = this->fieldHeight_ / 2;
+
+            this->fireEvent();
+        }
+
+        // If the ball has crossed the bottom boundary
+        if (position.z < -this->fieldHeight_ / 2)
+        {
+	//TODO: Ball Collector
+        }
+
+        // Set the position, velocity and acceleration of the ball, if they have changed.
+        if (acceleration != this->getAcceleration())
+            this->setAcceleration(acceleration);
+        if (velocity != this->getVelocity())
+            this->setVelocity(velocity);
+        if (position != this->getPosition())
+            this->setPosition(position);
+    }
+
+    /**
+    @brief
+        Set the speed of the ball (in x-direction).
+    @param speed
+        The speed to be set.
+    */
+    void OrxoBloxBall::setSpeed(float speed)
+    {
+        if (speed != this->speed_) // If the speed changes
+        {
+            this->speed_ = speed;
+
+            // Set the speed in the direction of the balls current velocity.
+            Vector3 velocity = this->getVelocity();
+            if (velocity.x != 0)
+                velocity.x = sgn(velocity.x) * this->speed_;
+            else // If the balls current velocity is zero, the speed is set in a random direction.
+                velocity.x = this->speed_ * sgn(rnd(-1,1));
+
+            this->setVelocity(velocity);
+        }
+    }
+
+    /**
+    @brief
+        Set the blocks for the ball.
+    @param bats
+        An array (of size n (n=#Blocks) of weak pointers, to be set as the new blocks.
+    */
+    void OrxoBloxBall::setBlock(WeakPtr<OrxoBloxBlock>* block, int n)
+    {
+        if (this->bDeleteBlock_) // If there are already some blocks, delete them.
+        {
+            delete[] this->block_;
+            this->bDeleteBlock_ = false;
+        }
+
+        this->block_ = block;
+        // Also store their object IDs, for synchronization.
+	for (int i = 0; i < n; i++) {
+        	this->blockID_[i] = this->block_[i]->getObjectID();
+	}
+    }
+
+    /**
+    @brief
+        Get the blocks over the network.
+    */
+    void OrxoBloxBall::applyBlock(int n)
+    {
+        // Make space for the blocks, if they don't exist, yet.
+        if (this->block_ == nullptr)
+        {
+            this->block_ = new WeakPtr<OrxoBloxBlock>[n];
+            this->bDeleteBlock_ = true;
+        }
+	
+	for (int i = 0; i < n; i++) {
+		if (this->blockID_[i] != OBJECTID_UNKNOWN)
+            	this->bat_[i] = orxonox_cast<OrxoBloxBlock*>(Synchronisable::getSynchronisable(this->blockID_[i]));
+	}
+    }
+
+    void OrxoBloxBall::setDefScoreSound(const std::string &pongSound)
+    {
+        if( defScoreSound_ )
+            defScoreSound_->setSource(pongSound);
+        else
+            assert(0); // This should never happen, because soundpointer is only available on master
+    }
+
+    const std::string& OrxoBloxBall::getDefScoreSound()
+    {
+        if( defScoreSound_ )
+            return defScoreSound_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+
+    void OrxoBloxBall::setDefBatSound(const std::string &pongSound)
+    {
+        if( defBatSound_ )
+            defBatSound_->setSource(pongSound);
+        else
+            assert(0); // This should never happen, because soundpointer is only available on master
+    }
+
+    const std::string& OrxoBloxBall::getDefBatSound()
+    {
+        if( defBatSound_ )
+            return defBatSound_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+
+    void OrxoBloxBall::setDefBoundarySound(const std::string &pongSound)
+    {
+        if( defBoundarySound_ )
+            defBoundarySound_->setSource(pongSound);
+        else
+            assert(0); // This should never happen, because soundpointer is only available on master
+    }
+
+    const std::string& OrxoBloxBall::getDefBoundarySound()
+    {
+        if( defBoundarySound_ )
+            return defBoundarySound_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxBall.h	(revision 12210)
@@ -0,0 +1,153 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file OrxoBloxBall.h
+    @brief Declaration of the OrxoBloxBall class.
+    @ingroup OrxoBlox
+*/
+
+#ifndef _OrxoBloxBall_H__
+#define _OrxoBloxBall_H__
+
+#include "OrxoBlox/OrxoBloxPrereqs.h"
+
+#include "util/Math.h"
+
+#include "worldentities/MovableEntity.h"
+
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        This class manages the ball for @ref orxonox::OrxoBlox "OrxoBlox".
+
+        It is responsible for both the movement of the ball in the x,y-plane as well as its interaction with the boundaries of the playing field (defined by the @ref orxonox::OrxoBloxCenterpoint "OrxoBloxCenterpoint") and the @ref orxonox::OrxoBloxBlocks "OrxoBloxBlocks". Or more precisely, it makes the ball bounce off then left and right delimiters of the playing field, it makes the ball bounce off the blocks, damages them and also detects when it reaches the lower bound and takes appropriate measures.
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup OrxoBlox
+    */
+    class _OrxoBloxExport OrxoBloxBall : public MovableEntity
+    {
+        public:
+            OrxoBloxBall(Context* context);
+            virtual ~OrxoBloxBall();
+
+            virtual void tick(float dt) override;
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode) override;
+
+            /**
+            @brief Set the dimensions of the playing field.
+            @param width The width of the playing field.
+            @param height The height of the playing field.
+            */
+            void setFieldDimension(float width, float height)
+                { this->fieldWidth_ = width; this->fieldHeight_ = height; }
+            /**
+            @brief Get the dimensions of the playing field.
+            @param dimension A vector with the width as the first and height as the second 		    component.
+            */
+            void setFieldDimension(const Vector2& dimension)
+                { this->setFieldDimension(dimension.x, dimension.y); }
+            /**
+            @brief Get the dimensions of the playing field.
+            @return Returns a vector with the width as the first and height as the second 	  	      component.
+            */
+            Vector2 getFieldDimension() const
+                { return Vector2(this->fieldWidth_, this->fieldHeight_); }
+
+            void setSpeed(float speed); //!< Set the speed of the ball (in x-direction).
+            /**
+            @brief Get the speed of the ball (in x-direction).
+            @return Returns the speed of the ball (in x-direction).
+            */
+            float getSpeed() const
+                { return this->speed_; }
+
+            /**
+            @brief Set the acceleration factor of the ball.
+            @param factor The factor the acceleration of the ball is set to.
+            */
+            void setAccelerationFactor(float factor)
+                { this->accelerationFactor_ = factor; }
+            /**
+            @brief Get the acceleration factor of the ball.
+            @return Returns the acceleration factor of the ball.
+            */
+            float getAccelerationFactor() const
+                { return this->accelerationFactor_; }
+
+            /**
+            @brief Set the length of the blocks.
+            @param batlength The length of the blocks (in x-direction) as percentage of the height 		    of the playing field.
+            */
+            void setBlockLength(float blocklength)
+                { this->blocklength_ = blocklength; }
+            /**
+            @brief Get the length of the blocks.
+            @return Returns the length of the blocks as percentage of the height of the playing 	    field.
+            */
+            float getBlockLength() const
+		{ return this->blocklength_; }
+
+            void setBlock(WeakPtr<OrxoBloxBlock>* block); //!< Set the blocks for the ball.
+            void applyBlock(); //!< Get the block over the network.
+
+            static const float MAX_REL_Z_VELOCITY;
+
+            void setDefScoreSound(const std::string& engineSound);
+            const std::string& getDefScoreSound();
+            void setDefBatSound(const std::string& engineSound);
+            const std::string& getDefBatSound();
+            void setDefBoundarySound(const std::string& engineSound);
+            const std::string& getDefBoundarySound();
+
+        private:
+            void registerVariables();
+
+            float fieldWidth_; //!< The width of the playing field.
+            float fieldHeight_; //!< The height of the playing field.
+            float speedX_; //!< The speed (in x-direction) of the ball.
+            float speedY_; //!< The speed (in y-direction) of the ball.
+            float accelerationFactor_; //!< The acceleration factor of the ball.
+            float blocklength_; //!< The length of the bats (in z-direction) as percentage of the 	    height of the playing field.
+            WeakPtr<OrxoBloxBlock>* block_; //!< An array with the blocks.
+            bool bDeleteBlock_; //!< Bool, to keep track, of whether this->block_ exists or not.
+            unsigned int* blockID_; //!< The object IDs of the blocks, to be able to synchronize 		    them over the network.
+            WorldSound* defScoreSound_;
+            WorldSound* defBatSound_;
+            WorldSound* defBoundarySound_;
+    };
+}
+
+#endif /* _OrxoBloxBall_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxPrereqs.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxPrereqs.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/OrxoBloxPrereqs.h	(revision 12210)
@@ -0,0 +1,79 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the OrxoBlox module
+*/
+
+#ifndef _OrxoBloxPrereqs_H__
+#define _OrxoBloxPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(PONG_STATIC_BUILD)
+#  ifdef PONG_SHARED_BUILD
+#    define _PongExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _PongExport
+#    else
+#      define _PongExport __declspec(dllimport)
+#    endif
+#  endif
+#  define _PongPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
+#  define _PongExport  __attribute__ ((visibility("default")))
+#  define _PongPrivate __attribute__ ((visibility("hidden")))
+#else
+#  define _PongExport
+#  define _PongPrivate
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class Pong;
+    class PongAI;
+    class PongBall;
+    class PongBat;
+    class PongBot;
+    class PongCenterpoint;
+    class PongScore;
+}
+
+#endif /* _PongPrereqs_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.cc	(revision 12210)
@@ -0,0 +1,385 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongAI.cc
+    @brief Implementation of the PongAI class.
+*/
+
+#include "PongAI.h"
+
+#include "core/CoreIncludes.h"
+#include "core/config/ConfigValueIncludes.h"
+#include "core/command/Executor.h"
+#include "tools/Timer.h"
+
+#include "worldentities/ControllableEntity.h"
+
+#include "PongBall.h"
+
+namespace orxonox
+{
+    RegisterUnloadableClass(PongAI);
+
+    const static float MAX_REACTION_TIME = 0.4f;
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    PongAI::PongAI(Context* context) : Controller(context)
+    {
+        RegisterObject(PongAI);
+
+        this->ball_ = nullptr;
+        this->ballDirection_ = Vector2::ZERO;
+        this->ballEndPosition_ = 0;
+        this->randomOffset_ = 0;
+        this->bChangedRandomOffset_ = false;
+        this->relHysteresisOffset_ = 0.02f;
+        this->strength_ = 0.5f;
+        this->movement_ = 0;
+        this->oldMove_ = 0;
+        this->bOscillationAvoidanceActive_ = false;
+
+        this->setConfigValues();
+    }
+
+    /**
+    @brief
+        Destructor. Cleans up the list fo reaction timers.
+    */
+    PongAI::~PongAI()
+    {
+        for (std::pair<Timer*, char>& pair : this->reactionTimers_)
+            delete pair.first;
+    }
+
+    /**
+    @brief
+        Sets config values.
+    */
+    void PongAI::setConfigValues()
+    {
+        // Sets the strength of the PongAi as a config value.
+        SetConfigValue(strength_, 0.5).description("A value from 0 to 1 where 0 is weak and 1 is strong.");
+    }
+
+    /**
+    @brief
+        Is called each tick.
+        Implements the behavior of the PongAI (i.e. its intelligence).
+    @param dt
+        The time that has elapsed since the last tick.
+    */
+    void PongAI::tick(float dt)
+    {
+        // If either the ball, or the controllable entity (i.e. the bat) don't exist (or aren't set).
+        if (this->ball_  == nullptr || this->getControllableEntity() == nullptr)
+            return;
+
+        Vector3 mypos = this->getControllableEntity()->getPosition();
+        Vector3 ballpos = this->ball_->getPosition();
+        Vector3 ballvel = this->ball_->getVelocity();
+        float hysteresisOffset = this->relHysteresisOffset_ * this->ball_->getFieldDimension().y;
+
+        char move = 0;
+        bool delay = false;
+
+        // Check in which direction the ball is flying
+        if ((mypos.x > 0 && ballvel.x < 0) || (mypos.x < 0 && ballvel.x > 0))
+        {
+            // The ball is flying away
+            this->ballDirection_.x = -1;
+            this->ballDirection_.y = 0;
+            this->bOscillationAvoidanceActive_ = false;
+
+            // Move to the middle
+            if (mypos.z > hysteresisOffset)
+                move = 1;
+            else if (mypos.z < -hysteresisOffset)
+                move = -1;
+        }
+        else if (ballvel.x == 0)
+        {
+            // The ball is standing still
+            this->ballDirection_.x = 0;
+            this->ballDirection_.y = 0;
+            this->bOscillationAvoidanceActive_ = false;
+        }
+        else
+        {
+            // The ball is approaching
+            if (this->ballDirection_.x != 1)
+            {
+                // The ball just started to approach, initialize all values
+                this->ballDirection_.x = 1;
+                this->ballDirection_.y = sgn(ballvel.z);
+                this->ballEndPosition_ = 0;
+                this->randomOffset_ = 0;
+                this->bChangedRandomOffset_ = false;
+
+                this->calculateRandomOffset();
+                this->calculateBallEndPosition();
+                delay = true;
+                this->bOscillationAvoidanceActive_ = false;
+            }
+
+            if (this->ballDirection_.y != sgn(ballvel.z))
+            {
+                // The ball just bounced from a bound, recalculate the predicted end position
+                this->ballDirection_.y = sgn(ballvel.z);
+
+                this->calculateBallEndPosition();
+                delay = true;
+                this->bOscillationAvoidanceActive_ = false;
+            }
+
+            // If the ball is close enough, calculate another random offset to accelerate the ball
+            if (!this->bChangedRandomOffset_)
+            {
+                float timetohit = (-ballpos.x + this->ball_->getFieldDimension().x / 2 * sgn(ballvel.x)) / ballvel.x;
+                if (timetohit < 0.05)
+                {
+                    this->bChangedRandomOffset_ = true;
+                    if (rnd() < this->strength_)
+                        this->calculateRandomOffset();
+                }
+            }
+
+            // Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
+            if (!this->bOscillationAvoidanceActive_)
+            {
+                float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
+
+                if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
+                    move = 1;
+                else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
+                    move = -1;
+            }
+
+            if (move != 0 && this->oldMove_ != 0 && move != this->oldMove_ && !delay)
+            {
+                // We had to correct our position because we moved too far
+                // (and delay is false, so we're not in the wrong place because of a new end-position prediction)
+                if (fabs(mypos.z - this->ballEndPosition_) < 0.5 * this->ball_->getBatLength() * this->ball_->getFieldDimension().y)
+                {
+                    // We're not at the right position, but we still hit the ball, so just stay there to avoid oscillation
+                    move = 0;
+                    this->bOscillationAvoidanceActive_ = true;
+                }
+            }
+        }
+
+        this->oldMove_ = move;
+        this->move(move, delay);
+        this->getControllableEntity()->moveFrontBack(this->movement_);
+    }
+
+    /**
+    @brief
+        Calculates the random offset, that accounts for random errors the AI makes in order to be beatable.
+        The higher the strength of the AI, the smaller the (expected value of the) error.
+        The result of this method is stored in this->randomOffset_.
+    */
+    void PongAI::calculateRandomOffset()
+    {
+        // Calculate the exponent for the position-formula
+        float exp = pow(10.0f, 1.0f - 2.0f*this->strength_); // strength: 0   -> exp = 10
+                                                             // strength: 0.5 -> exp = 1
+                                                             // strength: 1   -> exp = 0.1
+
+        // Calculate the relative position where to hit the ball with the bat
+        float position = pow(rnd(), exp); // exp > 1 -> position is more likely a small number
+                                          // exp < 1 -> position is more likely a large number
+
+        // The position shouldn't be larger than 0.5 (50% of the bat-length from the middle is the end)
+        position *= 0.48f;
+
+        // Both sides are equally probable
+        position *= rndsgn();
+
+        // Calculate the offset in world units
+        this->randomOffset_ = position * this->ball_->getBatLength() * this->ball_->getFieldDimension().y;
+    }
+
+    /**
+    @brief
+        Calculate the end position the ball will be in.
+        The result of this calculation is stored in this->ballEndPosition_.
+    */
+    void PongAI::calculateBallEndPosition()
+    {
+        Vector3 position = this->ball_->getPosition();
+        Vector3 velocity = this->ball_->getVelocity();
+        Vector3 acceleration = this->ball_->getAcceleration();
+        Vector2 dimension = this->ball_->getFieldDimension();
+
+        // Calculate bounces. The number of predicted bounces is limited by the AIs strength
+        for (float limit = -0.05f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
+        {
+            // calculate the time until the ball reaches the other side
+            float totaltime = (-position.x + dimension.x / 2 * sgn(velocity.x)) / velocity.x;
+
+            // calculate wall bounce position (four possible solutions of the equation: pos.z + vel.z*t + acc.z/2*t^2 = +/- dim.z/2)
+            float bouncetime = totaltime;
+            bool bUpperWall = false;
+
+            if (acceleration.z == 0)
+            {
+                if (velocity.z > 0)
+                {
+                    bUpperWall = true;
+                    bouncetime = (dimension.y/2 - position.z) / velocity.z;
+                }
+                else if (velocity.z < 0)
+                {
+                    bUpperWall = false;
+                    bouncetime = (-dimension.y/2 - position.z) / velocity.z;
+                }
+            }
+            else
+            {
+                // upper wall
+                float temp = velocity.z*velocity.z + 2*acceleration.z*(dimension.y/2 - position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = true;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = true;
+                    }
+                }
+                // lower wall
+                temp = velocity.z*velocity.z - 2*acceleration.z*(dimension.y/2 + position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = false;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = false;
+                    }
+                }
+            }
+
+            if (bouncetime < totaltime)
+            {
+                // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
+                float randomErrorX = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+                float randomErrorZ = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+
+                // ball bounces after <bouncetime> seconds, update the position and continue
+                velocity.z = velocity.z + acceleration.z * bouncetime;
+
+                if (bUpperWall)
+                {
+                    position.z = dimension.y / 2;
+                    velocity.z = -fabs(velocity.z) + fabs(randomErrorZ);
+                }
+                else
+                {
+                    position.z = -dimension.y / 2;
+                    velocity.z = fabs(velocity.z) - fabs(randomErrorZ);
+                }
+
+                position.x = position.x + velocity.x * bouncetime + randomErrorX;
+                this->ballEndPosition_ = position.z;
+            }
+            else
+            {
+                // ball doesn't bounce, calculate the end position and return
+                // calculate end-height: current height + slope * distance incl. acceleration
+                this->ballEndPosition_ = position.z + velocity.z * totaltime + acceleration.z / 2 * totaltime * totaltime;
+                return;
+            }
+        }
+    }
+
+    /**
+    @brief
+        Determine the movement the AI will undertake. (Either -1, 0 or 1)
+        The result of this calculation is stored in this->movement_;
+    @param direction
+        The current direction of movement.
+    @param bUseDelay
+        The time by which this move is delayed. (Again, to make the AI less efficient)
+    */
+    void PongAI::move(char direction, bool bUseDelay)
+    {
+        // The current direction is either what we're doing right now (movement_) or what is last in the queue
+        char currentDirection = this->movement_;
+        if (this->reactionTimers_.size() > 0)
+            currentDirection = this->reactionTimers_.back().second;
+
+        // Only add changes of direction
+        if (direction == currentDirection)
+            return;
+
+        if (bUseDelay)
+        {
+            // Calculate delay
+            float delay = MAX_REACTION_TIME * (1 - this->strength_);
+
+            // Add a new Timer
+            Timer* timer = new Timer(delay, false, createExecutor(createFunctor(&PongAI::delayedMove, this)));
+            this->reactionTimers_.emplace_back(timer, direction);
+        }
+        else
+        {
+            this->movement_ = direction;
+        }
+    }
+
+    /**
+    @brief
+        Is called, when a delayed move takes effect.
+    */
+    void PongAI::delayedMove()
+    {
+        // Get the new movement direction from the timer list
+        this->movement_ = this->reactionTimers_.front().second;
+
+        // Destroy the timer and remove it from the list
+        delete this->reactionTimers_.front().first;
+        this->reactionTimers_.pop_front();
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongAI.h	(revision 12210)
@@ -0,0 +1,98 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongAI.h
+    @brief Declaration of the PongAI class.
+    @ingroup Pong
+*/
+
+#ifndef _PongAI_H__
+#define _PongAI_H__
+
+#include "pong/PongPrereqs.h"
+
+#include <list>
+
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+
+#include "controllers/Controller.h"
+#include "PongBall.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The PongAI is an artificial intelligence for the @ref orxonox::Pong "Pong" gametype.
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup Pong
+    */
+    class _PongExport PongAI : public Controller, public Tickable
+    {
+        public:
+            PongAI(Context* context); //!< Constructor. Registers and initializes the object.
+            virtual ~PongAI();
+
+            void setConfigValues();
+
+            virtual void tick(float dt) override; //!< Implements the behavior of the PongAI (i.e. its intelligence).
+
+            /**
+            @brief Set the ball for the AI.
+            @param ball A pointer to the ball.
+            */
+            void setPongBall(PongBall* ball)
+                { this->ball_ = ball; }
+
+        protected:
+            void calculateRandomOffset(); //!< Calculates the random offset, that accounts for random errors the AI makes in order to be beatable.
+            void calculateBallEndPosition(); //!< Calculate the end position the ball will be in.
+            void move(char direction, bool bUseDelay); //!< Determine the movement the AI will undertake.
+            void delayedMove(); //!< Is called, when a delayed move takes effect.
+
+            WeakPtr<PongBall> ball_; //!< A weak pointer to the ball.
+            Vector2 ballDirection_; //!< Vector to store the (x,z) direction in which the ball is flying.
+            float ballEndPosition_; //!< The calculated end position of the ball.
+            float randomOffset_; //!< A random offset to introduce random errors (weighted by the strength of the AI) into the AI's behavior.
+            bool bChangedRandomOffset_; //!< Helper boolean, to change the random offset more often.
+            float relHysteresisOffset_; //!< A hysteresis offset.
+            float strength_; //!< The strength of the AI. Ranging from 0 to 1.
+
+            std::list<std::pair<Timer*, char>> reactionTimers_; //!< A list of reaction timers and the directions that take effect when their timer expires.
+            char movement_; //!< The planned movement.
+            char oldMove_; //!< The previous movement.
+            bool bOscillationAvoidanceActive_; //!< Boolean, to avoid oscillations.
+    };
+}
+
+#endif /* _PongAI_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.cc	(revision 12210)
@@ -0,0 +1,155 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongBat.cc
+    @brief Implementation of the PongBat class.
+*/
+
+#include "PongBat.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    RegisterClass(PongBat);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    PongBat::PongBat(Context* context) : ControllableEntity(context)
+    {
+        RegisterObject(PongBat);
+
+        this->movement_ = 0;
+        this->bMoveLocal_ = false;
+        this->speed_ = 60;
+        this->length_ = 0.25;
+        this->fieldHeight_ = 100;
+        this->bSteadiedPosition_ = false;
+
+        this->registerVariables();
+    }
+
+    /**
+    @brief
+        Registers variables to be synchronized over the network.
+    */
+    void PongBat::registerVariables()
+    {
+        registerVariable(this->speed_);
+        registerVariable(this->fieldHeight_);
+        registerVariable(this->length_);
+    }
+
+    /**
+    @brief
+        Is called each tick.
+        Moves the bat.
+    @param dt
+        The time since last tick.
+    */
+    void PongBat::tick(float dt)
+    {
+        // If the bat is controlled (but not over the network).
+        if (this->hasLocalController())
+        {
+            if (this->movement_ != 0)
+            {
+                // The absolute value of the movement is restricted to be lesser or equal than the speed of the bat.
+                this->movement_ = clamp(this->movement_, -1.0f, 1.0f) * this->speed_;
+
+                // If moveRightLeft() is used the movement is dependento on wehther it is the right or the left bat, so, it is i.e. dependent on the orientation of the bat.
+                if (this->bMoveLocal_)
+                    this->setVelocity(this->getOrientation() * Vector3(this->movement_, 0, 0));
+                else
+                    this->setVelocity(0, 0, this->movement_);
+
+                this->movement_ = 0;
+                this->bSteadiedPosition_ = false;
+            }
+            // If there is no movement but the position has not been steadied, the velocity is set to zero and the position is reaffirmed.
+            else if (!this->bSteadiedPosition_)
+            {
+                // To ensure network synchronicity
+                this->setVelocity(0, 0, 0);
+                this->setPosition(this->getPosition());
+                this->bSteadiedPosition_ = true;
+            }
+        }
+
+        SUPER(PongBat, tick, dt);
+
+        // Restrict the position of the bats, for them to always be between the upper and lower delimiters. i.e. the bats stall if they reach the upper or lower boundary.
+        Vector3 position = this->getPosition();
+        if (position.z > this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2)
+            position.z = this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2;
+        if (position.z < -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2)
+            position.z = -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2;
+        if (position != this->getPosition())
+        {
+            this->setPosition(position);
+            this->setVelocity( Vector3::ZERO );
+        }
+    }
+
+    /**
+    @brief
+        Overloaded the function to steer the bat up and down.
+    @param value
+        A vector whose first component is the inverse direction in which we want to steer the bat.
+    */
+    void PongBat::moveFrontBack(const Vector2& value)
+    {
+        this->bMoveLocal_ = false;
+        this->movement_ = -value.x;
+    }
+
+    /**
+    @brief
+        Overloaded the function to steer the bat up and down.
+    @param value
+        A vector whose first component is the direction in which we wnat to steer the bat.
+    */
+    void PongBat::moveRightLeft(const Vector2& value)
+    {
+        this->bMoveLocal_ = true;
+        this->movement_ = value.x;
+    }
+
+    /**
+    @brief
+        Is called when the player changed.
+    */
+    void PongBat::changedPlayer()
+    {
+        this->setVelocity(0, 0, 0);
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBat.h	(revision 12210)
@@ -0,0 +1,120 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongBat.h
+    @brief Declaration of the PongBat class.
+    @ingroup Pong
+*/
+
+#ifndef _PongBat_H__
+#define _PongBat_H__
+
+#include "pong/PongPrereqs.h"
+
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The PongBat class manages the bats for @ref orxonox::Pong "Pong", which are the elements controlled by the players.
+
+        It is responsible for the movement (controlled by the players) of the bat.
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup Pong
+    */
+    class _PongExport PongBat : public ControllableEntity
+    {
+        public:
+            PongBat(Context* context); //!< Constructor. Registers and initializes the object.
+            virtual ~PongBat() {}
+
+            virtual void tick(float dt) override;
+
+            virtual void moveFrontBack(const Vector2& value) override; //!< Overloaded the function to steer the bat up and down.
+            virtual void moveRightLeft(const Vector2& value) override; //!< Overloaded the function to steer the bat up and down.
+
+            virtual void changedPlayer() override; //!< Is called when the player changed.
+
+            /**
+            @brief Set the speed of the bat.
+            @param speed The speed to be set.
+            */
+            void setSpeed(float speed)
+                { this->speed_ = speed; }
+            /**
+            @brief Get the speed of the bat.
+            @return Returns the speed of the bat.
+            */
+            float getSpeed() const
+                { return this->speed_; }
+
+            /**
+            @brief Set the height of the playing field.
+            @param height The height of the playing field.
+            */
+            void setFieldHeight(float height)
+                { this->fieldHeight_ = height; }
+            /**
+            @brief Get the height of the playing field.
+            @return Returns the height of the playing field.
+            */
+            float getFieldHeight() const
+                { return this->fieldHeight_; }
+
+            /**
+            @brief Set the length of the bat.
+            @param length The length of the bat (in z-direction) as percentage of the height of the playing field.
+            */
+            void setLength(float length)
+                { this->length_ = length; }
+            /**
+            @brief Get the length of the bat.
+            @return Returns the length of the bat (in z-direction) as percentage of the height of the playing field.
+            */
+            float getLength() const
+                { return this->length_; }
+
+        private:
+            void registerVariables(); //!< Registers variables to be synchronized over the network.
+
+            float movement_; //!< The amount (and direction), in z-direction, of movement of the bat.
+            bool bMoveLocal_; //!< Helper to know whether the movement is caused by moveFrontBack() or moveRightLeft().
+            float speed_; //!< The movement speed of the bat.
+            float length_; //!< The length of the bat (in z-direction) as percentage of the height of the playing field.
+            float fieldHeight_; //!< The height of the playing field.
+            bool bSteadiedPosition_; //!< Helper boolean, to keep track of when to steady the position, to ensure network synchronicity.
+    };
+}
+
+#endif /* _PongBat_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.cc	(revision 12210)
@@ -0,0 +1,54 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongBot.cc
+    @brief Implementation of the PongBot class.
+*/
+
+#include "PongBot.h"
+
+#include "core/CoreIncludes.h"
+#include "PongAI.h"
+
+namespace orxonox
+{
+    RegisterClass(PongBot);
+
+    /**
+    @brief
+        Constructor. Registers the object and creates a PongAI controller.
+    */
+    PongBot::PongBot(Context* context) : Bot(context)
+    {
+        RegisterObject(PongBot);
+
+        this->defaultController_ = Class(PongAI);
+        this->createController();
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongBot.h	(revision 12210)
@@ -0,0 +1,63 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongBot.h
+    @brief Declaration of the PongBot class.
+    @ingroup Pong
+*/
+
+#ifndef _PongBot_H__
+#define _PongBot_H__
+
+#include "pong/PongPrereqs.h"
+#include "infos/Bot.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        A bot especially for @ref orxonox::Pong "Pong".
+
+        Uses the @ref orxonox::PongAI "PongAI".
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup Pong
+    */
+    class _PongExport PongBot : public Bot
+    {
+        public:
+            PongBot(Context* context);
+            virtual ~PongBot() {}
+    };
+}
+
+#endif /* _PongBot_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.cc	(revision 12210)
@@ -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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongCenterpoint.cc
+    @brief Implementation of the PongCenterpoint class.
+*/
+
+#include "PongCenterpoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "Pong.h"
+
+namespace orxonox
+{
+    RegisterClass(PongCenterpoint);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object and checks whether the gametype is actually Pong.
+    */
+    PongCenterpoint::PongCenterpoint(Context* context) : StaticEntity(context)
+    {
+        RegisterObject(PongCenterpoint);
+
+        this->width_ = 200;
+        this->height_ = 120;
+        this->ballspeed_ = 100;
+        this->ballaccfactor_ = 1.0;
+        this->batspeed_ = 60;
+        this->batlength_ = 0.25;
+
+        this->checkGametype();
+    }
+
+    /**
+    @brief
+        Method to create a PongCenterpoint through XML.
+    */
+    void PongCenterpoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PongCenterpoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PongCenterpoint, "dimension", setFieldDimension, getFieldDimension, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "balltemplate", setBalltemplate, getBalltemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "battemplate", setBattemplate, getBattemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballspeed", setBallSpeed, getBallSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballaccfactor", setBallAccelerationFactor, getBallAccelerationFactor, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batspeed", setBatSpeed, getBatSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batlength", setBatLength, getBatLength, xmlelement, mode);
+    }
+
+    /**
+    @brief
+        Checks whether the gametype is Pong and if it is, sets its centerpoint.
+    */
+    void PongCenterpoint::checkGametype()
+    {
+        if (this->getGametype() != nullptr && this->getGametype()->isA(Class(Pong)))
+        {
+            Pong* pongGametype = orxonox_cast<Pong*>(this->getGametype());
+            pongGametype->setCenterpoint(this);
+        }
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongCenterpoint.h	(revision 12210)
@@ -0,0 +1,235 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongCenterpoint.h
+    @brief Declaration of the PongCenterpoint class.
+    @ingroup Pong
+*/
+
+#ifndef _PongCenterpoint_H__
+#define _PongCenterpoint_H__
+
+#include "pong/PongPrereqs.h"
+
+#include <string>
+
+#include <util/Math.h>
+
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        The PongCenterpoint implements the playing field @ref orxonox::Pong "Pong" takes place in and allows for many parameters of the minigame to be set.
+        The playing field resides in the x,z-plane, with the x-axis being the horizontal axis and the z-axis being the vertical axis.
+        
+        Various parameters can be set:
+        - The <b>dimension</b> is a vector, that defines the width and height of the playing field. The default is <em>(200, 120)</em>.
+        - The <b>balltemplate</b> is a template that is applied to the @ref orxonox::PongBall "PongBall", it can be used to attach different things to it, e.g. its @ref orxonox::Model "Model". See below for a usage example.
+        - The <b>battemplate</b> is a template that is applied to the @ref orxonox::PongBall "PongBat", it can be used to attach different things to it, e.g. its @ref orxonox::Model "Model". See below for a usage example.
+        - The <b>ballspeed</b> is the speed with which the @ref orxonox::PongBall "PongBall" moves. The default is <em>100</em>.
+        - The <b>ballaccfactor</b> is the acceleration factor for the @ref orxonox::PongBall "PongBall". The default is <em>1.0</em>.
+        - The <b>batspeed</b> is the speed with which the @ref orxonox::PongBat "PongBats" move. The default is <em>60</em>.
+        - The <b>batlength</b> is the length of the @ref orxonox::PongBat "PongBats" as the percentage of the height of the playing field. The default is <em>0.25</em>.
+        
+        An example in XML of the PongCenterpoint would be:
+        
+        First the needed templates:
+        The template for the @ref orxonox::PongBall "PongBall".
+        @code
+        <Template name="pongball">
+          <PongBall>
+            <attached>
+              <Model mesh="sphere.mesh" scale="2" />
+              <ParticleSpawner name="hiteffect" position="0,0,0" source="Orxonox/sparks2" lifetime="0.01" autostart="0" mainstate="spawn" />
+            </attached>
+            <eventlisteners>
+              <EventTarget target="hiteffect" />
+            </eventlisteners>
+          </PongBall>
+        </Template>
+        @endcode
+        As can be seen, a sphere is attached as the @ref orxonox::Model "Model" for the @ref orxonox::PongBall "PongBall", and also an @ref orxonox::EventListener "EventListener" that triggers a @ref orxonox::ParticleSpawner "ParticleSpawner", whenever the ball hits the boundaries is attached.
+        
+        Additionally the template for the @ref orxonox::PongBat "PongBat".
+        @code
+        <Template name="pongbatcameras" defaults="0">
+          <PongBat>
+            <camerapositions>
+              <CameraPosition position="0,200,0" pitch="-90" absolute="true" />
+            </camerapositions>
+          </PongBat>
+        </Template>
+
+        <Template name="pongbat">
+          <PongBat camerapositiontemplate=pongbatcameras>
+            <attached>
+              <Model position="0,0,3" mesh="cube.mesh" scale3D="14,2,2" />
+            </attached>
+          </PongBat>
+        </Template>
+        @endcode
+        As can be seen, there are actually two templates. The first template is needed to set the camera for the @ref orxonox::PongBat "PongBat". The second template ist the actual template for the @ref orxonox::PongBat "PongBat", the template for the camera position is added and a @ref orxonox::Model "Model" for the @ref orxonox::PongBat "PongBat" is attached.
+        
+        Finally the PongCenterpoint is created.
+        @code
+        <PongCenterpoint name="pongcenter" dimension="200,120" balltemplate="pongball" battemplate="pongbat" ballspeed="200" ballaccfactor="1.0" batspeed="130" batlength="0.25">
+          <attached>
+            <Model position="0,0,60" mesh="cube.mesh" scale3D="105,1,1" />
+            <Model position="0,0,-60" mesh="cube.mesh" scale3D="105,1,1" />
+          </attached>
+        </PongCenterpoint>
+        @endcode
+        All parameters are specified. And also two @ref orxonox::Model "Models" (for the upper and lower boundary) are attached.
+        
+        For a more elaborate example, have a look at the <code>pong.oxw</code> level file.
+    
+    @author
+        Fabian 'x3n' Landau
+        
+    @ingroup Pong
+    */
+    class _PongExport PongCenterpoint : public StaticEntity
+    {
+        public:
+            PongCenterpoint(Context* context); //!< Constructor. Registers and initializes the object and checks whether the gametype is actually Pong.
+            virtual ~PongCenterpoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode) override; //!< Method to create a PongCenterpoint through XML.
+
+            /**
+            @brief Set the template for the ball. (e.g. to attach the model of the ball, but also to attach an EventListener to it to detect, when it hits the boundaries, and e.g. display some ParticleEffets, when it does.)
+            @param balltemplate The name of the template to be set.
+            */
+            void setBalltemplate(const std::string& balltemplate)
+                { this->balltemplate_ = balltemplate; }
+            /**
+            @brief Get the template of the ball.
+            @return Returns the name of the template of the ball. 
+            */
+            const std::string& getBalltemplate() const
+                { return this->balltemplate_; }
+
+            /**
+            @brief Set the template for the bats. (e.g. to attach the model of the bat, but also to attach CameraPositions to it, to be able to view the game from the bats perspective)
+            @param battemplate The name of the template to be set.
+            */
+            void setBattemplate(const std::string& battemplate)
+                { this->battemplate_ = battemplate; }
+            /**
+            @brief Get the template of the bats.
+            @return Returns the name of the template of the bats.
+            */
+            const std::string& getBattemplate() const
+                { return this->battemplate_; }
+
+            /**
+            @brief Set the dimensions of the playing field.
+            @param dimension A vector with the width of the playing field as first component and the height as second.
+            */
+            void setFieldDimension(const Vector2& dimension)
+                { this->width_ = dimension.x; this->height_ = dimension.y; }
+            /**
+            @brief Get the dimensions of the playing field.
+            @return Returns a vector with the width of the playing field as first component and the height as second.
+            */
+            Vector2 getFieldDimension() const
+                { return Vector2(this->width_, this->height_); }
+
+            /**
+            @brief Set the speed of the ball.
+            @param ballspeed The speed of the ball.
+            */
+            void setBallSpeed(float ballspeed)
+                { this->ballspeed_ = ballspeed; }
+            /**
+            @brief Get the speed of the ball.
+            @return Returns the speed of the ball.
+            */
+            float getBallSpeed() const
+                { return this->ballspeed_; }
+
+            /**
+            @brief Set the ball's acceleration factor.
+            @param ballaccfactor The ball's acceleration factor.
+            */
+            void setBallAccelerationFactor(float ballaccfactor)
+                { this->ballaccfactor_ = ballaccfactor; }
+            /**
+            @brief Get the ball's acceleration factor
+            @return Returns the ball's acceleration factor.
+            */
+            float getBallAccelerationFactor() const
+                { return this->ballaccfactor_; }
+
+            /**
+            @brief Set the speed of the bats.
+            @param batspeed The speed of the bats.
+            */
+            void setBatSpeed(float batspeed)
+                { this->batspeed_ = batspeed; }
+            /**
+            @brief Get the speed of the bats.
+            @return Returns the speed of the bats.
+            */
+            float getBatSpeed() const
+                { return this->batspeed_; }
+
+            /**
+            @brief Set the length of the bats.
+            @param batlength The length of the bats (in z-direction) as a percentage of the height of the playing field.
+            */
+            void setBatLength(float batlength)
+                { this->batlength_ = batlength; }
+            /**
+            @brief Get the length of the bats.
+            @return Returns the length of the bats (in z-direction) as a percentage of the height of the playing field.
+            */
+            float getBatLength() const
+                { return this->batlength_; }
+
+        private:
+            void checkGametype(); //!< Checks whether the gametype is Pong and if it is, sets its centerpoint.
+
+            std::string balltemplate_; //!< The template for the ball.
+            std::string battemplate_; //!< The template for the bats.
+
+            float ballspeed_; //!< The speed of then ball.
+            float ballaccfactor_; //!< The acceleration factor of the ball.
+            float batspeed_; //!< The speed of the bat.
+            float batlength_; //!< The length of the bat (in z-direction) as a percentage of the height of the playing field.
+
+            float width_; //!< The height of the playing field.
+            float height_; //!< The width of the playing field.
+    };
+}
+
+#endif /* _PongCenterpoint_H__ */
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.cc
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.cc	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.cc	(revision 12210)
@@ -0,0 +1,176 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongScore.cc
+    @brief Implementation of the PongScore class.
+*/
+
+#include "PongScore.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/Convert.h"
+
+#include "infos/PlayerInfo.h"
+
+#include "Pong.h"
+#include "sound/WorldSound.h" /////////////////////////////
+
+namespace orxonox
+{
+    RegisterClass(PongScore);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    PongScore::PongScore(Context* context) : OverlayText(context)
+    {
+        RegisterObject(PongScore);
+
+        this->owner_ = nullptr;
+
+        this->bShowName_ = false;
+        this->bShowScore_ = false;
+        this->bShowLeftPlayer_ = false;
+        this->bShowRightPlayer_ = false;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    PongScore::~PongScore()
+    {
+    }
+
+    /**
+    @brief
+        Method to create a PongScore through XML.
+    */
+    void PongScore::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PongScore, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PongScore, "showname",        setShowName,        getShowName,        xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showscore",       setShowScore,       getShowScore,       xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showleftplayer",  setShowLeftPlayer,  getShowLeftPlayer,  xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showrightplayer", setShowRightPlayer, getShowRightPlayer, xmlelement, mode).defaultValues(false);
+    }
+
+    /**
+    @brief
+        Is called each tick.
+        Creates and sets the caption to be displayed by the PongScore.
+    @param dt
+        The time that has elapsed since the last tick.
+    */
+    void PongScore::tick(float dt)
+    {
+        SUPER(PongScore, tick, dt);
+
+        // If the owner is set. The owner being a Pong game.
+        if (this->owner_ != nullptr)
+        {
+            if (!this->owner_->hasEnded())
+            {
+                // Get the two players.
+                player1_ = this->owner_->getLeftPlayer();
+                player2_ = this->owner_->getRightPlayer();
+            }
+
+            std::string name1;
+            std::string name2;
+
+            std::string score1("0");
+            std::string score2("0");
+
+            // Save the name and score of each player as a string.
+            if (player1_ != nullptr)
+            {
+                name1 = player1_->getName();
+                score1 = multi_cast<std::string>(this->owner_->getScore(player1_));
+            }
+            if (player2_ != nullptr)
+            {
+                name2 = player2_->getName();
+                score2 = multi_cast<std::string>(this->owner_->getScore(player2_));
+            }
+
+            // Assemble the strings, depending on what should all be displayed.
+            std::string output1;
+            if (this->bShowLeftPlayer_)
+            {
+                if (this->bShowName_ && this->bShowScore_ && player1_ != nullptr)
+                    output1 = name1 + " - " + score1;
+                else if (this->bShowScore_)
+                    output1 = score1;
+                else if (this->bShowName_)
+                    output1 = name1;
+            }
+
+            std::string output2;
+            if (this->bShowRightPlayer_)
+            {
+                if (this->bShowName_ && this->bShowScore_ && player2_ != nullptr)
+                    output2 = score2 + " - " + name2;
+                else if (this->bShowScore_)
+                    output2 = score2;
+                else if (this->bShowName_)
+                    output2 = name2;
+            }
+
+            std::string output("PONG");
+            if (this->bShowName_ || this->bShowScore_)
+            {
+                if (this->bShowLeftPlayer_ && this->bShowRightPlayer_)
+                    output = output1 + ':' + output2;
+                else if (this->bShowLeftPlayer_ || this->bShowRightPlayer_)
+                    output = output1 + output2;
+            }
+
+            this->setCaption(output);
+        }
+    }
+
+    /**
+    @brief
+        Is called when the owner changes.
+        Sets the owner to nullptr, if it is not a pointer to a Pong game.
+    */
+    void PongScore::changedOwner()
+    {
+        SUPER(PongScore, changedOwner);
+
+        if (this->getOwner() != nullptr && this->getOwner()->getGametype())
+            this->owner_ = orxonox_cast<Pong*>(this->getOwner()->getGametype());
+        else
+            this->owner_ = nullptr;
+    }
+}
Index: code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.h
===================================================================
--- code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.h	(revision 12210)
+++ code/branches/OrxoBlox_FS19/src/modules/OrxoBlox/PongScore.h	(revision 12210)
@@ -0,0 +1,130 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+/**
+    @file PongScore.h
+    @brief Declaration of the PongScore class.
+    @ingroup Pong
+*/
+
+#ifndef _PongScore_H__
+#define _PongScore_H__
+
+#include "pong/PongPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The PongScore class displays the score for a game of @ref orxonox::Pong "Pong".
+
+    @author
+        Fabian 'x3n' Landau
+
+    @ingroup Pong
+    */
+    class _PongExport PongScore : public OverlayText, public Tickable
+    {
+        public:
+            PongScore(Context* context);
+            virtual ~PongScore();
+
+            virtual void tick(float dt) override; //!< Creates and sets the caption to be displayed by the PongScore.
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode) override;
+            virtual void changedOwner() override; //!< Is called when the owner changes.
+
+            /**
+            @brief Set whether the PongScore displays the players' names.
+            @param value If true the players' names are displayed.
+            */
+            inline void setShowName(bool value)
+                { this->bShowName_ = value; }
+            /**
+            @brief Get whether the PongScore displays the players' names.
+            @return Returns true if the players' names are displayed, false otherwise.
+            */
+            inline bool getShowName() const
+                { return this->bShowName_; }
+
+            /**
+            @brief Set whether the PongScore displays the players' scores.
+            @param value If true the players' scores are displayed.
+            */
+            inline void setShowScore(bool value)
+                { this->bShowScore_ = value; }
+            /**
+            @brief Get whether the PongScore displays the players' scores.
+            @return Returns true if the players' scores are displayed, false otherwise.
+            */
+            inline bool getShowScore() const
+                { return this->bShowScore_; }
+
+            /**
+            @brief Set whether the PongScore displays the left player.
+            @param value If true the left player is displayed.
+            */
+            inline void setShowLeftPlayer(bool value)
+                { this->bShowLeftPlayer_ = value; }
+            /**
+            @brief Get whether the PongScore displays the left player.
+            @return Returns true if the left player is displayed, false otherwise.
+            */
+            inline bool getShowLeftPlayer() const
+                { return this->bShowLeftPlayer_; }
+
+            /**
+            @brief Set whether the PongScore displays the right player.
+            @param value If true the right player is displayed.
+            */
+            inline void setShowRightPlayer(bool value)
+                { this->bShowRightPlayer_ = value; }
+            /**
+            @brief Get whether the PongScore displays the right player.
+            @return Returns true if the right player is displayed, false otherwise.
+            */
+            inline bool getShowRightPlayer() const
+                { return this->bShowRightPlayer_; }
+
+        private:
+            Pong* owner_; //!< The Pong game that owns this PongScore.
+            bool bShowName_; //!< Whether the names of the players are shown.
+            bool bShowScore_; //!< Whether the score of the players is shown.
+            bool bShowLeftPlayer_; //!< Whether the left player is shown.
+            bool bShowRightPlayer_; //!< Whether the right player is shown.
+            WeakPtr<PlayerInfo> player1_; //!< Store information about left player permanently.
+            WeakPtr<PlayerInfo> player2_; //!< Same for the right player. To end the game properly.
+            WorldSound* scoreSound_;
+
+    };
+}
+#endif /* _PongScore_H__ */
