diff --git a/Project.xml b/Project.xml
index 8ba14e7dc..db338d32a 100644
--- a/Project.xml
+++ b/Project.xml
@@ -45,6 +45,7 @@
 		<library name="week6" preload="true" />
 		<library name="week7" preload="true" />
 		<library name="weekend1" preload="true" />
+		<library name="videos" preload="true" />
 	</section>
 	<section if="NO_PRELOAD_ALL">
 		<library name="songs" preload="false" />
@@ -58,10 +59,13 @@
 		<library name="week6" preload="false" />
 		<library name="week7" preload="false" />
 		<library name="weekend1" preload="false" />
+		<library name="videos" preload="false" />
 	</section>
 	<library name="art" preload="false" />
 	<assets path="assets/songs" library="songs" exclude="*.fla|*.ogg|*.wav" if="web" />
 	<assets path="assets/songs" library="songs" exclude="*.fla|*.mp3|*.wav" unless="web" />
+	<!-- Videos go in their own library because web never needs to preload them, they can just be streamed. -->
+	<assets path="assets/videos" library="videos" />
 	<assets path="assets/shared" library="shared" exclude="*.fla|*.ogg|*.wav" if="web" />
 	<assets path="assets/shared" library="shared" exclude="*.fla|*.mp3|*.wav" unless="web" />
 	<assets path="assets/tutorial" library="tutorial" exclude="*.fla|*.ogg|*.wav" if="web" />
diff --git a/assets b/assets
index bef67ec4b..0782d868b 160000
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit bef67ec4b3c834416e73ce4e7c3e7128c5d7de63
+Subproject commit 0782d868ba8379d699ef9ab9547c3507580628e2
diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx
index fd4ef76fa..54a4b7acf 100644
--- a/source/funkin/Paths.hx
+++ b/source/funkin/Paths.hx
@@ -113,7 +113,7 @@ class Paths
 
   public static function videos(key:String, ?library:String):String
   {
-    return getPath('videos/$key.${Constants.EXT_VIDEO}', BINARY, library);
+    return getPath('videos/$key.${Constants.EXT_VIDEO}', BINARY, library ?? 'videos');
   }
 
   public static function voices(song:String, ?suffix:String = ''):String
diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx
index 78f660d3f..62860ee0f 100644
--- a/source/funkin/modding/PolymodHandler.hx
+++ b/source/funkin/modding/PolymodHandler.hx
@@ -240,8 +240,8 @@ class PolymodHandler
   {
     return {
       assetLibraryPaths: [
-        'default' => 'preload', 'shared' => 'shared', 'songs' => 'songs', 'tutorial' => 'tutorial', 'week1' => 'week1',      'week2' => 'week2',
-            'week3' => 'week3',   'week4' => 'week4', 'week5' => 'week5',       'week6' => 'week6', 'week7' => 'week7', 'weekend1' => 'weekend1',
+        'default' => 'preload', 'shared' => 'shared', 'songs' => 'songs', 'videos' => 'videos', 'tutorial' => 'tutorial', 'week1' => 'week1',
+        'week2' => 'week2', 'week3' => 'week3', 'week4' => 'week4', 'week5' => 'week5', 'week6' => 'week6', 'week7' => 'week7', 'weekend1' => 'weekend1',
       ],
       coreAssetRedirect: CORE_FOLDER,
     }
diff --git a/source/funkin/play/cutscene/VideoCutscene.hx b/source/funkin/play/cutscene/VideoCutscene.hx
index 0c05bc876..0939dae38 100644
--- a/source/funkin/play/cutscene/VideoCutscene.hx
+++ b/source/funkin/play/cutscene/VideoCutscene.hx
@@ -67,8 +67,13 @@ class VideoCutscene
     if (!openfl.Assets.exists(filePath))
     {
       // Display a popup.
-      lime.app.Application.current.window.alert('Video file does not exist: ${filePath}', 'Error playing video');
-      return;
+      // lime.app.Application.current.window.alert('Video file does not exist: ${filePath}', 'Error playing video');
+      // return;
+
+      // TODO: After moving videos to their own library,
+      // this function ALWAYS FAILS on web, but the video still plays.
+      // I think that's due to a weird quirk with how OpenFL libraries work.
+      trace('Video file does not exist: ${filePath}');
     }
 
     var rawFilePath = Paths.stripLibrary(filePath);
diff --git a/source/funkin/ui/credits/CreditsDataHandler.hx b/source/funkin/ui/credits/CreditsDataHandler.hx
index 86afdafd1..628a9f893 100644
--- a/source/funkin/ui/credits/CreditsDataHandler.hx
+++ b/source/funkin/ui/credits/CreditsDataHandler.hx
@@ -99,12 +99,19 @@ class CreditsDataHandler
 
   static function fetchCreditsData():funkin.data.JsonFile
   {
+    #if !macro
     var rawJson:String = openfl.Assets.getText(CREDITS_DATA_PATH).trim();
 
     return {
       fileName: CREDITS_DATA_PATH,
       contents: rawJson
     };
+    #else
+    return {
+      fileName: CREDITS_DATA_PATH,
+      contents: null
+    };
+    #end
   }
 
   static function parseCreditsData(file:JsonFile):Null<CreditsData>
diff --git a/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx b/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx
index cd403c6f8..98f5a47aa 100644
--- a/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx
+++ b/source/funkin/ui/debug/charting/components/ChartEditorNoteSprite.hx
@@ -117,12 +117,6 @@ class ChartEditorNoteSprite extends FlxSprite
     {
       noteFrameCollection.pushFrame(frame);
     }
-    var frameCollectionNormal2:FlxAtlasFrames = Paths.getSparrowAtlas('NoteHoldNormal');
-
-    for (frame in frameCollectionNormal2.frames)
-    {
-      noteFrameCollection.pushFrame(frame);
-    }
 
     // Pixel notes
     var graphicPixel = FlxG.bitmap.add(Paths.image('weeb/pixelUI/arrows-pixels', 'week6'), false, null);
diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx
index 189e04973..6b963a242 100644
--- a/source/funkin/ui/freeplay/AlbumRoll.hx
+++ b/source/funkin/ui/freeplay/AlbumRoll.hx
@@ -37,8 +37,8 @@ class AlbumRoll extends FlxSpriteGroup
   }
 
   var newAlbumArt:FlxAtlasSprite;
