diff --git a/App/GameLayer.cpp b/App/GameLayer.cpp
index bf95ba27c8c0c68da6f8362800189ae5c9af3311..5d548bdcd72176cf254a0b80931958cd8ab7950f 100644
--- a/App/GameLayer.cpp
+++ b/App/GameLayer.cpp
@@ -25,9 +25,8 @@ const QPong::Particle::Properties initialParticleSettings = {
     .size = 512,
     .position = {0.0, 0.0, 0.0},
     .momentum = {0.0, 0.0, 0.0},
-    .sharpness = 64.0,
-    .startValue = 0.01,
-    .hbar = 0.000125,
+    .dx = 6.475,
+    .hbar = 0.000175,
     .threads = 8
 };
 
@@ -151,6 +150,7 @@ void QPong::GameLayer::onAttach()
     m_showPotentialsLocation = glGetUniformLocation(m_shader->getRendererID(), "u_showPotential");
     m_isMomentumEnabled = glGetUniformLocation(m_shader->getRendererID(), "u_isMomentumEnabled");
     reset();
+    m_propagate = false;
 }
 
 void QPong::GameLayer::onDetach()
@@ -180,11 +180,13 @@ void QPong::GameLayer::reset()
         m_properties.momentum.x = (1.0f - (2.0f * positive)) * (1.0 + static_cast<float>(xRand) / 120.0f) / 20.0;
         positive = rand() % 2;
         m_properties.momentum.y = (1.0f - (2.0f * positive)) * (1.0 + static_cast<float>(yRand) / 120.0f) / 20.0;
+        m_properties.position.y = m_properties.momentum.y * 5.0;
     }
     m_options.game = m_gaming;
     m_options.absorbtionEnabled = m_gaming;
     m_options.momentumEnabled = !m_gaming;
 
+
     m_particle.reset(new Particle(
                 m_properties,
                 m_options,
@@ -195,10 +197,11 @@ void QPong::GameLayer::reset()
                 m_staticBorderPotential,
                 m_dynamicPotential));
 
-    m_restart = false;
-    m_gameCounts = true;
     constexpr double veryLittleInitialStep(0.00025);
     m_particle->update(veryLittleInitialStep);
+    m_gameCounts = true;
+    m_restart = false;
+    m_propagate = true;
 }
 
 void QPong::GameLayer::onUpdate(GuiCore::Timestep ts)
@@ -278,23 +281,23 @@ void QPong::GameLayer::onGuiRender()
 {
     // GUI settings for the particle
     ImGui::Begin("Particle Settings");
-    ImGui::DragFloat2("Start Position", glm::value_ptr(m_properties.position), 0.025f, -0.8f, 0.8f);
+    ImGui::DragFloat2("Start Position", glm::value_ptr(m_properties.position), 0.01f, -0.6f, 0.6f);
 
     // Select initial momentum for particle at restart
     ImGui::DragFloat2("Momentum [x,y]", glm::value_ptr(m_properties.momentum), 0.001f, -0.1f, 0.1f);
     ImGui::Checkbox("Random Momentum", &m_randomMomentum);
 
-    float sharpness = m_properties.sharpness;
-    if (ImGui::DragFloat("Sharpness", &sharpness, 5.0f, 5.0f, 1000.0f))
+    float dx = static_cast<float>(m_properties.dx);
+    if (ImGui::DragFloat("dx", &dx, 0.1f, 2.0f, 50.0f))
     {
-        m_properties.sharpness = sharpness;
+        m_properties.dx = static_cast<double>(dx);
     }
 
     // Select hbar, changes apply on the fly.
-    float hbar = m_properties.hbar;
+    float hbar = static_cast<float>(m_properties.hbar);
     if (ImGui::DragFloat("hbar", &hbar, 0.0000001f, 0.0000001f, 1.0f, "%.7f"))
     {
-        m_properties.hbar = hbar;
+        m_properties.hbar = static_cast<double>(hbar);
     }
 
     // This value increases or decreases the time step made every iteration.
@@ -326,6 +329,7 @@ void QPong::GameLayer::onGuiRender()
     // Restart game
     if (ImGui::Button("Restart"))
     {
+        m_propagate = false;
         m_restart = true;
     }
     ImGui::Text("Player 1: %d", m_playerOne.getTotalScore());
@@ -347,6 +351,9 @@ void QPong::GameLayer::onGuiRender()
         m_options.absorbtionEnabled = false;
         m_options.momentumEnabled = true;
         m_restart = true;
+        m_properties.position.y = 0.4;
+        m_properties.momentum.y = 0.0;
+        m_properties.hbar *= 1.5;
     }
     ImGui::End();
 }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4dbc4b4e2d365b7f4dfe34e8b7d0686491fbb7f3..fb68d1a993e7683a33a4884fe7453f3823c40ec5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ project(QPong VERSION 0.0.1 LANGUAGES C CXX)
 set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_BUILD_TYPE Release)
 
