diff --git a/TippuKivet/.idea/.idea.TippuKivet/.idea/indexLayout.xml b/TippuKivet/.idea/.idea.TippuKivet/.idea/indexLayout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7b08163cebc50fb3e777eea4881b68fcebc10590
--- /dev/null
+++ b/TippuKivet/.idea/.idea.TippuKivet/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="UserContentModel">
+    <attachedFolders />
+    <explicitIncludes />
+    <explicitExcludes />
+  </component>
+</project>
\ No newline at end of file
diff --git a/TippuKivet/.idea/.idea.TippuKivet/.idea/projectSettingsUpdater.xml b/TippuKivet/.idea/.idea.TippuKivet/.idea/projectSettingsUpdater.xml
new file mode 100644
index 0000000000000000000000000000000000000000..64af657f5c97b403cfbcdc958aed2580df4e6e5f
--- /dev/null
+++ b/TippuKivet/.idea/.idea.TippuKivet/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RiderProjectSettingsUpdater">
+    <option name="singleClickDiffPreview" value="1" />
+    <option name="vcsConfiguration" value="3" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/TippuKivet/.idea/.idea.TippuKivet/.idea/vcs.xml b/TippuKivet/.idea/.idea.TippuKivet/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..94a25f7f4cb416c083d265558da75d457237d671
--- /dev/null
+++ b/TippuKivet/.idea/.idea.TippuKivet/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/TippuKivet/.idea/.idea.TippuKivet/.idea/workspace.xml b/TippuKivet/.idea/.idea.TippuKivet/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8819f18e5fca56ef96074b7ae1b38f0847ee92b9
--- /dev/null
+++ b/TippuKivet/.idea/.idea.TippuKivet/.idea/workspace.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AutoGeneratedRunConfigurationManager">
+    <projectFile>TippuKivet/TippuKivet.csproj</projectFile>
+  </component>
+  <component name="AutoImportSettings">
+    <option name="autoReloadType" value="SELECTIVE" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="0ece420b-6c30-4076-bfb6-b7d5d926f6cf" name="Changes" comment="" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectColorInfo"><![CDATA[{
+  "associatedIndex": 4
+}]]></component>
+  <component name="ProjectId" id="2ul5Xh6t4LXvV8I0yFwY1wP6QLU" />
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent"><![CDATA[{
+  "keyToString": {
+    ".NET Project.TippuKivet.executor": "Run",
+    "RunOnceActivity.ShowReadmeOnStart": "true",
+    "git-widget-placeholder": "master",
+    "node.js.detected.package.eslint": "true",
+    "node.js.detected.package.tslint": "true",
+    "node.js.selected.package.eslint": "(autodetect)",
+    "node.js.selected.package.tslint": "(autodetect)",
+    "nodejs_package_manager_path": "npm",
+    "settings.editor.selected.configurable": "preferences.lookFeel",
+    "vue.rearranger.settings.migration": "true"
+  }
+}]]></component>
+  <component name="RunManager">
+    <configuration name="TippuKivet" type="DotNetProject" factoryName=".NET Project">
+      <option name="EXE_PATH" value="" />
+      <option name="PROGRAM_PARAMETERS" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="PASS_PARENT_ENVS" value="1" />
+      <option name="USE_EXTERNAL_CONSOLE" value="0" />
+      <option name="USE_MONO" value="0" />
+      <option name="RUNTIME_ARGUMENTS" value="" />
+      <option name="PROJECT_PATH" value="$PROJECT_DIR$/TippuKivet/TippuKivet.csproj" />
+      <option name="PROJECT_EXE_PATH_TRACKING" value="1" />
+      <option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
+      <option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
+      <option name="PROJECT_KIND" value="DotNetCore" />
+      <option name="PROJECT_TFM" value="" />
+      <method v="2">
+        <option name="Build" />
+      </method>
+    </configuration>
+  </component>
+  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="0ece420b-6c30-4076-bfb6-b7d5d926f6cf" name="Changes" comment="" />
+      <created>1742810361526</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1742810361526</updated>
+      <workItem from="1742810362569" duration="8643000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="3" />
+  </component>
+  <component name="UnityProjectConfiguration" hasMinimizedUI="false" />
+  <component name="VcsManagerConfiguration">
+    <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/TippuKivet/TippuKivet.sln b/TippuKivet/TippuKivet.sln
new file mode 100644
index 0000000000000000000000000000000000000000..515c89db24ac954b8d4a01d72b59b79e43da31f3
--- /dev/null
+++ b/TippuKivet/TippuKivet.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TippuKivet", "TippuKivet\TippuKivet.csproj", "{6F93BB78-40DE-4ECC-8013-9ED759B25F8D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6F93BB78-40DE-4ECC-8013-9ED759B25F8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6F93BB78-40DE-4ECC-8013-9ED759B25F8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6F93BB78-40DE-4ECC-8013-9ED759B25F8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6F93BB78-40DE-4ECC-8013-9ED759B25F8D}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/TippuKivet/TippuKivet/Ohjelma.cs b/TippuKivet/TippuKivet/Ohjelma.cs
new file mode 100644
index 0000000000000000000000000000000000000000..932a4faf2fd3d4a4c5c605d7140cb7cdc57cbd1c
--- /dev/null
+++ b/TippuKivet/TippuKivet/Ohjelma.cs
@@ -0,0 +1,26 @@
+#region Using Statements
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+#endregion
+
+namespace TippuKivet
+{
+    /// <summary>
+    /// The main class.
+    /// </summary>
+    public static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            using var game = new TippuKivet();
+            game.Run();
+        }
+    }
+}
\ No newline at end of file
diff --git a/TippuKivet/TippuKivet/TippuKivet.cs b/TippuKivet/TippuKivet/TippuKivet.cs
new file mode 100644
index 0000000000000000000000000000000000000000..78f117be66fe5f0547760930173ab38eccc569b1
--- /dev/null
+++ b/TippuKivet/TippuKivet/TippuKivet.cs
@@ -0,0 +1,189 @@
+using Jypeli;
+
+namespace TippuKivet
+{
+    public class TippuKivet : PhysicsGame
+    {
+        private readonly Vector nopeusOikea = new Vector(800, 0);
+        private readonly Vector nopeusVasen = new Vector(-800, 0);
+
+        private PhysicsObject pelaaja;
+        private IntMeter pistelaskuri;
+        private Timer ajastinTimantit;
+        private Timer ajastinKivet;
+        private int ohimenneetTimantit;
+
+        public override void Begin()
+        {
+            SetWindowSize(1024, 768, false);
+
+            ajastinTimantit = Timer.CreateAndStart(1.5, LuoTimantti);
+            ajastinKivet = Timer.CreateAndStart(3.0, LuoKivi);
+
+            pistelaskuri = new IntMeter(0);
+            LuoPisteNaytto();
+
+            Gravity = new Vector(0, -700);
+            pelaaja = LuoPelaaja(0);
+            LuoKenttä();
+            AsetaOhjaimet();
+        }
+
+        private void LuoKenttä()
+        {
+            PhysicsObject alalaatta = Level.CreateBottomBorder();
+            alalaatta.IsVisible = false;
+            AddCollisionHandler(alalaatta, "Kivi", KiviAlalaattaCollide);
+            AddCollisionHandler(alalaatta, "Timantti", TimanttiAlalaattaCollide);
+            
+            Level.Background.Color = Color.Black;
+            Camera.ZoomToLevel();
+        }
+
+        private PhysicsObject LuoPelaaja(double x)
+        {
+            PhysicsObject pelaaja = LuoObjekti(350, 100, x, -400, Color.Red, "Pelaaja");
+            pelaaja.IgnoresCollisionResponse = true;
+            pelaaja.IgnoresGravity = true;
+
+            AddCollisionHandler(pelaaja, "Kivi", PelaajaKiviCollide);
+            AddCollisionHandler(pelaaja, "Timantti", PelaajaTimanttiCollide);
+            
+            Add(pelaaja);
+            return pelaaja;
+        }
+
+        private void LuoPisteNaytto()
+        {
+            Label pisteNaytto = new Label
+            {
+                Position = new Vector(-400, 200),
+                TextColor = Color.Red,
+                Color = Color.White,
+                Size = new Vector(5000, 5000)
+            };
+            pisteNaytto.BindTo(pistelaskuri);
+            Add(pisteNaytto);
+        }
+
+        private void LuoTimantti()
+        {
+            double x = RandomGen.NextDouble(Level.Left + 50, Level.Right - 50);
+            PhysicsObject timantti = LuoObjekti(60, 60, x, Level.Top + 50, Color.Yellow, "Timantti");
+            timantti.AngularVelocity = RandomGen.NextDouble(-5.0, 5.0);
+            AddCollisionHandler(timantti, "Pelaaja", PelaajaTimanttiCollide);
+            Add(timantti);
+        }
+
+        private void LuoKivi()
+        {
+            double x = RandomGen.NextDouble(Level.Left + 20, Level.Right - 20);
+            double randomSize = RandomGen.NextDouble(30.0, 120.0);
+            PhysicsObject kivi = LuoObjekti(randomSize, randomSize, x, Level.Top + 50, Color.White, "Kivi");
+            kivi.Velocity = new Vector(0, -400);
+            AddCollisionHandler(kivi, "Pelaaja", PelaajaKiviCollide);
+            Add(kivi);
+        }
+        
+        private PhysicsObject LuoObjekti(double width, double height, double x, double y, Color color, string tag)
+        {
+            return new PhysicsObject(width, height, Shape.Rectangle)
+            {
+                X = x,
+                Y = y,
+                Color = color,
+                Tag = tag
+            };
+        }
+
+        private void PelaajaTimanttiCollide(PhysicsObject pelaaja, PhysicsObject timantti)
+        {
+            pistelaskuri.Value += 1;
+            timantti.Destroy();
+            KutistaPelaaja();
+
+            if (pistelaskuri.Value >= 10)
+            {
+                VoitaPeli();
+            }
+        }
+
+        private void PelaajaKiviCollide(PhysicsObject pelaaja, PhysicsObject kivi)
+        {
+            kivi.Destroy();
+            LopetaPeli("Kivi osui sinua päähän, Peli ohi!");
+        }
+
+        private void KiviAlalaattaCollide(PhysicsObject alalaatta, PhysicsObject kivi)
+        {
+            kivi.Destroy();
+        }
+
+        private void TimanttiAlalaattaCollide(PhysicsObject alalaatta, PhysicsObject timantti)
+        {
+            timantti.Destroy();
+            ohimenneetTimantit++;
+
+            if (ohimenneetTimantit >= 2)
+            {
+                LopetaPeli("Et ollut tarpeeksi tehokas!");
+            }
+        }
+
+        private void KutistaPelaaja()
+        {
+            const double shrinkFactor = 0.9;
+            const double minSize = 10.0;
+
+            if (pelaaja.Width > minSize && pelaaja.Height > minSize)
+            {
+                pelaaja.Width *= shrinkFactor;
+                pelaaja.Height *= shrinkFactor;
+            }
+        }
+
+        private void VoitaPeli()
+        {
+            MessageDisplay.Add("Olet TippuKiviLuolan suvereeni Päällikkö!");
+            ajastinTimantit.Stop();
+            ajastinKivet.Stop();
+            Timer.SingleShot(6, Exit);
+        }
+
+        private void LopetaPeli(string viesti)
+        {
+            MessageDisplay.Add(viesti);
+            ajastinTimantit.Stop();
+            ajastinKivet.Stop();
+            Timer.SingleShot(7, Exit);
+        }
+
+        private void AsetaOhjaimet()
+        {
+            Keyboard.Listen(Key.A, ButtonState.Down, AsetaNopeus, "Liikuta pelaajaa vasemmalle", pelaaja, nopeusVasen);
+            Keyboard.Listen(Key.A, ButtonState.Released, AsetaNopeus, null, pelaaja, Vector.Zero);
+            Keyboard.Listen(Key.D, ButtonState.Down, AsetaNopeus, "Liikuta pelaajaa oikealle", pelaaja, nopeusOikea);
+            Keyboard.Listen(Key.D, ButtonState.Released, AsetaNopeus, null, pelaaja, Vector.Zero);
+            Keyboard.Listen(Key.Left, ButtonState.Down, AsetaNopeus, "Liikuta pelaajaa vasemmalle nuolinäppäimellä", pelaaja, nopeusVasen);
+            Keyboard.Listen(Key.Left, ButtonState.Released, AsetaNopeus, null, pelaaja, Vector.Zero);
+            Keyboard.Listen(Key.Right, ButtonState.Down, AsetaNopeus, "Liikuta pelaajaa oikealle nuolinäppäimellä", pelaaja, nopeusOikea);
+            Keyboard.Listen(Key.Right, ButtonState.Released, AsetaNopeus, null, pelaaja, Vector.Zero);
+            Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
+        }
+
+        private void AsetaNopeus(PhysicsObject pelaaja, Vector nopeus)
+        {
+            if ((pelaaja.X + pelaaja.Width / 2 >= Level.Right && nopeus.X > 0) ||
+                (pelaaja.X - pelaaja.Width / 2 <= Level.Left && nopeus.X < 0))
+            {
+                pelaaja.Velocity = Vector.Zero;
+            }
+            else
+            {
+                pelaaja.Velocity = nopeus;
+            }
+        }
+
+
+    }
+}
diff --git a/TippuKivet/TippuKivet/TippuKivet.csproj b/TippuKivet/TippuKivet/TippuKivet.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..d164748ef3ffb530b112a04baa4bad2904c8c70d
--- /dev/null
+++ b/TippuKivet/TippuKivet/TippuKivet.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>WinExe</OutputType>
+        <TargetFramework>net8.0</TargetFramework>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="Jypeli.NET" Version="11.*"/>
+        <PackageReference Include="Jypeli.FarseerPhysics.NET" Version="2.*"/>
+    </ItemGroup>
+
+</Project>
diff --git a/suunnitelma/esimerkkikuva.png b/suunnitelma/esimerkkikuva.png
deleted file mode 100644
index 9b0022169994bf03a5509f42ae69f18efaf4114a..0000000000000000000000000000000000000000
Binary files a/suunnitelma/esimerkkikuva.png and /dev/null differ