-  var difficultyStars:DifficultyStars;
 
+  // var difficultyStars:DifficultyStars;
   var _exitMovers:Null<FreeplayState.ExitMoverData>;
 
   var albumData:Album;
@@ -65,9 +65,9 @@ class AlbumRoll extends FlxSpriteGroup
 
     add(newAlbumArt);
 
-    difficultyStars = new DifficultyStars(140, 39);
-    difficultyStars.stars.visible = false;
-    add(difficultyStars);
+    // difficultyStars = new DifficultyStars(140, 39);
+    // difficultyStars.stars.visible = false;
+    // add(difficultyStars);
   }
 
   function onAlbumFinish(animName:String):Void
@@ -86,7 +86,7 @@ class AlbumRoll extends FlxSpriteGroup
   {
     if (albumId == null)
     {
-      difficultyStars.stars.visible = false;
+      // difficultyStars.stars.visible = false;
       return;
     }
 
@@ -132,13 +132,6 @@ class AlbumRoll extends FlxSpriteGroup
         speed: 0.4,
         wait: 0
       });
-
-    exitMovers.set([difficultyStars],
-      {
-        x: FlxG.width * 1.2,
-        speed: 0.2,
-        wait: 0.3
-      });
   }
 
   var titleTimer:Null<FlxTimer> = null;
@@ -151,10 +144,10 @@ class AlbumRoll extends FlxSpriteGroup
     newAlbumArt.visible = true;
     newAlbumArt.playAnimation(animNames.get('$albumId-active'), false, false, false);
 
-    difficultyStars.stars.visible = false;
+    // difficultyStars.stars.visible = false;
     new FlxTimer().start(0.75, function(_) {
       // showTitle();
-      showStars();
+      // showStars();
     });
   }
 
@@ -163,18 +156,16 @@ class AlbumRoll extends FlxSpriteGroup
     newAlbumArt.playAnimation(animNames.get('$albumId-trans'), false, false, false);
   }
 
-  public function setDifficultyStars(?difficulty:Int):Void
-  {
-    if (difficulty == null) return;
-
-    difficultyStars.difficulty = difficulty;
-  }
-
-  /**
-   * Make the album stars visible.
-   */
-  public function showStars():Void
-  {
-    difficultyStars.stars.visible = false; // true;
-  }
+  // public function setDifficultyStars(?difficulty:Int):Void
+  // {
+  //   if (difficulty == null) return;
+  //   difficultyStars.difficulty = difficulty;
+  // }
+  // /**
+  //  * Make the album stars visible.
+  //  */
+  // public function showStars():Void
+  // {
+  //   difficultyStars.stars.visible = false; // true;
+  // }
 }