-list(APPEND basic_flags "-O3" "-Wextra" "-Wall" "-Wshadow" "-Wold-style-cast" "-pedantic" "-Wpedantic")
+list(APPEND basic_flags "-O3" "-Wall" "-Wextra" "-Wshadow" "-Wold-style-cast" "-Werror" "-Wuninitialized" "-pedantic" "-Wpedantic")
 
 option(LOG_DEBUG_INFO "Enable logging t console" OFF)
 if(LOG_DEBUG_INFO)
diff --git a/QPong/Bat.cpp b/QPong/Bat.cpp
index da160c7ac4a46f129b6291b694bb382a9c77d54a..a090bc577ab13d0c5fab063e0b690bd2d126e234 100644
--- a/QPong/Bat.cpp
+++ b/QPong/Bat.cpp
@@ -27,18 +27,21 @@ QPong::Bat::Bat(double x, double y, int keyUp, int keyDown)
 
 void QPong::Bat::onUpdate(GuiCore::Timestep ts)
 {
-    constexpr double speed = 20.0;
+    constexpr double speed = 3.5;
+    constexpr double speedMultiplier = 1.05;
     if (GuiCore::Input::isKeyPressed(m_keyDown))
     {
-        m_vy += s_speedStepSize * speed; 
+        m_vy += s_speedStepSize * speed;
+        m_vy *= speedMultiplier; 
     }
     else if (GuiCore::Input::isKeyPressed(m_keyUp))
     {
         m_vy -= s_speedStepSize * speed;
+        m_vy *= speedMultiplier; 
     }
     else
     {
-        m_vy = 0.0;
+        m_vy *= 0.85;
     }
 
     constexpr double maxSpeedFactor = 300.0;
@@ -81,7 +84,8 @@ double QPong::Bat::getPotential(double x, double y) const
     {
         dist = pow2(m_x - x) + m_width;
     }
-    return 1.0 / (pow2(dist) ) * scale;
+    auto pot = 1.0 / (pow2(dist)) * scale;
+    return(pot);
 }
 
 double QPong::Bat::getX() const
