diff --git a/source/LoadingState.hx b/source/LoadingState.hx
index 23bce2e68..52a883b77 100644
--- a/source/LoadingState.hx
+++ b/source/LoadingState.hx
@@ -1,39 +1,37 @@
 package;
 
-import lime.app.Promise;
-import lime.app.Future;
 import flixel.FlxG;
-import flixel.FlxState;
 import flixel.FlxSprite;
+import flixel.FlxState;
 import flixel.graphics.frames.FlxAtlasFrames;
 import flixel.util.FlxTimer;
-
-import openfl.utils.Assets;
-import lime.utils.Assets as LimeAssets;
+import haxe.io.Path;
+import lime.app.Future;
+import lime.app.Promise;
 import lime.utils.AssetLibrary;
 import lime.utils.AssetManifest;
-
-import haxe.io.Path;
+import lime.utils.Assets as LimeAssets;
+import openfl.utils.Assets;
 
 class LoadingState extends MusicBeatState
 {
 	inline static var MIN_TIME = 1.0;
-	
+
 	var target:FlxState;
 	var stopMusic = false;
 	var callbacks:MultiCallback;
-	
+
 	var logo:FlxSprite;
 	var gfDance:FlxSprite;
 	var danceLeft = false;
-	
+
 	function new(target:FlxState, stopMusic:Bool)
 	{
 		super();
 		this.target = target;
 		this.stopMusic = stopMusic;
 	}
-	
+
 	override function create()
 	{
 		logo = new FlxSprite(-150, -100);
@@ -52,29 +50,26 @@ class LoadingState extends MusicBeatState
 		gfDance.antialiasing = true;
 		add(gfDance);
 		add(logo);
-		
-		initSongsManifest().onComplete
-		(
-			function (lib)
-			{
-				callbacks = new MultiCallback(onLoad);
-				var introComplete = callbacks.add("introComplete");
-				checkLoadSong(getSongPath());
-				if (PlayState.SONG.needsVoices)
-					checkLoadSong(getVocalPath());
-				checkLibrary("shared");
-				if (PlayState.storyWeek > 0)
-					checkLibrary("week" + PlayState.storyWeek);
-				else
-					checkLibrary("tutorial");
-				
-				var fadeTime = 0.5;
-				FlxG.camera.fade(FlxG.camera.bgColor, fadeTime, true);
-				new FlxTimer().start(fadeTime + MIN_TIME, function(_) introComplete());
-			}
-		);
+
+		initSongsManifest().onComplete(function(lib)
+		{
+			callbacks = new MultiCallback(onLoad);
+			var introComplete = callbacks.add("introComplete");
+			checkLoadSong(getSongPath());
+			if (PlayState.SONG.needsVoices)
+				checkLoadSong(getVocalPath());
+			checkLibrary("shared");
+			if (PlayState.storyWeek > 0)
+				checkLibrary("week" + PlayState.storyWeek);
+			else
+				checkLibrary("tutorial");
+
+			var fadeTime = 0.5;
+			FlxG.camera.fade(FlxG.camera.bgColor, fadeTime, true);
+			new FlxTimer().start(fadeTime + MIN_TIME, function(_) introComplete());
+		});
 	}
-	
+
 	function checkLoadSong(path:String)
 	{
 		if (!Assets.cache.hasSound(path))
@@ -86,10 +81,13 @@ class LoadingState extends MusicBeatState
 			// @:privateAccess
 			// library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]);
 			var callback = callbacks.add("song:" + path);
-			Assets.loadSound(path).onComplete(function (_) { callback(); });
+			Assets.loadSound(path).onComplete(function(_)
+			{
+				callback();
+			});
 		}
 	}
-	
+
 	function checkLibrary(library:String)
 	{
 		trace(Assets.hasLibrary(library));
@@ -98,25 +96,28 @@ class LoadingState extends MusicBeatState
 			@:privateAccess
 			if (!LimeAssets.libraryPaths.exists(library))
 				throw "Missing library: " + library;
-			
+
 			var callback = callbacks.add("library:" + library);
-			Assets.loadLibrary(library).onComplete(function (_) { callback(); });
+			Assets.loadLibrary(library).onComplete(function(_)
+			{
+				callback();
+			});
 		}
 	}
-	
+
 	override function beatHit()
 	{
 		super.beatHit();
-		
+
 		logo.animation.play('bump');
 		danceLeft = !danceLeft;
-		
+
 		if (danceLeft)
 			gfDance.animation.play('danceRight');
 		else
 			gfDance.animation.play('danceLeft');
 	}
-	
+
 	override function update(elapsed:Float)
 	{
 		super.update(elapsed);
@@ -125,30 +126,30 @@ class LoadingState extends MusicBeatState
 			trace('fired: ' + callbacks.getFired() + " unfired:" + callbacks.getUnfired());
 		#end
 	}
-	
+
 	function onLoad()
 	{
 		if (stopMusic && FlxG.sound.music != null)
 			FlxG.sound.music.stop();
-		
+
 		FlxG.switchState(target);
 	}
-	
+
 	static function getSongPath()
 	{
 		return Paths.inst(PlayState.SONG.song);
 	}
