diff --git a/inc/Math.hpp b/inc/Math.hpp
index 4c123b7..0cf1aa8 100644
--- a/inc/Math.hpp
+++ b/inc/Math.hpp
@@ -2,3 +2,4 @@
 
 Color ColorLerp(Color c1, Color c2, float amount);
 Vector2 CalculateVector(float rotation, float offSet, float len);
+float GetRandomFloat();
\ No newline at end of file
diff --git a/inc/canvas/BackGround.hpp b/inc/canvas/BackGround.hpp
index 34c9649..e693abc 100644
--- a/inc/canvas/BackGround.hpp
+++ b/inc/canvas/BackGround.hpp
@@ -1,5 +1,13 @@
 #include <vector>
 #include "raylib.h"
+#include "values/RandBuffer.hpp"
+
+struct Moon
+{
+  float x;
+  float y;
+  float size;
+};
 
 class BackGround
 {
@@ -9,29 +17,34 @@ public:
   ~BackGround() = default;
   void init(int size);
   void newGen();
+  void draw();
 
 private:
-  void starts();
-  void moon();
-  void mounten(size_t mountenSegments, float scale, int min, int max, Color color);
+  void drawStarts();
+  void drawMoon();
+  void drawMounten(size_t mountenSegments, int min, int max, Color color);
+
+  RandBuffer starBuff;
+  RandBuffer mountenBuff;
+  Moon m_moon;
 
   int size = 0;
-  Texture2D texShapes = {1, 1, 1, 1, 7};
 
-  size_t numOfStarts = 150;
-
-  float minSizeOfMoon = 0.05f;
-  float maxSizeOfMoon = 0.075f;
-  float maxYPosOfMoon = 0.75f;
-  float bigRingRatio = 0.5f;
-  float smallRingRatio = 0.25f;
-  float bigRingBlend = 0.02f;
-  float smallRingBlend = 0.05f;
-
-  float colorRatio1 = 0.3f;
-  float colorRatio2 = 0.5f;
-  float mounten1 = 0.6875f;
-  float mounten2 = 0.8125f;
-  float mounten3 = 0.9125;
-  float mounten4 = 0.975f;
+  constexpr static size_t numOfStarts = 150;
+  constexpr static float moonXOffset = 0.1f;
+  constexpr static float minSizeOfMoon = 0.05f;
+  constexpr static float maxSizeOfMoon = 0.075f;
+  constexpr static float maxYPosOfMoon = 0.80f;
+  constexpr static float bigRingRatio = 0.5f;
+  constexpr static float smallRingRatio = 0.25f;
+  constexpr static float bigRingBlend = 0.02f;
+  constexpr static float smallRingBlend = 0.05f;
+  constexpr static float colorRatio1 = 0.3f;
+  constexpr static float colorRatio2 = 0.7f;
+  constexpr static float mounten1min = 0.78f;
+  constexpr static float mounten1max = 0.81f;
+  constexpr static float mounten2min = 0.83f;
+  constexpr static float mounten2max = 0.87;
+  constexpr static float mounten3min = 0.90f;
+  constexpr static float mounten3max = 0.95f;
 };