diff --git a/QPong/CMakeLists.txt b/QPong/CMakeLists.txt
index 42f71f946245e575797fc3655ccdaaa1d6bbcf6a..0b8cad96dcc23810823c392292a07a4cb5a3ff15 100644
--- a/QPong/CMakeLists.txt
+++ b/QPong/CMakeLists.txt
@@ -21,12 +21,4 @@ target_link_libraries(QPong
         GuiCore
         fftw3
         fftw3_omp
-    )
-
-# target_include_directories( QPong 
-# PUBLIC
-#     .
-#     ..
-#     ../libs
-#     ../libs/imgui/examples/libs/gl3w
-# )
\ No newline at end of file
+    )
\ No newline at end of file
diff --git a/QPong/Particle.cpp b/QPong/Particle.cpp
index ea20c6993ea4c8265480797b7adabed067ea180d..2c8d8a2eea918153da88eb0d6ea9c77d5a40dd84 100644
--- a/QPong/Particle.cpp
+++ b/QPong/Particle.cpp
@@ -61,17 +61,18 @@ Particle::Particle(Properties properties, GameOptions &options, Player &playerOn
     Log::get()->debug("Init Particle");
     m_xAt = new double[m_properties.elements()];
     m_yAt = new double[m_properties.elements()];
-    m_E_At = new double[m_properties.elements()];
+    m_P_At = new double[m_properties.elements()];
 
     for (int i{0}; i < m_properties.elements(); ++i)
     {
         m_xAt[i] = xAtIndex(i, m_properties.size);
         m_yAt[i] = yAtIndex(i, m_properties.size);
-        m_E_At[i] = (pow2(pxAtIndex(i, m_properties.size, m_properties.hbar)) + pow2(pyAtIndex(i, m_properties.size, m_properties.hbar))) / (2.0 * 1.0);
+        m_P_At[i] = pow2(pxAtIndex(i, m_properties.size, m_properties.hbar)) + pow2(pyAtIndex(i, m_properties.size, m_properties.hbar));
     }
 
     int memorySize = sizeof(fftw_complex) * m_properties.elements();
-    m_psi = static_cast<std::complex<double> *>(fftw_malloc(memorySize));
+    m_psi_positional = static_cast<std::complex<double> *>(fftw_malloc(memorySize));
+    m_psi_momentum = static_cast<std::complex<double> *>(fftw_malloc(memorySize));
     m_momentum = static_cast<std::complex<double> *>(fftw_malloc(memorySize));
     initialiseParticleMomentum();
 
@@ -94,12 +95,18 @@ Particle::Particle(Properties properties, GameOptions &options, Player &playerOn
     m_planForward = fftw_plan_dft_2d(
         m_properties.size,
         m_properties.size,
-        reinterpret_cast<fftw_complex*>(m_psi),
-        reinterpret_cast<fftw_complex*>(m_psi),
+        reinterpret_cast<fftw_complex*>(m_psi_positional),
+        reinterpret_cast<fftw_complex*>(m_psi_momentum),
         FFTW_FORWARD,
         FFTW_MEASURE);
     fftw_plan_with_nthreads(m_properties.threads);
-    m_planBackwards = fftw_plan_dft_2d(m_properties.size, m_properties.size, reinterpret_cast<fftw_complex*>(m_psi), reinterpret_cast<fftw_complex*>(m_psi), FFTW_BACKWARD, FFTW_MEASURE);
+    m_planBackwards = fftw_plan_dft_2d(
+        m_properties.size,
+        m_properties.size,
+        reinterpret_cast<fftw_complex*>(m_psi_momentum),
+        reinterpret_cast<fftw_complex*>(m_psi_positional),
+        FFTW_BACKWARD,
+        FFTW_MEASURE);
 
     int numberOfThreads = m_properties.threads;
     for (int i = 0; i < numberOfThreads; i++)
@@ -131,16 +138,17 @@ Particle::~Particle()
     }
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
-    fftw_free(m_psi);
+    fftw_free(m_psi_positional);
+    fftw_free(m_psi_momentum);
     delete (m_xAt);
     delete (m_yAt);
-    delete (m_E_At);
+    delete (m_P_At);
     delete (m_momentum);
 }
 
 std::complex<double> *Particle::getPsi() const
 {
-    return m_psi;
+    return m_psi_positional;
 }
 
 std::complex<double> *Particle::getMomentum() const