diff --git a/source/funkin/ui/freeplay/DifficultyStars.hx b/source/funkin/ui/freeplay/DifficultyStars.hx
deleted file mode 100644
index 51526bcbe..000000000
--- a/source/funkin/ui/freeplay/DifficultyStars.hx
+++ /dev/null
@@ -1,106 +0,0 @@
-package funkin.ui.freeplay;
-
-import flixel.group.FlxSpriteGroup;
-import funkin.graphics.adobeanimate.FlxAtlasSprite;
-import funkin.graphics.shaders.HSVShader;
-
-class DifficultyStars extends FlxSpriteGroup
-{
-  /**
-   * Internal handler var for difficulty... ranges from 0... to 15
-   * 0 is 1 star... 15 is 0 stars!
-   */
-  var curDifficulty(default, set):Int = 0;
-
-  /**
-   * Range between 0 and 15
-   */
-  public var difficulty(default, set):Int = 1;
-
-  public var stars:FlxAtlasSprite;
-
-  var flames:FreeplayFlames;
-
-  var hsvShader:HSVShader;
-
-  public function new(x:Float, y:Float)
-  {
-    super(x, y);
-
-    hsvShader = new HSVShader();
-
-    flames = new FreeplayFlames(0, 0);
-    add(flames);
-
-    stars = new FlxAtlasSprite(0, 0, Paths.animateAtlas("freeplay/freeplayStars"));
-    stars.anim.play("diff stars");
-    add(stars);
-
-    stars.shader = hsvShader;
-
-    for (memb in flames.members)
-      memb.shader = hsvShader;
-  }
-
-  override function update(elapsed:Float):Void
-  {
-    super.update(elapsed);
-
-    // "loops" the current animation
-    // for clarity, the animation file looks like
-    // frame : stars
-    // 0-99: 1 star
-    // 100-199: 2 stars
-    // ......
-    // 1300-1499: 15 stars
-    // 1500 : 0 stars
-    if (curDifficulty < 15 && stars.anim.curFrame >= (curDifficulty + 1) * 100)
-    {
-      stars.anim.play("diff stars", true, false, curDifficulty * 100);
-    }
-  }
-
-  function set_difficulty(value:Int):Int
-  {
-    difficulty = value;
-
-    if (difficulty <= 0)
-    {
-      difficulty = 0;
-      curDifficulty = 15;
-    }
-    else if (difficulty <= 15)
-    {
-      difficulty = value;
-      curDifficulty = difficulty - 1;
-    }
-    else
-    {
-      difficulty = 15;
-      curDifficulty = difficulty - 1;
-    }
-
-    if (difficulty > 10) flames.flameCount = difficulty - 10;
-    else
-      flames.flameCount = 0;
-
-    return difficulty;
-  }
-
-  function set_curDifficulty(value:Int):Int
-  {
-    curDifficulty = value;
-    if (curDifficulty == 15)
-    {
-      stars.anim.play("diff stars", true, false, 1500);
-      stars.anim.pause();
-    }
-    else
-    {
-      stars.anim.curFrame = Std.int(curDifficulty * 100);
-      stars.anim.play("diff stars", true, false, curDifficulty * 100);
-    }
-
-    return curDifficulty;
-  }
-}
diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx
index dc1f164ea..ae51ba82a 100644
--- a/source/funkin/ui/freeplay/FreeplayState.hx
+++ b/source/funkin/ui/freeplay/FreeplayState.hx
@@ -469,6 +469,10 @@ class FreeplayState extends MusicBeatSubState
 
       albumRoll.playIntro();
 
+      new FlxTimer().start(0.75, function(_) {
+        // albumRoll.showTitle();
+      });
+
       FlxTween.tween(grpDifficulties, {x: 90}, 0.6, {ease: FlxEase.quartOut});
 
       var diffSelLeft:DifficultySelector = new DifficultySelector(20, grpDifficulties.y - 10, false, controls);
@@ -1039,9 +1043,6 @@ class FreeplayState extends MusicBeatSubState
       }
     }
 
-    // Set the difficulty star count on the right.
-    albumRoll.setDifficultyStars(daSong?.songRating);
-
     // Set the album graphic and play the animation if relevant.
     var newAlbumId:String = daSong?.albumId;
     if (albumRoll.albumId != newAlbumId)
@@ -1161,10 +1162,6 @@ class FreeplayState extends MusicBeatSubState
     {
       currentDifficulty = rememberedDifficulty;
     }
-
-    // Set the difficulty star count on the right.
-    var daSong:Null<FreeplaySongData> = grpCapsules.members[curSelected]?.songData;
-    albumRoll.setDifficultyStars(daSong?.songRating ?? 0);
   }
 
   function changeSelection(change:Int = 0):Void
diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx
index ecd67b4da..3bdc2dfe6 100644
--- a/source/funkin/ui/mainmenu/MainMenuState.hx
+++ b/source/funkin/ui/mainmenu/MainMenuState.hx
@@ -1,5 +1,6 @@
 package funkin.ui.mainmenu;
 
+import funkin.graphics.FunkinSprite;
 import flixel.addons.transition.FlxTransitionableState;
 import funkin.ui.debug.DebugMenuSubState;
 import flixel.FlxObject;
@@ -56,7 +57,8 @@ class MainMenuState extends MusicBeatState
     persistentUpdate = false;
     persistentDraw = true;
 
-    var bg:FlxSprite = new FlxSprite(Paths.image('menuBG'));
+    var bg = FunkinSprite.create('menuDesat');
+    bg.color = 0xFFFDE871;
     bg.scrollFactor.x = 0;
     bg.scrollFactor.y = 0.17;
     bg.setGraphicSize(Std.int(bg.width * 1.2));