diff --git a/vsproject.py b/vsproject.py
new file mode 100644
index 000000000..9ee1d0143
--- /dev/null
+++ b/vsproject.py
@@ -0,0 +1,323 @@
+import os
+import uuid
+
+cl_compile = []
+cl_include = []
+source_dirs = set()
+for root, subdirs, files in os.walk('src'):
+ for file in [os.path.join(root, f) for f in files]:
+ lowerfile = file.lower()
+ if lowerfile.endswith('.cpp') or lowerfile.endswith('.c'):
+ cl_compile.append(file)
+ source_dirs.add(os.path.dirname(file))
+ if lowerfile.endswith('.hpp') or lowerfile.endswith('.h'):
+ cl_include.append(file)
+ source_dirs.add(os.path.dirname(file))
+
+sln = open('The-Powder-Toy.sln', 'w')
+sln.write(r"""
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "The-Powder-Toy", "The-Powder-Toy.vcxproj", "{57F7954F-6975-4DEE-8C4F-F9B083E05985}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Static|Win32 = Static|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Debug|Win32.ActiveCfg = Debug|Win32
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Debug|Win32.Build.0 = Debug|Win32
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Release|Win32.ActiveCfg = Release|Win32
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Release|Win32.Build.0 = Release|Win32
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Static|Win32.ActiveCfg = Static|Win32
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}.Static|Win32.Build.0 = Static|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
+""")
+sln.close()
+
+vcxproj = open('The-Powder-Toy.vcxproj', 'w')
+vcxproj.write(r"""
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Static
+ Win32
+
+
+
+ {57F7954F-6975-4DEE-8C4F-F9B083E05985}
+ Win32Proj
+ 10.0.17763.0
+
+
+
+ Application
+ true
+ v141
+
+
+ Application
+ false
+ v141
+
+
+ Application
+ false
+ v141
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ $(SolutionDir)Build\
+ Powder
+ $(ProjectDir)includes;$(ProjectDir)includes/SDL2;$(ProjectDir)includes/luajit-2.0;$(ProjectDir)data;$(ProjectDir)src;$(ProjectDir)generated;$(ProjectDir)resources;$(IncludePath)
+ $(ProjectDir)Libraries;$(LibraryPath)
+
+
+ false
+ $(SolutionDir)Build\
+ Powder
+ $(ProjectDir)includes;$(ProjectDir)includes/SDL2;$(ProjectDir)includes/luajit-2.0;$(ProjectDir)data;$(ProjectDir)src;$(ProjectDir)generated;$(ProjectDir)resources;$(IncludePath)
+ $(ProjectDir)Libraries;$(LibraryPath)
+
+
+ false
+ $(SolutionDir)Build\
+ Powder
+ $(ProjectDir)includes;$(ProjectDir)includes/SDL2;$(ProjectDir)includes/luajit-2.0;$(ProjectDir)data;$(ProjectDir)src;$(ProjectDir)generated;$(ProjectDir)resources;$(IncludePath)
+ $(ProjectDir)Staticlibs;$(LibraryPath)
+
+
+
+ WIN;X86;X86_SSE2;USE_SDL;STABLE;GRAVFFT;LUACONSOLE;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebugDLL
+ Level1
+ ProgramDatabase
+ Disabled
+ Fast
+ true
+
+
+ MachineX86
+ true
+ Windows
+ SDL2.lib;SDL2main.lib;shell32.lib;libbz2.lib;pthreadVC2.lib;luajit2.0.lib;libfftw3f-3.lib;zlib.lib;libcurl.lib;ws2_32.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN;X86;X86_SSE2;USE_SDL;STABLE;GRAVFFT;LUACONSOLE;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+ Level1
+ ProgramDatabase
+ Fast
+ true
+ StreamingSIMDExtensions2
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+ SDL2.lib;SDL2main.lib;shell32.lib;libbz2.lib;pthreadVC2.lib;luajit2.0.lib;libfftw3f-3.lib;zlib.lib;libcurl.lib;ws2_32.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN;X86;X86_SSE2;USE_SDL;STABLE;GRAVFFT;LUACONSOLE;ZLIB_WINAPI;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;PTW32_STATIC_LIB;CURL_STATICLIB;%(PreprocessorDefinitions)
+ MultiThreaded
+ Level1
+ ProgramDatabase
+ Fast
+ true
+ StreamingSIMDExtensions2
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+ SDL2.lib;SDL2main.lib;shell32.lib;libbz2.lib;pthreadVC2.lib;luajit2.0.lib;libfftw3f-3.lib;zlib.lib;libcurl.lib;ws2_32.lib;Wldap32.lib;crypt32.lib;winmm.lib;dxguid.lib;imm32.lib;version.lib;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+ false
+
+
+
+
+
+
+
+
+
+""")
+vcxproj.write(''.join([('') for p in cl_compile]))
+vcxproj.write(r"""
+
+
+
+
+
+
+
+
+
+
+
+
+""")
+vcxproj.write(''.join([('') for p in cl_include]))
+vcxproj.write(r"""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""")
+vcxproj.close()
+
+filters = open('The-Powder-Toy.vcxproj.filters', 'w')
+filters.write(r"""
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+ {fc5911e1-d5ba-4da3-9cfa-5631c6914487}
+
+
+ {bfb47e29-68f3-48bd-86c2-46b9f63d2597}
+
+""")
+filters.write(''.join([('{' + str(uuid.uuid4()) + '}') for p in source_dirs]))
+filters.write(r"""
+
+
+
+ generated
+
+
+ generated
+
+""")
+filters.write(''.join([('' + os.path.dirname(p) + '') for p in cl_compile]))
+filters.write(r"""
+
+
+
+ generated
+
+
+ generated
+
+
+ src\simulation
+
+
+ data
+
+
+ data
+
+
+ data
+
+
+ data
+
+
+ data
+
+
+ data
+
+
+ data
+
+""")
+filters.write(''.join([('' + os.path.dirname(p) + '') for p in cl_include]))
+filters.write(r"""
+
+ resources
+
+
+
+
+ resources
+
+
+
+
+ src\graphics
+
+
+ src\graphics
+
+
+ src\graphics
+
+
+
+
+
+
+
+
+ src\lua\socket
+
+
+
+""")
+filters.close()