@@ -155,40 +163,37 @@ int Particle::arrayElementCount() const
 
 void Particle::initialiseParticleMomentum()
 {
-    constexpr std::complex<double> ci{0.0, 1.0}; // complex number
+    constexpr std::complex<double> ci{0.0, 1.0};
     const double hbar = m_properties.hbar;
-    const double A0 = m_properties.startValue;
     const double px0 = m_properties.momentum.x;
     const double py0 = m_properties.momentum.y;
     const double x0 = m_properties.position.x;
     const double y0 = m_properties.position.y;
-    const double lambda = m_properties.sharpness;
+    const double dx = m_properties.dx;
 
     double sum{0.0};
-    double m_particleAbsoluteSumStart = 0.0;
     double y{0.0};
     double x{0.0};
     for (auto i{0}; i < arrayElementCount(); ++i)
     {
         x = m_xAt[i];
         y = m_yAt[i];
-        m_psi[i] = A0 * exp(ci / hbar * (x * px0 + y * py0) - lambda * (pow2(x - x0) + pow2(y - y0)));
-        sum += pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i]));
+        m_psi_positional[i] = exp(ci / hbar * (x * px0 + y * py0) - pow2(dx) * (pow2(x-x0) + pow2(y-y0)));
+        sum += pow2(std::real(m_psi_positional[i])) + pow2(std::imag(m_psi_positional[i]));
     }
     for (auto i{0}; i < arrayElementCount(); ++i)
     {
-        m_psi[i] *= 10.0 / sqrt(sum);
-        m_particleAbsoluteSumStart += pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i]));
+        m_psi_positional[i] *= 10.0 / sqrt(sum);
     }
     Log::get()->trace("Particle initialised");
 }
 
 double Particle::absorbParticle(int i, double c)
 {
-    double normPrevious = pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i]));
-    double absorb = pow2(std::cos(c * 10));
-    m_psi[i] *= absorb;
-    double delta = normPrevious - (pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i])));
+    double normPrevious = pow2(std::real(m_psi_positional[i])) + pow2(std::imag(m_psi_positional[i]));
+    double absorb = pow2(std::cos(c * 10.0));
+    m_psi_positional[i] *= absorb;
+    double delta = normPrevious - (pow2(std::real(m_psi_positional[i])) + pow2(std::imag(m_psi_positional[i])));
     return delta;
 }
 
@@ -198,39 +203,34 @@ void Particle::applyPotentials(int indexBegin, int indexEnd, double dt)
     const double hbar = m_properties.hbar;
     double x{0.0};
     double y{0.0};
-    const double potential = 1.0;
     double particleAbsorbtAtPlayerOne = 0.0;
     double particleAbsorbtAtPlayerTwo = 0.0;
 
     for (int i{indexBegin}; i < indexEnd; ++i)
     {
-        double potSum = 1.0;
-        if (m_options.potentialsEnabled)
+        double potSum = 0.0;
+        x = m_xAt[i];
+        y = m_yAt[i];
+        if (m_options.absorbtionEnabled)
         {
-            potSum = 0.0;
-            x = m_xAt[i];
-            y = m_yAt[i];
-            if (m_options.absorbtionEnabled)
+            if (x < m_leftBat.getX())
+            {
+                double distanceToEdge = -m_leftBat.getX() + x;
+                double c = distanceToEdge * (M_PI / 2.0) / (1.0 + m_leftBat.getX());
+                particleAbsorbtAtPlayerOne += absorbParticle(i, c);
+            }
+            if (x > m_rightBat.getX())
             {
-                if (x < m_leftBat.getX())
-                {
-                    double distanceToEdge = -m_leftBat.getX() + x;
-                    double c = distanceToEdge * (M_PI / 2.0) / (1.0 + m_leftBat.getX());
-                    particleAbsorbtAtPlayerOne += absorbParticle(i, c);
-                }
-                if (x > m_rightBat.getX())
-                {
-                    double distanceToEdge = x - m_rightBat.getX();
-                    double c = distanceToEdge * (M_PI / 2.0) / (1.0 + m_rightBat.getX());
-                    particleAbsorbtAtPlayerTwo += absorbParticle(i, c);
-                }
+                double distanceToEdge = x - m_rightBat.getX();
+                double c = distanceToEdge * (M_PI / 2.0) / (1.0 + m_rightBat.getX());
+                particleAbsorbtAtPlayerTwo += absorbParticle(i, c);
             }
-            double potLeftBat = m_leftBat.getPotential(x, y);
-            double potRightBat = m_rightBat.getPotential(x, y);
-            potSum = potLeftBat + potRightBat + m_staticBorders[i];
         }
-        auto psi = m_psi[i] * exp(-ci * dt / hbar * potential * potSum);
-        m_psi[i] = psi;
+        double potLeftBat = m_leftBat.getPotential(x, y);
+        double potRightBat = m_rightBat.getPotential(x, y);
+        potSum = potLeftBat + potRightBat + m_staticBorders[i];
+        auto psi = m_psi_positional[i] * exp(-ci * dt / hbar * potSum);
+        m_psi_positional[i] = psi;
         if (m_options.potentialsEnabled)
         {
             m_dynamicPotential[i] = potSum;
@@ -247,7 +247,7 @@ void Particle::moveForward(int indexBegin, int indexEnd, double dt)
     const double N = 1.0 / static_cast<double>(arrayElementCount());
     for (int i{indexBegin}; i < indexEnd; ++i)
     {
-        m_psi[i] *= exp(-ci * dt / hbar * m_E_At[i]) * N;
+        m_psi_momentum[i] *= exp(((-ci * dt) / (2.0 * hbar)) * m_P_At[i]) * N;
     }
 }
 
@@ -279,7 +279,7 @@ void Particle::updateMomentumView(int indexBegin, int indexEnd)
         {
             x = x + halfArraySize;
         }
-        m_momentum[i] = m_psi[(y * m_properties.size) - x] * 100.0;
+        m_momentum[i] = m_psi_momentum[(y * m_properties.size) - x] * 100.0;
     }
 }
 