diff --git a/inc/values/Buffer.hpp b/inc/values/Buffer.hpp
new file mode 100644
index 0000000..b1765a0
--- /dev/null
+++ b/inc/values/Buffer.hpp
@@ -0,0 +1,40 @@
+#ifndef BUFFER_HPP
+#define BUFFER_HPP
+
+#include <cstdint>
+#include <string>
+
+class Buffer
+{
+public:
+	uint8_t *buffer = nullptr;
+	size_t taken = 0;
+	size_t size = 0;
+	std::string file_path;
+
+	Buffer(size_t size);
+	Buffer();
+	~Buffer();
+	bool resize(size_t new_size);
+	uint32_t add_end(uint8_t *data, size_t data_size);
+	int add_middle(uint8_t *data, size_t data_size, size_t index);
+
+	// Removes data from buffer without checking if it's in the buffer
+	void remove_fast(uint8_t *data, size_t data_size);
+
+	void remove(size_t index, size_t data_size);
+
+	size_t find(uint8_t *data, size_t data_size);
+
+	void remove(uint8_t *data, size_t data_size);
+
+	void clear() { taken = 0; }
+
+	bool save_to_file();
+	bool save_to_file(std::string file_path);
+
+	bool load_from_file();
+	bool load_from_file(std::string file_path);
+};
+
+#endif
\ No newline at end of file
diff --git a/inc/values/RandBuffer.hpp b/inc/values/RandBuffer.hpp
new file mode 100644
index 0000000..5cc61a1
--- /dev/null
+++ b/inc/values/RandBuffer.hpp
@@ -0,0 +1,15 @@
+#include "values/Buffer.hpp"
+
+class RandBuffer
+{
+public:
+  RandBuffer() = default;
+  ~RandBuffer() = default;
+
+  void reset();
+  float next();
+
+private:
+  Buffer m_buffer;
+  size_t m_pos = 0;
+};
diff --git a/src/Math.cpp b/src/Math.cpp
index 92b9c52..63725c8 100644
--- a/src/Math.cpp
+++ b/src/Math.cpp
@@ -19,4 +19,9 @@ Vector2 CalculateVector(float rotation, float offSet, float len)
   return {
       .x = len * std::sin(angle),
       .y = len * std::cos(angle)};
-}
\ No newline at end of file
+}
+
+float GetRandomFloat()
+{
+  return GetRandomValue(0, 100000) / 100000.0f;
+}
diff --git a/src/canvas/BackGround.cpp b/src/canvas/BackGround.cpp
index e183fa4..159eb54 100644
--- a/src/canvas/BackGround.cpp
+++ b/src/canvas/BackGround.cpp
@@ -5,7 +5,6 @@
 #include "raylib.h"
 #include "rlgl.h"
 #include "raymath.h"
-#include "external/stb_perlin.h"
 
 // Public
 void BackGround::init(int size)
@@ -15,30 +14,38 @@ void BackGround::init(int size)
 
 void BackGround::newGen()
 {
+  starBuff.reset();
+  mountenBuff.reset();
+  m_moon = {GetRandomFloat(), GetRandomFloat(), GetRandomFloat()};
+
   BackGroundColors::setColor();
-  ClearBackground(BackGroundColors::backGroundColor);
-  starts();
-  moon();
-  mounten(20, 0.3, (int)(mounten1 * size), (int)(mounten2 * size), BackGroundColors::backMountenColor);
-  mounten(21, 0.3, (int)(mounten2 * size), (int)(mounten3 * size), ColorLerp(BackGroundColors::backMountenColor, BackGroundColors::frontMountenColor, colorRatio1));
-  mounten(23, 0.3, (int)(mounten3 * size), (int)(mounten4 * size), ColorLerp(BackGroundColors::backMountenColor, BackGroundColors::frontMountenColor, colorRatio2));
+
+  draw();
 }
 
