diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..3d9d087db261b54fe638e7a30f0d6ac003926eac
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1,114 @@
+## Java
+
+*.class
+*.war
+*.ear
+hs_err_pid*
+
+## Robovm
+/ios/robovm-build/
+
+## GWT
+/html/war/
+/html/gwt-unitCache/
+.apt_generated/
+.gwt/
+gwt-unitCache/
+www-test/
+.gwt-tmp/
+
+## Android Studio and Intellij and Android in general
+/android/libs/armeabi-v7a/
+/android/libs/arm64-v8a/
+/android/libs/x86/
+/android/libs/x86_64/
+/android/gen/
+.idea/
+*.ipr
+*.iws
+*.iml
+/android/out/
+com_crashlytics_export_strings.xml
+
+## Eclipse
+
+.classpath
+.project
+.metadata/
+/android/bin/
+/core/bin/
+/desktop/bin/
+/html/bin/
+/ios/bin/
+*.tmp
+*.bak
+*.swp
+*~.nib
+.settings/
+.loadpath
+.externalToolBuilders/
+*.launch
+
+## NetBeans
+
+/nbproject/private/
+/android/nbproject/private/
+/core/nbproject/private/
+/desktop/nbproject/private/
+/html/nbproject/private/
+/ios/nbproject/private/
+
+/build/
+/android/build/
+/core/build/
+/desktop/build/
+/html/build/
+/ios/build/
+
+/nbbuild/
+/android/nbbuild/
+/core/nbbuild/
+/desktop/nbbuild/
+/html/nbbuild/
+/ios/nbbuild/
+
+/dist/
+/android/dist/
+/core/dist/
+/desktop/dist/
+/html/dist/
+/ios/dist/
+
+/nbdist/
+/android/nbdist/
+/core/nbdist/
+/desktop/nbdist/
+/html/nbdist/
+/ios/nbdist/
+
+nbactions.xml
+nb-configuration.xml
+
+## Gradle
+
+/local.properties
+.gradle/
+gradle-app.setting
+/build/
+/android/build/
+/core/build/
+/desktop/build/
+/html/build/
+/ios/build/
+
+## OS Specific
+.DS_Store
+Thumbs.db
+
+## iOS
+/ios/xcode/*.xcodeproj/*
+!/ios/xcode/*.xcodeproj/xcshareddata
+!/ios/xcode/*.xcodeproj/project.pbxproj
+/ios/xcode/native/
+/ios/IOSLauncher.app
+/ios/IOSLauncher.app.dSYM
diff --git a/frontend/android/AndroidManifest.xml b/frontend/android/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..02c39ad3e8c6b1b02cf62b9725394aead15b4cea
--- /dev/null
+++ b/frontend/android/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.game.tankwars">
+
+    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+
+    <application
+        android:allowBackup="true"
+        android:fullBackupContent="true"
+        android:icon="@drawable/ic_launcher"
+        android:isGame="true"
+        android:appCategory="game"
+        android:label="@string/app_name"
+        tools:ignore="UnusedAttribute">
+        <activity
+            android:name="com.game.tankwars.AndroidLauncher"
+            android:label="@string/app_name" 
+            android:screenOrientation="landscape"
+            android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/frontend/android/build.gradle b/frontend/android/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..fb0d06bc0d5a8cd8476ce06f29c59d7d19656186
--- /dev/null
+++ b/frontend/android/build.gradle
@@ -0,0 +1,88 @@
+android {
+    buildToolsVersion "33.0.1"
+    compileSdkVersion 33
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            java.srcDirs = ['src']
+            aidl.srcDirs = ['src']
+            renderscript.srcDirs = ['src']
+            res.srcDirs = ['res']
+            assets.srcDirs = ['../assets']
+            jniLibs.srcDirs = ['libs']
+        }
+
+    }
+    packagingOptions {
+        exclude 'META-INF/robovm/ios/robovm.xml'
+    }
+    defaultConfig {
+        applicationId "com.game.tankwars"
+        minSdkVersion 14
+        targetSdkVersion 33
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled true
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+
+// called every time gradle gets executed, takes the native dependencies of
+// the natives configuration, and extracts them to the proper libs/ folders
+// so they get packed with the APK.
+task copyAndroidNatives {
+    doFirst {
+        file("libs/armeabi-v7a/").mkdirs()
+        file("libs/arm64-v8a/").mkdirs()
+        file("libs/x86_64/").mkdirs()
+        file("libs/x86/").mkdirs()
+
+        configurations.natives.copy().files.each { jar ->
+            def outputDir = null
+            if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
+            if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
+            if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
+            if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
+            if(outputDir != null) {
+                copy {
+                    from zipTree(jar)
+                    into outputDir
+                    include "*.so"
+                }
+            }
+        }
+    }
+}
+
+tasks.matching { it.name.contains("merge") && it.name.contains("JniLibFolders") }.configureEach { packageTask ->
+    packageTask.dependsOn 'copyAndroidNatives'
+}
+
+task run(type: Exec) {
+    def path
+    def localProperties = project.file("../local.properties")
+    if (localProperties.exists()) {
+        Properties properties = new Properties()
+        localProperties.withInputStream { instr ->
+            properties.load(instr)
+        }
+        def sdkDir = properties.getProperty('sdk.dir')
+        if (sdkDir) {
+            path = sdkDir
+        } else {
+            path = "$System.env.ANDROID_HOME"
+        }
+    } else {
+        path = "$System.env.ANDROID_HOME"
+    }
+
+    def adb = path + "/platform-tools/adb"
+    commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.game.tankwars/com.game.tankwars.AndroidLauncher'
+}
+
+eclipse.project.name = appName + "-android"
diff --git a/frontend/android/ic_launcher-web.png b/frontend/android/ic_launcher-web.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f0110dd3c1fcb756c2b9e2cdaef289b9990e7f3
Binary files /dev/null and b/frontend/android/ic_launcher-web.png differ
diff --git a/frontend/android/proguard-rules.pro b/frontend/android/proguard-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..63c1adb6ea11ce663a9d6db358b5736feb1da28b
--- /dev/null
+++ b/frontend/android/proguard-rules.pro
@@ -0,0 +1,38 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+-verbose
+
+-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
+
+# Required if using Gdx-Controllers extension
+-keep class com.badlogic.gdx.controllers.android.AndroidControllers
+
+# Required if using Box2D extension
+-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
+   boolean contactFilter(long, long);
+   void    beginContact(long);
+   void    endContact(long);
+   void    preSolve(long, long);
+   void    postSolve(long, long);
+   boolean reportFixture(long);
+   float   reportRayFixture(long, float, float, float, float, float);
+}
diff --git a/frontend/android/project.properties b/frontend/android/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..3fefa92640cd1db0af03197ce342de43ee0e8033
--- /dev/null
+++ b/frontend/android/project.properties
@@ -0,0 +1,9 @@
+# This file is used by the Eclipse ADT plugin. It is unnecessary for IDEA and Android Studio projects, which
+# configure Proguard and the Android target via the build.gradle file.
+
+# To enable ProGuard to work with Eclipse ADT, uncomment this (available properties: sdk.dir, user.home)
+# and ensure proguard.jar in the Android SDK is up to date (or alternately reduce the android target to 23 or lower):
+# proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-rules.pro
+
+# Project target.
+target=android-19
diff --git a/frontend/android/res/drawable-anydpi-v26/ic_launcher.xml b/frontend/android/res/drawable-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c7313ae11ce6d6f203a17843f0dfe026a92ebb8
--- /dev/null
+++ b/frontend/android/res/drawable-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon
+        xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_background_color"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
diff --git a/frontend/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml b/frontend/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5916ee8f982b4215a00d2f4d1abf588fa56430dc
--- /dev/null
+++ b/frontend/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml
@@ -0,0 +1,40 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+  <path
+      android:pathData="M22,48.667l2.987,0l0,10.667l-2.987,0z"
+      android:fillColor="#000000"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M26.907,52.72l2.987,0l0,6.613l-2.987,0z"
+      android:fillColor="#000000"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M26.907,48.667l2.987,0l0,2.56l-2.987,0z"
+      android:fillColor="#000000"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M31.813,48.667L31.813,52.72 31.813,55.067 31.813,56.767 31.813,59.333l2.992,0 2.117,0c1.654,0 2.998,-1.481 2.998,-3.307 0,-1.826 -1.344,-3.307 -2.998,-3.307l-2.117,0L34.805,48.667ZM34.805,55.067l1.269,0c0.469,0 0.848,0.384 0.848,0.853 0,0.469 -0.379,0.847 -0.848,0.847l-1.269,0z"
+      android:fillColor="#000000"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="m44.192,48.667c-1.65,0 -2.992,1.481 -2.992,3.307 0,0.023 -0,0.044 0,0.067 0,0.004 -0,0.009 0,0.013l0,3.893c-0.001,0.027 0,0.053 0,0.08 0,1.826 1.341,3.307 2.992,3.307l2.112,0 0.247,0 2.739,0 0.247,0 2.112,0c1.651,0 2.992,-1.481 2.992,-3.307 0,-1.826 -1.341,-3.307 -2.992,-3.307l-1.199,0 -0.48,0 -2.372,0l0,2.347l2.372,0 0.48,0 0.353,0c0.468,0 0.846,0.384 0.846,0.853 0,0.469 -0.378,0.847 -0.846,0.847l-0.833,0 -0.433,0 -0.247,0 -2.739,0 -0.247,0 -0.433,0 -0.833,0c-0.459,0 -0.832,-0.363 -0.846,-0.82l0,-3.893 0,-0.013c0.021,-0.45 0.391,-0.807 0.846,-0.807l0.833,0 0.433,0 1.293,0l0,0.007L54.207,51.24L54.207,48.667l-4.917,0 -1.692,0 -1.293,0 -2.112,0z"
+      android:fillColor="#e74a45"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M56.133,48.667L56.133,51.238l5.406,0 1.859,0 1.105,0 0.43,0 0.827,0c0.452,0 0.82,0.356 0.84,0.806l0,0.013 0,3.891c-0.014,0.456 -0.384,0.819 -0.84,0.819l-0.827,0 -0.43,0 -1.899,0 -1.065,0 -2.442,0L59.098,52.724L56.133,52.724l0,4.044 0,1.752 0,0.813l5.406,0 1.065,0 1.899,0 2.098,0c1.639,0 2.971,-1.48 2.971,-3.305 0,-0.027 0.001,-0.053 0,-0.08L69.573,52.058c0,-0.004 -0,-0.009 0,-0.013 0,-0.022 0,-0.044 0,-0.067 0,-1.825 -1.332,-3.305 -2.971,-3.305l-2.098,0 -1.105,0l0,-0.007L56.133,48.667Z"
+      android:fillColor="#e74a45"
+      android:strokeColor="#00000000"
+      android:fillAlpha="1"/>
+  <path
+      android:pathData="M69.572,48.667L73.72,48.667L77.787,52.733 81.853,48.667l4.147,0l-5.333,5.333 5.333,5.333L81.853,59.333L77.787,55.267 73.72,59.333l-4.147,0l5.333,-5.333z"
+      android:fillColor="#e74a45"
+      android:strokeColor="#00000000"/>
+</vector>
diff --git a/frontend/android/res/drawable-hdpi/ic_launcher.png b/frontend/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..91f696b48e19c3052c6aae15eeae5ffe15338769
Binary files /dev/null and b/frontend/android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/frontend/android/res/drawable-mdpi/ic_launcher.png b/frontend/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1ab239c58cbb3ade4d6a53d9e815fcee786be0f
Binary files /dev/null and b/frontend/android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/frontend/android/res/drawable-xhdpi/ic_launcher.png b/frontend/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..2011cc006a668ddedb2a4b694a4129e6bcb1d5df
Binary files /dev/null and b/frontend/android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/frontend/android/res/drawable-xxhdpi/ic_launcher.png b/frontend/android/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..25fcef036d3f9011954534316c589ed9fcf649f6
Binary files /dev/null and b/frontend/android/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/frontend/android/res/drawable-xxxhdpi/ic_launcher.png b/frontend/android/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1099464ab0b61e3efe7b19f6a376e2c9c33eea0
Binary files /dev/null and b/frontend/android/res/drawable-xxxhdpi/ic_launcher.png differ
diff --git a/frontend/android/res/values/color.xml b/frontend/android/res/values/color.xml
new file mode 100644
index 0000000000000000000000000000000000000000..933353e06d5c8bccfce91974e4c13c52f598a72f
--- /dev/null
+++ b/frontend/android/res/values/color.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="ic_background_color">#FFFFFFFF</color>
+</resources>
diff --git a/frontend/android/res/values/strings.xml b/frontend/android/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc43a47f062408883dd8cf104e1560294d6cfec0
--- /dev/null
+++ b/frontend/android/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Tank Wars</string>
+
+</resources>
diff --git a/frontend/android/src/com/game/tankwars/AndroidLauncher.java b/frontend/android/src/com/game/tankwars/AndroidLauncher.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c6c5c394bcacf03ae1d76010ab65742363ad4cb
--- /dev/null
+++ b/frontend/android/src/com/game/tankwars/AndroidLauncher.java
@@ -0,0 +1,16 @@
+package com.game.tankwars;
+
+import android.os.Bundle;
+
+import com.badlogic.gdx.backends.android.AndroidApplication;
+import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
+import com.game.tankwars.TankWarsGame;
+
+public class AndroidLauncher extends AndroidApplication {
+	@Override
+	protected void onCreate (Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
+		initialize(new TankWarsGame(), config);
+	}
+}
diff --git a/frontend/assets/badlogic.jpg b/frontend/assets/badlogic.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4390da6e0f6d041590c6313d2b4c978abc00a342
Binary files /dev/null and b/frontend/assets/badlogic.jpg differ
diff --git a/frontend/build.gradle b/frontend/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1fb8ca8279633c36f8c9fb153ba270f5965b9076
--- /dev/null
+++ b/frontend/build.gradle
@@ -0,0 +1,97 @@
+buildscript {
+    
+
+    repositories {
+        mavenLocal()
+        mavenCentral()
+        gradlePluginPortal()
+        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
+        google()
+    }
+    dependencies {
+        classpath 'org.wisepersist:gwt-gradle-plugin:1.1.16'
+        classpath 'org.gretty:gretty:3.0.7'
+        classpath 'com.android.tools.build:gradle:7.2.2'
+        
+
+    }
+}
+
+allprojects {
+    apply plugin: "eclipse"
+
+    version = '1.0'
+    ext {
+        appName = "Tank Wars"
+        gdxVersion = '1.11.0'
+        roboVMVersion = '2.3.16'
+        box2DLightsVersion = '1.5'
+        ashleyVersion = '1.7.4'
+        aiVersion = '1.8.2'
+        gdxControllersVersion = '2.2.1'
+    }
+
+    repositories {
+        mavenLocal()
+        mavenCentral()
+        google()
+        gradlePluginPortal()
+        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
+        maven { url "https://oss.sonatype.org/content/repositories/releases/" }
+        maven { url "https://jitpack.io" }
+    }
+}
+
+project(":desktop") {
+    apply plugin: "java-library"
+
+
+    dependencies {
+        implementation project(":core")
+        api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
+        api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
+        
+    }
+}
+
+project(":android") {
+    apply plugin: "com.android.application"
+
+    configurations { natives }
+
+    dependencies {
+        implementation project(":core")
+        api "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
+        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
+        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
+        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
+        natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
+        
+    }
+}
+
+project(":html") {
+    apply plugin: "java-library"
+    apply plugin: "gwt"
+    apply plugin: "war"
+    apply plugin: "org.gretty"
+
+
+    dependencies {
+        implementation project(":core")
+        api "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion"
+        api "com.badlogicgames.gdx:gdx:$gdxVersion:sources"
+        api "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"
+        
+    }
+}
+
+project(":core") {
+    apply plugin: "java-library"
+
+
+    dependencies {
+        api "com.badlogicgames.gdx:gdx:$gdxVersion"
+        
+    }
+}
diff --git a/frontend/core/build.gradle b/frontend/core/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..d192d041d2164132cd2ec37cc81105151b1b9126
--- /dev/null
+++ b/frontend/core/build.gradle
@@ -0,0 +1,6 @@
+sourceCompatibility = 1.7
+[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
+
+sourceSets.main.java.srcDirs = [ "src/" ]
+
+eclipse.project.name = appName + "-core"
diff --git a/frontend/core/src/TankWarsGame.gwt.xml b/frontend/core/src/TankWarsGame.gwt.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6e150872f37d50514299f7e1465eb41326f01bb0
--- /dev/null
+++ b/frontend/core/src/TankWarsGame.gwt.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://www.gwtproject.org/doctype/2.8.0/gwt-module.dtd">
+<module>
+	<source path="com/game/tankwars" />
+</module>
\ No newline at end of file
diff --git a/frontend/core/src/com/game/tankwars/TankWarsGame.java b/frontend/core/src/com/game/tankwars/TankWarsGame.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa0de6efc7206bc2ae810c4cbf44dc3ab053ae25
--- /dev/null
+++ b/frontend/core/src/com/game/tankwars/TankWarsGame.java
@@ -0,0 +1,31 @@
+package com.game.tankwars;
+
+import com.badlogic.gdx.ApplicationAdapter;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.graphics.g2d.SpriteBatch;
+import com.badlogic.gdx.utils.ScreenUtils;
+
+public class TankWarsGame extends ApplicationAdapter {
+	SpriteBatch batch;
+	Texture img;
+	
+	@Override
+	public void create () {
+		batch = new SpriteBatch();
+		img = new Texture("badlogic.jpg");
+	}
+
+	@Override
+	public void render () {
+		ScreenUtils.clear(1, 0, 0, 1);
+		batch.begin();
+		batch.draw(img, 0, 0);
+		batch.end();
+	}
+	
+	@Override
+	public void dispose () {
+		batch.dispose();
+		img.dispose();
+	}
+}
diff --git a/frontend/desktop/build.gradle b/frontend/desktop/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..6a6e12b4bda59b0855db384ce041fe003d939b71
--- /dev/null
+++ b/frontend/desktop/build.gradle
@@ -0,0 +1,47 @@
+sourceCompatibility = 1.8
+sourceSets.main.java.srcDirs = [ "src/" ]
+sourceSets.main.resources.srcDirs = ["../assets"]
+
+project.ext.mainClassName = "com.game.tankwars.DesktopLauncher"
+project.ext.assetsDir = new File("../assets")
+
+import org.gradle.internal.os.OperatingSystem
+
+task run(dependsOn: classes, type: JavaExec) {
+    main = project.mainClassName
+    classpath = sourceSets.main.runtimeClasspath
+    standardInput = System.in
+    workingDir = project.assetsDir
+    ignoreExitValue = true
+
+    if (OperatingSystem.current() == OperatingSystem.MAC_OS) {
+        // Required to run on macOS
+        jvmArgs += "-XstartOnFirstThread"
+    }
+}
+
+task debug(dependsOn: classes, type: JavaExec) {
+    main = project.mainClassName
+    classpath = sourceSets.main.runtimeClasspath
+    standardInput = System.in
+    workingDir = project.assetsDir
+    ignoreExitValue = true
+    debug = true
+}
+
+task dist(type: Jar) {
+    duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
+    manifest {
+        attributes 'Main-Class': project.mainClassName
+    }
+    dependsOn configurations.runtimeClasspath
+    from {
+        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+    }
+    with jar
+}
+
+
+dist.dependsOn classes
+
+eclipse.project.name = appName + "-desktop"
diff --git a/frontend/desktop/src/com/game/tankwars/DesktopLauncher.java b/frontend/desktop/src/com/game/tankwars/DesktopLauncher.java
new file mode 100644
index 0000000000000000000000000000000000000000..a537466a8192c5a64f08aab4170458f1bca1eeb8
--- /dev/null
+++ b/frontend/desktop/src/com/game/tankwars/DesktopLauncher.java
@@ -0,0 +1,15 @@
+package com.game.tankwars;
+
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
+import com.game.tankwars.TankWarsGame;
+
+// Please note that on macOS your application needs to be started with the -XstartOnFirstThread JVM argument
+public class DesktopLauncher {
+	public static void main (String[] arg) {
+		Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
+		config.setForegroundFPS(60);
+		config.setTitle("Tank Wars");
+		new Lwjgl3Application(new TankWarsGame(), config);
+	}
+}
diff --git a/frontend/gradle.properties b/frontend/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ff329ac36cbe588a0699f6e5ca4446ee0f08abf5
--- /dev/null
+++ b/frontend/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.daemon=true
+org.gradle.jvmargs=-Xms128m -Xmx1500m
+org.gradle.configureondemand=false
diff --git a/frontend/gradle/wrapper/gradle-wrapper.jar b/frontend/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196
Binary files /dev/null and b/frontend/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/frontend/gradle/wrapper/gradle-wrapper.properties b/frontend/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ae04661ee733431762e7ccf8ab9b7409ed44960c
--- /dev/null
+++ b/frontend/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/frontend/gradlew b/frontend/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..a69d9cb6c20655813e44515156e7253a2a239138
--- /dev/null
+++ b/frontend/gradlew
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/frontend/gradlew.bat b/frontend/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..53a6b238d414d91c30c5644c82393d27416fbbe6
--- /dev/null
+++ b/frontend/gradlew.bat
@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/frontend/html/build.gradle b/frontend/html/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1b443e26e3032e6dcbf7e5312017b84e6ecc05fe
--- /dev/null
+++ b/frontend/html/build.gradle
@@ -0,0 +1,92 @@
+gwt {
+    gwtVersion='2.8.2' // Should match the gwt version used for building the gwt backend
+    maxHeapSize="1G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY
+    minHeapSize="1G"
+
+    src = files(file("src/")) // Needs to be in front of "modules" below.
+    modules 'com.game.tankwars.GdxDefinition'
+    devModules 'com.game.tankwars.GdxDefinitionSuperdev'
+    project.webAppDirName = 'webapp'
+
+    compiler {
+        strict = true;
+        disableCastChecking = true;
+    }
+}
+
+import org.wisepersist.gradle.plugins.gwt.GwtSuperDev
+import org.akhikhl.gretty.AppBeforeIntegrationTestTask
+
+gretty.httpPort = 8080
+gretty.resourceBase = project.buildDir.path + "/gwt/draftOut"
+gretty.contextPath = "/"
+gretty.portPropertiesFileName = "TEMP_PORTS.properties"
+
+task startHttpServer () {
+    dependsOn draftCompileGwt
+
+    doFirst {
+        copy {
+            from "webapp"
+            into gretty.resourceBase
+        }
+
+        copy {
+            from "war"
+            into gretty.resourceBase
+        }
+    }
+}
+
+task beforeRun(type: AppBeforeIntegrationTestTask, dependsOn: startHttpServer) {
+    // The next line allows ports to be reused instead of
+    // needing a process to be manually terminated.
+    file("build/TEMP_PORTS.properties").delete()
+    // Somewhat of a hack; uses Gretty's support for wrapping a task in
+    // a start and then stop of a Jetty server that serves files while
+    // also running the SuperDev code server.
+    integrationTestTask 'superDev'
+
+    interactive false
+}
+
+task superDev (type: GwtSuperDev) {
+    dependsOn startHttpServer
+    doFirst {
+        gwt.modules = gwt.devModules
+    }
+}
+
+task dist(dependsOn: [clean, compileGwt]) {
+    doLast {
+        file("build/dist").mkdirs()
+        copy {
+            from "build/gwt/out"
+            into "build/dist"
+        }
+        copy {
+            from "webapp"
+            into "build/dist"
+            }
+        copy {
+            from "war"
+            into "build/dist"
+        }
+    }
+}
+
+task addSource {
+    doLast {
+        sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs)
+    }
+}
+
+tasks.compileGwt.dependsOn(addSource)
+tasks.draftCompileGwt.dependsOn(addSource)
+tasks.checkGwt.dependsOn(addSource)
+checkGwt.war = file("war")
+
+sourceCompatibility = 1.7
+sourceSets.main.java.srcDirs = [ "src/" ]
+
+eclipse.project.name = appName + "-html"
diff --git a/frontend/html/src/com/game/tankwars/GdxDefinition.gwt.xml b/frontend/html/src/com/game/tankwars/GdxDefinition.gwt.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cf4f97607356c0c8a355365f68c415b62857a669
--- /dev/null
+++ b/frontend/html/src/com/game/tankwars/GdxDefinition.gwt.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://www.gwtproject.org/doctype/2.8.0/gwt-module.dtd">
+<module rename-to="html">
+	<inherits name='com.badlogic.gdx.backends.gdx_backends_gwt' />
+
+	<inherits name='TankWarsGame' />
+	<entry-point class='com.game.tankwars.client.HtmlLauncher' />
+	<set-configuration-property name='xsiframe.failIfScriptTag' value='FALSE'/>
+	<set-configuration-property name="gdx.assetpath" value="../assets" />
+	<set-property name="user.agent" value="gecko1_8, safari"/>
+	<collapse-property name="user.agent" values="*" />
+</module>
diff --git a/frontend/html/src/com/game/tankwars/GdxDefinitionSuperdev.gwt.xml b/frontend/html/src/com/game/tankwars/GdxDefinitionSuperdev.gwt.xml
new file mode 100644
index 0000000000000000000000000000000000000000..62ba476b113486f62e14da9923bbabe478162b08
--- /dev/null
+++ b/frontend/html/src/com/game/tankwars/GdxDefinitionSuperdev.gwt.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://www.gwtproject.org/doctype/2.8.0/gwt-module.dtd">
+<module rename-to="html">
+	<inherits name='com.badlogic.gdx.backends.gdx_backends_gwt' />
+
+    <inherits name='com.game.tankwars.GdxDefinition' />
+    
+    <collapse-all-properties />
+    
+	<add-linker name="xsiframe"/>	
+	<set-configuration-property name="devModeRedirectEnabled" value="true"/>
+	<set-configuration-property name='xsiframe.failIfScriptTag' value='FALSE'/>	
+</module>
diff --git a/frontend/html/src/com/game/tankwars/client/HtmlLauncher.java b/frontend/html/src/com/game/tankwars/client/HtmlLauncher.java
new file mode 100644
index 0000000000000000000000000000000000000000..42dff39df3a14c7c1398372c107659fcc5313aa6
--- /dev/null
+++ b/frontend/html/src/com/game/tankwars/client/HtmlLauncher.java
@@ -0,0 +1,22 @@
+package com.game.tankwars.client;
+
+import com.badlogic.gdx.ApplicationListener;
+import com.badlogic.gdx.backends.gwt.GwtApplication;
+import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
+import com.game.tankwars.TankWarsGame;
+
+public class HtmlLauncher extends GwtApplication {
+
+        @Override
+        public GwtApplicationConfiguration getConfig () {
+                // Resizable application, uses available space in browser
+                return new GwtApplicationConfiguration(true);
+                // Fixed size application:
+                //return new GwtApplicationConfiguration(480, 320);
+        }
+
+        @Override
+        public ApplicationListener createApplicationListener () {
+                return new TankWarsGame();
+        }
+}
\ No newline at end of file
diff --git a/frontend/html/webapp/WEB-INF/web.xml b/frontend/html/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4301df2483bb501c3c72079c65b160578721412f
--- /dev/null
+++ b/frontend/html/webapp/WEB-INF/web.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" ?>
+<web-app>
+</web-app>
\ No newline at end of file
diff --git a/frontend/html/webapp/index.html b/frontend/html/webapp/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..b42db3b0d0588c6ad180bad0453c326d1be5987f
--- /dev/null
+++ b/frontend/html/webapp/index.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+       <head>
+              <title>Tank Wars</title>
+              <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+              <meta id="gameViewport" name="viewport" content="width=device-width initial-scale=1">
+              <link href="styles.css" rel="stylesheet" type="text/css">
+       </head>
+
+       <body>
+              <a class="superdev" href="javascript:%7B%20window.__gwt_bookmarklet_params%20%3D%20%7B'server_url'%3A'http%3A%2F%2Flocalhost%3A9876%2F'%7D%3B%20var%20s%20%3D%20document.createElement('script')%3B%20s.src%20%3D%20'http%3A%2F%2Flocalhost%3A9876%2Fdev_mode_on.js'%3B%20void(document.getElementsByTagName('head')%5B0%5D.appendChild(s))%3B%7D">&#8635;</a>
+              <div align="center" id="embed-html"></div>
+              <script type="text/javascript" src="html/html.nocache.js"></script>
+       </body>
+
+       <script>
+              function handleMouseDown(evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+                window.focus();
+              }
+
+              function handleMouseUp(evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+              }
+              document.addEventListener('contextmenu', event => event.preventDefault());
+              document.getElementById('embed-html').addEventListener('mousedown', handleMouseDown, false);
+              document.getElementById('embed-html').addEventListener('mouseup', handleMouseUp, false);
+       </script>
+</html>
diff --git a/frontend/html/webapp/styles.css b/frontend/html/webapp/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..0abbdaa32d9e099605f1a428c6fe752ed2c72830
--- /dev/null
+++ b/frontend/html/webapp/styles.css
@@ -0,0 +1,43 @@
+canvas {
+    cursor: default;
+    outline: none;
+}
+
+body {
+    background-color: #222222;
+}
+
+.superdev {
+    color: rgb(37,37,37);
+    text-shadow: 0px 1px 1px rgba(250,250,250,0.1);
+    font-size: 50pt;
+    display: block;
+    position: relative;
+    text-decoration: none;
+    background-color: rgb(83,87,93);
+    box-shadow: 0px 3px 0px 0px rgb(34,34,34),
+                0px 7px 10px 0px rgb(17,17,17),
+                inset 0px 1px 1px 0px rgba(250, 250, 250, .2),
+                inset 0px -12px 35px 0px rgba(0, 0, 0, .5);
+    width: 70px;
+    height: 70px;
+    border: 0;
+    border-radius: 35px;
+    text-align: center;
+    line-height: 68px;
+}
+
+.superdev:active {
+    box-shadow: 0px 0px 0px 0px rgb(34,34,34),
+                0px 3px 7px 0px rgb(17,17,17),
+                inset 0px 1px 1px 0px rgba(250, 250, 250, .2),
+                inset 0px -10px 35px 5px rgba(0, 0, 0, .5);
+    background-color: rgb(83,87,93);
+    top: 3px;
+    color: #fff;
+    text-shadow: 0px 0px 3px rgb(250,250,250);
+}
+
+.superdev:hover {
+    background-color: rgb(100,100,100);
+}
diff --git a/frontend/settings.gradle b/frontend/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..14bee42fc44d0b54cd1651dfeb340025b453c343
--- /dev/null
+++ b/frontend/settings.gradle
@@ -0,0 +1 @@
+include 'desktop', 'android', 'html', 'core'
\ No newline at end of file