diff --git a/QPong/Particle.hpp b/QPong/Particle.hpp
index 41dfa3ca86f9ce127c17545632ba3c2095b1adea..23eb117dc4b329070264505954e7836cda84920b 100644
--- a/QPong/Particle.hpp
+++ b/QPong/Particle.hpp
@@ -34,8 +34,7 @@ namespace QPong
             int size;
             glm::vec3 position;
             glm::vec3 momentum;
-            double sharpness;
-            double startValue;
+            double dx;
             double hbar;
             int threads;
             int elements() const {return size * size;}
@@ -86,10 +85,11 @@ namespace QPong
         fftw_plan m_planBackwards;
         double *m_xAt;
         double *m_yAt;
-        double *m_E_At;
+        double *m_P_At;
         float *m_staticBorders;
         float *m_dynamicPotential;
-        std::complex<double> *m_psi;
+        std::complex<double> *m_psi_positional;
+        std::complex<double> *m_psi_momentum;
         std::complex<double> *m_momentum;
         double m_timeFFT;
     };
diff --git a/QPong/Utils.cpp b/QPong/Utils.cpp
index 4e0ae381cfb07507aecb67fe2ffe137198f25928..eac6ee2a853ff34e173cb3e5bb29a5a078c1913c 100644
--- a/QPong/Utils.cpp
+++ b/QPong/Utils.cpp
@@ -10,7 +10,7 @@ void calculatePointPositions(float *positions, int arraySize)
     constexpr float size{3.175f};
     constexpr float xOffset{0.0f};
     constexpr float yOffset{-0.175f};
-    
+
     constexpr float width{size};
     constexpr float xMin{-width / 2.0};
     constexpr float xMax{width / 2.0};