-void BackGround::starts()
+void BackGround::draw()
 {
-  rlSetTexture(texShapes.id);
+  ClearBackground(BackGroundColors::backGroundColor);
+  drawStarts();
+  drawMoon();
+  drawMounten(20, (int)(mounten1min * size), (int)(mounten1max * size), BackGroundColors::backMountenColor);
+  drawMounten(21, (int)(mounten2min * size), (int)(mounten2max * size), ColorLerp(BackGroundColors::backMountenColor, BackGroundColors::frontMountenColor, colorRatio1));
+  drawMounten(23, (int)(mounten3min * size), (int)(mounten3max * size), ColorLerp(BackGroundColors::backMountenColor, BackGroundColors::frontMountenColor, colorRatio2));
+}
+
+void BackGround::drawStarts()
+{
+  rlSetTexture(1);
   rlBegin(RL_TRIANGLES);
   rlNormal3f(0.0f, 0.0f, 1.0f);
-
   bool star = true;
 
-  for (size_t i = 1; i <= numOfStarts; i++)
+  for (size_t i = 0; i < numOfStarts; i++)
   {
-    int x = GetRandomValue(0, size);
-    int y = GetRandomValue(0, size);
-    int weight = GetRandomValue(1, 3);
-
-    float alph = ((float)GetRandomValue(10, 200)) / 255.0f;
+    int x = starBuff.next() * size;
+    int y = starBuff.next() * size;
+    int weight = starBuff.next() * 3 + 1;
+    float alph = Normalize(starBuff.next(), 0.04f, 0.8f);
     Color color = ColorLerp(BackGroundColors::backGroundColor, BackGroundColors::starColor, alph);
 
     rlColor4ub(color.r, color.g, color.b, color.a);
@@ -66,11 +73,12 @@ void BackGround::starts()
   rlSetTexture(0);
 }
 
-void BackGround::moon()
+void BackGround::drawMoon()
 {
-  int xpos = GetRandomValue(100, size - 100);
-  int ypos = GetRandomValue(100, (int)(maxYPosOfMoon * size));
-  int r = GetRandomValue((int)(minSizeOfMoon * size), (int)(maxSizeOfMoon * size));
+  int r = ((m_moon.size * (maxSizeOfMoon - minSizeOfMoon)) + minSizeOfMoon) * size;
+  int xpos = Lerp(size * moonXOffset, size - size * moonXOffset, m_moon.x);
+  int ypos = Lerp(size * moonXOffset, maxYPosOfMoon * size, m_moon.y);
+
   int ring1 = (float)r * bigRingRatio;
   int ring2 = (float)r * smallRingRatio;
 
@@ -79,21 +87,15 @@ void BackGround::moon()
   DrawCircle(xpos, ypos, r, BackGroundColors::moonColor);
 }
 
-void BackGround::mounten(size_t mountenSegments, float scale, int min, int max, Color color)
+void BackGround::drawMounten(size_t mountenSegments, int min, int max, Color color)
 {
-  // get random offset in the perlin noise
-  int offsetX = GetRandomValue(20, 1000);
-  int offsetY = GetRandomValue(20, 1000);
-
   int x = 0;
   int diff = size / (mountenSegments - 1);
 
-  float nx = (float)offsetX * scale;
-  float p = stb_perlin_fbm_noise3(nx, offsetY, 1.0f, 2.0f, 0.5f, 6);
-  p = (p + 1.0f) / 2.0f;
-  int y = Lerp(min, max, p);
+  float p = mountenBuff.next();
 
-  rlSetTexture(texShapes.id);
+  int y = Lerp(min, max, p);
+  rlSetTexture(1);
   rlBegin(RL_TRIANGLES);
   rlNormal3f(0.0f, 0.0f, 1.0f);
   rlColor4ub(color.r, color.g, color.b, color.a);
@@ -105,9 +107,7 @@ void BackGround::mounten(size_t mountenSegments, float scale, int min, int max,
     // bottomLeft
     rlVertex2f(x, size);
 
-    nx = (float)(i + offsetX) * scale;
-    p = stb_perlin_fbm_noise3(nx, offsetY, 1.0f, 2.0f, 0.5f, 6);
-    p = (p + 1.0f) / 2.0f;
+    p = mountenBuff.next();
     y = Lerp(min, max, p);
     x += diff;
     // topRight
diff --git a/src/values/Buffer.cpp b/src/values/Buffer.cpp
new file mode 100644
index 0000000..3104862
--- /dev/null
+++ b/src/values/Buffer.cpp
@@ -0,0 +1,152 @@
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include "values/Buffer.hpp"
+
+Buffer::Buffer()
+{
+	buffer = nullptr;
+	size = 0;
+	taken = 0;
+}
+
+Buffer::Buffer(size_t size)
+{
+	this->size = size;
+	this->buffer = new uint8_t[size];
+}
+
+Buffer::~Buffer()
+{
+	if (buffer)
+		delete[] buffer;
+}
+
+bool Buffer::resize(size_t new_size)
+{
+	if (size >= new_size)
+		return true;
+	uint8_t *new_buffer = (uint8_t *)realloc(buffer, new_size);
+	if (!new_buffer)
+	{
+		printf("Error resizing buffer\n");
+		return false;
+	}
+	buffer = new_buffer;
+	size = new_size;
+	return true;
+}
+
+uint32_t Buffer::add_end(uint8_t *data, size_t data_size)
+{
+	if (taken + data_size > size)
+		if (!resize(size + data_size))
+			return -1;
+
+	memcpy(buffer + taken, data, data_size);
+	taken += data_size;
+	return taken - data_size;
+}
+
+int Buffer::add_middle(uint8_t *data, size_t data_size, size_t index)
+{
+	if (taken + data_size > size)
+		if (!resize(size + data_size))
+			return -1;
+	memmove(buffer + index + data_size, buffer + index, taken - index);
+	memcpy(buffer + index, data, data_size);
+	taken += data_size;
+	return index;
+}
+
+void Buffer::remove_fast(uint8_t *data, size_t data_size)
+{
+	size_t index = data - buffer;
+	if (index < 0 || index > taken || index + data_size > taken)
+	{
+		printf("Error removing from buffer\n");
+		return;
+	}
+	memmove(buffer + index, buffer + index + data_size, taken - index - data_size);
+	taken -= data_size;
+}
+
+void Buffer::remove(size_t index, size_t data_size)
+{
+	if (index + data_size > taken)
+	{
+		printf("Error removing from buffer\n");
+		return;
+	}
+	memmove(buffer + index, buffer + index + data_size, taken - index - data_size);
+	taken -= data_size;
+}
+
+size_t Buffer::find(uint8_t *data, size_t data_size)
+{
+	for (size_t i = 0; i < taken; i++)
+		if (memcmp(buffer + i, data, data_size) == 0)
+			return i;
+
+	return SIZE_MAX;
+}
+
+void Buffer::remove(uint8_t *data, size_t data_size)
+{
+	size_t index = find(data, data_size);
+	if (index == SIZE_MAX)
+	{
+		printf("Error removing from buffer\n");
+		return;
+	}
+	remove(index, data_size);
+}
+
+bool Buffer::save_to_file()
+{
+	std::ofstream file(this->file_path, std::ios::binary | std::ios::out);
+	if (!file.is_open())
+	{
+		printf("Error saving file\n");
+		return false;
+	}
+	file.write((char *)this->buffer, this->taken);
+	file.close();
+	return true;
+}
+
+bool Buffer::save_to_file(std::string file_path)
+{
+	this->file_path = file_path;
+	return save_to_file();
+}
+
+bool Buffer::load_from_file()
+{
+	std::ifstream file(this->file_path, std::ios::binary | std::ios::in);
+	if (!file.is_open())
+		return false;
+
+	file.seekg(0, std::ios::end);
+
+	size_t file_size = file.tellg();
+	resize(file_size);
+
+	file.seekg(0, std::ios::beg);
+	file.read((char *)buffer, size);
+
+	if (file)
+		taken = file_size;
+	else
+		taken = file.gcount();
+
+	file.close();
+	return true;
+}
+
+bool Buffer::load_from_file(std::string file_path)
+{
+	this->file_path = file_path;
+	return load_from_file();
+}
diff --git a/src/values/RandBuffer.cpp b/src/values/RandBuffer.cpp
new file mode 100644
index 0000000..b4b36ed
--- /dev/null
+++ b/src/values/RandBuffer.cpp
@@ -0,0 +1,20 @@
+#include "values/RandBuffer.hpp"
+#include "Math.hpp"
+
+void RandBuffer::reset()
+{
+  m_buffer.clear();
+  m_pos = 0;
+}
+
+float RandBuffer::next()
+{
+  if (m_pos * 4 < m_buffer.taken)
+  {
+    return ((float *)m_buffer.buffer)[m_pos++];
+  }
+  float ret = GetRandomFloat();
+  m_buffer.add_end((uint8_t *)&ret, sizeof(float));
+  m_pos++;
+  return ret;
+}
\ No newline at end of file