-	
+
 	static function getVocalPath()
 	{
 		return Paths.voices(PlayState.SONG.song);
 	}
-	
+
 	inline static public function loadAndSwitchState(target:FlxState, stopMusic = false)
 	{
 		FlxG.switchState(getNextState(target, stopMusic));
 	}
-	
+
 	static function getNextState(target:FlxState, stopMusic = false):FlxState
 	{
 		Paths.setCurrentLevel("week" + PlayState.storyWeek);
@@ -156,35 +157,35 @@ class LoadingState extends MusicBeatState
 		var loaded = isSoundLoaded(getSongPath())
 			&& (!PlayState.SONG.needsVoices || isSoundLoaded(getVocalPath()))
 			&& isLibraryLoaded("shared");
-		
+
 		if (!loaded)
 			return new LoadingState(target, stopMusic);
 		#end
 		if (stopMusic && FlxG.sound.music != null)
 			FlxG.sound.music.stop();
-		
+
 		return target;
 	}
-	
+
 	#if NO_PRELOAD_ALL
 	static function isSoundLoaded(path:String):Bool
 	{
 		return Assets.cache.hasSound(path);
 	}
-	
+
 	static function isLibraryLoaded(library:String):Bool
 	{
 		return Assets.getLibrary(library) != null;
 	}
 	#end
-	
+
 	override function destroy()
 	{
 		super.destroy();
-		
+
 		callbacks = null;
 	}
-	
+
 	static function initSongsManifest()
 	{
 		var id = "songs";
@@ -245,7 +246,7 @@ class LoadingState extends MusicBeatState
 			}
 		}).onError(function(_)
 		{
-			promise.error("There is no asset library with an ID of \"" + id + "\"");
+				promise.error("There is no asset library with an ID of \"" + id + "\"");
 		});
 
 		return promise.future;
@@ -258,33 +259,33 @@ class MultiCallback
 	public var logId:String = null;
 	public var length(default, null) = 0;
 	public var numRemaining(default, null) = 0;
-	
+
 	var unfired = new Map<String, Void->Void>();
 	var fired = new Array<String>();
-	
-	public function new (callback:Void->Void, logId:String = null)
+
+	public function new(callback:Void->Void, logId:String = null)
 	{
 		this.callback = callback;
 		this.logId = logId;
 	}
-	
+
 	public function add(id = "untitled")
 	{
 		id = '$length:$id';
 		length++;
 		numRemaining++;
 		var func:Void->Void = null;
-		func = function ()
+		func = function()
 		{
 			if (unfired.exists(id))
 			{
 				unfired.remove(id);
 				fired.push(id);
 				numRemaining--;
-				
+
 				if (logId != null)
 					log('fired $id, $numRemaining remaining');
-				
+
 				if (numRemaining == 0)
 				{
 					if (logId != null)
@@ -298,13 +299,16 @@ class MultiCallback
 		unfired[id] = func;
 		return func;
 	}
-	
+
 	inline function log(msg):Void
 	{
 		if (logId != null)
 			trace('$logId: $msg');
 	}
-	
-	public function getFired() return fired.copy();
-	public function getUnfired() return [for (id in unfired.keys()) id];
-}
\ No newline at end of file
+
+	public function getFired()
+		return fired.copy();
+
+	public function getUnfired()
+		return [for (id in unfired.keys()) id];
+}
diff --git a/source/ModdingSubstate.hx b/source/ModdingSubstate.hx
new file mode 100644
index 000000000..81f5a358f
--- /dev/null
+++ b/source/ModdingSubstate.hx
@@ -0,0 +1,33 @@
+package;
+
+import flixel.text.FlxText;
+import sys.FileSystem;
+
+class ModdingSubstate extends MusicBeatSubstate
+{
+	public function new():Void
+	{
+		super();
+
+		// var pathShit
+
+		var modList = [];
+
+		for (file in FileSystem.readDirectory('./mods'))
+		{
+			if (FileSystem.isDirectory("./mods/" + file))
+				modList.push(file);
+		}
+
+		trace(modList);
+
+		var loopNum:Int = 0;
+		for (i in modList)
+		{
+			var txt:FlxText = new FlxText(0, 10 + (40 * loopNum), 0, i, 32);
+			add(txt);
+
+			loopNum++;
+		}
+	}
+}
diff --git a/source/OptionsSubState.hx b/source/OptionsSubState.hx
index 2b63e0c2f..67b129c67 100644
--- a/source/OptionsSubState.hx
+++ b/source/OptionsSubState.hx
@@ -19,6 +19,10 @@ class OptionsSubState extends MusicBeatSubstate
 	{
 		super();
 
+		#if desktop
+		textMenuItems.push('Mods');
+		#end
+
 		grpOptionsTexts = new FlxTypedGroup<FlxText>();
 		add(grpOptionsTexts);
 
@@ -64,6 +68,9 @@ class OptionsSubState extends MusicBeatSubstate
 				case "Controls":
 					FlxG.state.closeSubState();
 					FlxG.state.openSubState(new ControlsSubState());
+				case "Mods":
+					FlxG.state.closeSubState();
+					FlxG.state.openSubState(new ModdingSubstate());
 			}
 		}
 	}