@@ -88,15 +88,12 @@ void calculateBorderPotential(float *potential, [[maybe_unused]] double *xAt, do
 void calculateMorseBox(float *potential, double *xAt, double *yAt, int arrayElements)
 {
     constexpr double grow = 0.1;
-    constexpr double scalePotential = 1.0;
     for (int i{0}; i < arrayElements; ++i)
     {
         auto x = xAt[i] * grow;
         auto y = yAt[i] * grow;
         auto d = sqrt(pow2(x) + pow2(y));
-        // V(x) = 1 / cosh^2(x) = 1 / (1/2 * (cosh(2x)+1))
         auto V = 1.0 / ( 0.5 * (cosh(2.0 * d) + 1.0));
-        V *= scalePotential;
         potential[i] = 1.0 - V;
     }
 }
@@ -118,29 +115,30 @@ void calculateGaussBox(float *potential, double *xAt, double *yAt, int arrayElem
 
 void calculateH2Box(float *potential, double *xAt, double *yAt, int arrayElements)
 {
-    constexpr double grow = 0.001;
+    constexpr double grow { 0.0018 };
+    constexpr double reducedSingularity { 0.0991 };
+    constexpr double scale { 0.10039 };
     for (int i{0}; i < arrayElements; ++i)
     {
         auto x = xAt[i] * grow;
         auto y = yAt[i] * grow;
-        auto d = sqrt(pow2(x) + pow2(y)) + 0.1;
-        auto V =  0.10035 / d;
+        auto d = sqrt(pow2(x) + pow2(y)) + reducedSingularity;
+        auto V =  scale / d;
         potential[i] = 1.0 - V;
     }
 }
 
-
-// void Kegel(float *potential, double *xAt, double *yAt, int arrayElements)
-// {
-//     constexpr double grow = 1.0;
-//     constexpr double scalePotential = 0.005;
-//     for (int i{0}; i < arrayElements; ++i)
-//     {
-//         auto x = xAt[i] * grow;
-//         auto y = yAt[i] * grow;
-//         auto d = sqrt(pow2(x) + pow2(y));
-//         auto V =   d;
-//         V *= scalePotential;
-//         potential[i] = V;
-//     }
-// }
\ No newline at end of file
+void Kegel(float *potential, double *xAt, double *yAt, int arrayElements)
+{
+    constexpr double grow = 1.0;
+    constexpr double scalePotential = 0.005;
+    for (int i{0}; i < arrayElements; ++i)
+    {
+        auto x = xAt[i] * grow;
+        auto y = yAt[i] * grow;
+        auto d = sqrt(pow2(x) + pow2(y));
+        auto V =   d;
+        V *= scalePotential;
+        potential[i] = V;
+    }
+}
diff --git a/QPong/Utils.hpp b/QPong/Utils.hpp
index 53a305ef3b4864b7841dc6d0876d51a47d4383b5..155d7102f30eaf8e35730546df073b6f384e677c 100644
--- a/QPong/Utils.hpp
+++ b/QPong/Utils.hpp
@@ -20,4 +20,6 @@ void calculateBorderPotential(float *potential, double *xAt, double *yAt, int ar
 void calculateMorseBox(float *potential, double *xAt, double *yAt, int arrayElemnts);
 void calculateGaussBox(float *potential, double *xAt, double *yAt, int arrayElemnts);
 void calculateH2Box(float *potential, double *xAt, double *yAt, int arrayElemnts);
-#endif
\ No newline at end of file
+void calculateKegelBox(float *potential, double *xAt, double *yAt, int arrayElemnts);
+
+#endif
diff --git a/assets/shaders/particle.vert.glsl b/assets/shaders/particle.vert.glsl
index 9cd55d644a685a005400088b67f21e38c9500765..6dc1b88b1c25b0c7d809fa916f6eaa34b6b5b92c 100644
--- a/assets/shaders/particle.vert.glsl
+++ b/assets/shaders/particle.vert.glsl
@@ -25,16 +25,16 @@ void main()
     gl_Position = u_viewProjection * vec4(pos, 1.0f);
     
     // Calculate "color" value of the momentum
-    float pot = potential * 100.0 * u_showPotential;
+    float pot = abs(potential * 100.0f * u_showPotential);
 
     // Generate color from data
     float real = v_particle_complex[0];
     float imag = v_particle_complex[1];
     float real2 = real * real;
     float imag2 = imag * imag;
-    
+     
     fragmentColor = vec3(
-                        sqrt(real2) * 5.0 + pot,                        // red
-                        (sqrt(real2) + sqrt(imag2)) * 5.0 + pot,    // green
-                        sqrt(imag2) * 5.0 + pot);                       // blue
+        pot + sqrt(real2) * 5.0f, 
+        pot + (sqrt(real2) + sqrt(imag2)) * 5.0f,
+        pot + sqrt(imag2) * 5.0f);   
 }