diff --git a/README.md b/README.md
index a1932b0fdf..a1f478e39a 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Clone the repository including submodules
 Build and run
 
 - Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included)
-- From command line using `dotnet run --project osu.Desktop --framework netcoreapp2.1`
+- From command line using `dotnet run --project osu.Desktop`
 
 If you run into issues building you may need to restore nuget packages (commonly via `dotnet restore`). Visual Studio Code users must run `Restore` task from debug tab before attempt to build.
 
diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml
index 0247714cdf..6d8d95e773 100644
--- a/appveyor_deploy.yml
+++ b/appveyor_deploy.yml
@@ -16,17 +16,15 @@ build_script:
   - cd osu-deploy
   - nuget restore -verbosity quiet
   - msbuild osu.Desktop.Deploy.csproj
-  - cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu.Desktop.Deploy.exe.config
-  - cd bin\Debug\net471\
-  - osu.Desktop.Deploy.exe %code_signing_password% %APPVEYOR_REPO_TAG_NAME%
+  - cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\netcoreapp2.1\osu.Desktop.Deploy.dll.config
+  - dotnet bin/Debug/netcoreapp2.1/osu.Desktop.Deploy.dll %code_signing_password% %APPVEYOR_REPO_TAG_NAME%
 environment:
-  TargetFramework: net471
   decode_secret:
     secure: i67IC2xj6DjjxmA6Oj2jing3+MwzLkq6CbGsjfZ7rdY=
   code_signing_password:
     secure: 34tLNqvjmmZEi97MLKfrnQ==
 artifacts:
-  - path: 'Releases\*'
+  - path: 'osu-deploy/releases/*'
 deploy:
   - provider: Environment
     name: github
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
index 2a82d65014..da9344b6a2 100644
--- a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
@@ -2,35 +2,7 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "VisualTests (Debug, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Catch.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Release, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Catch.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Debug, netcoreapp2.1)",
+            "name": "VisualTests (Debug)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -38,12 +10,12 @@
                 "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, dotnet)",
+            "preLaunchTask": "Build (Debug)",
             "env": {},
             "console": "internalConsole"
         },
         {
-            "name": "VisualTests (Release, netcoreapp2.1)",
+            "name": "VisualTests (Release)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -51,7 +23,7 @@
                 "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, dotnet)",
+            "preLaunchTask": "Build (Release)",
             "env": {},
             "console": "internalConsole"
         }
diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json
index 6c6d562512..18a6f8ca70 100644
--- a/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json
+++ b/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json
@@ -4,43 +4,13 @@
     "version": "2.0.0",
     "tasks": [
         {
-            "label": "Build (Debug, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Catch.Tests.csproj",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Release, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Catch.Tests.csproj",
-                "/p:Configuration=Release",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Debug, dotnet)",
+            "label": "Build (Debug)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Catch.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:GenerateFullPaths=true",
                 "/m",
                 "/verbosity:m"
@@ -49,14 +19,13 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Build (Release, dotnet)",
+            "label": "Build (Release)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Catch.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:Configuration=Release",
                 "/p:GenerateFullPaths=true",
                 "/m",
@@ -66,16 +35,7 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Restore (net471)",
-            "type": "shell",
-            "command": "nuget",
-            "args": [
-                "restore"
-            ],
-            "problemMatcher": []
-        },
-        {
-            "label": "Restore (netcoreapp2.1)",
+            "label": "Restore",
             "type": "shell",
             "command": "dotnet",
             "args": [
diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
index bc41d4ccf9..c781b0e64e 100644
--- a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
@@ -2,35 +2,7 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "VisualTests (Debug, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Mania.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Release, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Mania.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Debug, netcoreapp2.1)",
+            "name": "VisualTests (Debug)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -38,12 +10,12 @@
                 "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, dotnet)",
+            "preLaunchTask": "Build (Debug)",
             "env": {},
             "console": "internalConsole"
         },
         {
-            "name": "VisualTests (Release, netcoreapp2.1)",
+            "name": "VisualTests (Release)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -51,7 +23,7 @@
                 "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, dotnet)",
+            "preLaunchTask": "Build (Release)",
             "env": {},
             "console": "internalConsole"
         }
diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json
index 7fc2f7b2ef..608c4340ac 100644
--- a/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json
+++ b/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json
@@ -4,43 +4,13 @@
     "version": "2.0.0",
     "tasks": [
         {
-            "label": "Build (Debug, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Mania.Tests.csproj",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Release, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Mania.Tests.csproj",
-                "/p:Configuration=Release",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Debug, dotnet)",
+            "label": "Build (Debug)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Mania.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:GenerateFullPaths=true",
                 "/m",
                 "/verbosity:m"
@@ -49,14 +19,13 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Build (Release, dotnet)",
+            "label": "Build (Release)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Mania.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:Configuration=Release",
                 "/p:GenerateFullPaths=true",
                 "/m",
@@ -66,16 +35,7 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Restore (net471)",
-            "type": "shell",
-            "command": "nuget",
-            "args": [
-                "restore"
-            ],
-            "problemMatcher": []
-        },
-        {
-            "label": "Restore (netcoreapp2.1)",
+            "label": "Restore",
             "type": "shell",
             "command": "dotnet",
             "args": [
diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
index 13aba025fd..fe3ecbec47 100644
--- a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
@@ -2,35 +2,7 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "VisualTests (Debug, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Osu.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Release, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Osu.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Debug, netcoreapp2.1)",
+            "name": "VisualTests (Debug)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -38,12 +10,12 @@
                 "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, dotnet)",
+            "preLaunchTask": "Build (Debug)",
             "env": {},
             "console": "internalConsole"
         },
         {
-            "name": "VisualTests (Release, netcoreapp2.1)",
+            "name": "VisualTests (Release)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -51,7 +23,7 @@
                 "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, dotnet)",
+            "preLaunchTask": "Build (Release)",
             "env": {},
             "console": "internalConsole"
         }
diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json
index 62cf51382f..ed2a015e11 100644
--- a/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json
+++ b/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json
@@ -4,43 +4,13 @@
     "version": "2.0.0",
     "tasks": [
         {
-            "label": "Build (Debug, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Osu.Tests.csproj",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Release, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Osu.Tests.csproj",
-                "/p:Configuration=Release",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Debug, dotnet)",
+            "label": "Build (Debug)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Osu.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:GenerateFullPaths=true",
                 "/m",
                 "/verbosity:m"
@@ -49,14 +19,13 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Build (Release, dotnet)",
+            "label": "Build (Release)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Osu.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:Configuration=Release",
                 "/p:GenerateFullPaths=true",
                 "/m",
@@ -66,16 +35,7 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Restore (net471)",
-            "type": "shell",
-            "command": "nuget",
-            "args": [
-                "restore"
-            ],
-            "problemMatcher": []
-        },
-        {
-            "label": "Restore (netcoreapp2.1)",
+            "label": "Restore",
             "type": "shell",
             "command": "dotnet",
             "args": [
diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json
index df49e177dc..de7bf77070 100644
--- a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json
@@ -2,35 +2,7 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "VisualTests (Debug, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Taiko.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Release, net471)",
-            "windows": {
-                "type": "clr"
-            },
-            "type": "mono",
-            "request": "launch",
-            "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Taiko.Tests.exe",
-            "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, msbuild)",
-            "runtimeExecutable": null,
-            "env": {},
-            "console": "internalConsole"
-        },
-        {
-            "name": "VisualTests (Debug, netcoreapp2.1)",
+            "name": "VisualTests (Debug)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -38,12 +10,12 @@
                 "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Debug, dotnet)",
+            "preLaunchTask": "Build (Debug)",
             "env": {},
             "console": "internalConsole"
         },
         {
-            "name": "VisualTests (Release, netcoreapp2.1)",
+            "name": "VisualTests (Release)",
             "type": "coreclr",
             "request": "launch",
             "program": "dotnet",
@@ -51,7 +23,7 @@
                 "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll"
             ],
             "cwd": "${workspaceRoot}",
-            "preLaunchTask": "Build (Release, dotnet)",
+            "preLaunchTask": "Build (Release)",
             "env": {},
             "console": "internalConsole"
         }
diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json
index 7c8beed00f..9b91f2c9b9 100644
--- a/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json
+++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json
@@ -4,43 +4,13 @@
     "version": "2.0.0",
     "tasks": [
         {
-            "label": "Build (Debug, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Taiko.Tests.csproj",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Release, msbuild)",
-            "type": "shell",
-            "command": "msbuild",
-            "args": [
-                "osu.Game.Rulesets.Taiko.Tests.csproj",
-                "/p:Configuration=Release",
-                "/p:TargetFramework=net471",
-                "/p:GenerateFullPaths=true",
-                "/m",
-                "/verbosity:m"
-            ],
-            "group": "build",
-            "problemMatcher": "$msCompile"
-        },
-        {
-            "label": "Build (Debug, dotnet)",
+            "label": "Build (Debug)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Taiko.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:GenerateFullPaths=true",
                 "/m",
                 "/verbosity:m"
@@ -49,14 +19,13 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Build (Release, dotnet)",
+            "label": "Build (Release)",
             "type": "shell",
             "command": "dotnet",
             "args": [
                 "build",
                 "--no-restore",
                 "osu.Game.Rulesets.Taiko.Tests.csproj",
-                "/p:TargetFramework=netcoreapp2.1",
                 "/p:Configuration=Release",
                 "/p:GenerateFullPaths=true",
                 "/m",
@@ -66,16 +35,7 @@
             "problemMatcher": "$msCompile"
         },
         {
-            "label": "Restore (net471)",
-            "type": "shell",
-            "command": "nuget",
-            "args": [
-                "restore"
-            ],
-            "problemMatcher": []
-        },
-        {
-            "label": "Restore (netcoreapp2.1)",
+            "label": "Restore",
             "type": "shell",
             "command": "dotnet",
             "args": [