diff --git a/.github/actions/setup-haxeshit/action.yml b/.github/actions/setup-haxeshit/action.yml
index 21fab6fb2..bf81e0d6d 100644
--- a/.github/actions/setup-haxeshit/action.yml
+++ b/.github/actions/setup-haxeshit/action.yml
@@ -10,11 +10,19 @@ runs:
         run: |
           haxelib config
         shell: bash
+      - name: Restore/create existing haxelib cache for faster downloads
+        uses: actions/cache@v3
+        id: cache-haxelib-windows
+        with:
+          # wha?
+          key: cache-haxelib-${{ runner.os }}-${{ hashFiles('**/hmm.json')}}
+          path: |
+            .haxelib/
       - name: Installing Haxe lol
         run: |
           haxe -version
           haxelib git haxelib https://github.com/HaxeFoundation/haxelib.git
           haxelib version
           haxelib --global install hmm
-          haxelib --global run hmm install --quiet
+          haxelib --global run hmm install
         shell: bash
diff --git a/.github/workflows/build-shit.yml b/.github/workflows/build-shit.yml
index 7115f2f6d..35d436b2c 100644
--- a/.github/workflows/build-shit.yml
+++ b/.github/workflows/build-shit.yml
@@ -2,7 +2,7 @@ name: build-upload
 on:
   workflow_dispatch:
   push:
-  
+
 jobs:
   check_date:
     runs-on: ubuntu-latest
@@ -44,18 +44,6 @@ jobs:
        actions: write
     steps:
       - uses: actions/checkout@v3
-      - name: Restore existing build cache for faster compilation
-        uses: actions/cache/restore@v3
-        id: cache-windows-shit
-        with:
-          # wha?
-          key: cache-build-win
-          path: |
-            .haxelib/
-            export/debug/windows/haxe/
-            export/debug/windows/obj/
-          restore-keys: |
-            cache-build-windows
       - uses: ./.github/actions/setup-haxeshit
       - name: Build game
         run: |
@@ -66,33 +54,3 @@ jobs:
           butler-key: ${{ secrets.BUTLER_API_KEY}}
           build-dir: export/debug/windows/bin
           target: win
-      - name: Clearing already existing cache
-        uses: actions/github-script@v6
-        with:
-          script: |
-            const caches = await github.rest.actions.getActionsCacheList({
-              owner: context.repo.owner,
-              repo: context.repo.repo,
-            })
-            for (const cache of caches.data.actions_caches) {
-              if (cache.key == "cache-build-windows") {
-                console.log('Clearing ' + cache.key + '...')
-                await github.rest.actions.deleteActionsCacheById({
-                  owner: context.repo.owner,
-                  repo: context.repo.repo,
-                  cache_id: cache.id,
-                })
-                console.log("Cache cleared.")
-              }
-            }
-      - name: Uploading new cache
-        uses: actions/cache/save@v3
-        with:
-          # caching again since for some reason it doesnt work with the first post cache shit
-          key: cache-build-windows
-          path: |
-            .haxelib/
-            export/debug/windows/haxe/
-            export/debug/windows/obj/
-          restore-keys: |
-            cache-build-windows
diff --git a/hmm.json b/hmm.json
index f45a94b08..dc403a5ab 100644
--- a/hmm.json
+++ b/hmm.json
@@ -68,8 +68,8 @@
       "name": "hxCodec",
       "type": "git",
       "dir": null,
-      "ref": "c42ab99",
-      "url": "https://github.com/polybiusproxy/hxCodec"
+      "ref": "a56f4b4",
+      "url": "https://github.com/FunkinCrew/hxCodec"
     },
     {
       "name": "hxcpp",
diff --git a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx
index aad9cd851..1c120a7c7 100644
--- a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx
+++ b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx
@@ -16,7 +16,7 @@ class FlxAtlasSprite extends FlxAnimate
       FrameRate: 24.0,
       Reversed: false,
       // ?OnComplete:Void -> Void,
-      ShowPivot: #if debug true #else false #end,
+      ShowPivot: #if debug false #else false #end,
       Antialiasing: true,
       ScrollFactor: new FlxPoint(1, 1),
       // Offset: new FlxPoint(0, 0), // This is just FlxSprite.offset
diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx
index 140a4fbc8..7c39cef56 100644
--- a/source/funkin/play/GameOverSubState.hx
+++ b/source/funkin/play/GameOverSubState.hx
@@ -1,5 +1,6 @@
 package funkin.play;
 
+import flixel.FlxG;
 import flixel.FlxObject;
 import flixel.FlxSprite;
 import flixel.system.FlxSound;
@@ -97,7 +98,6 @@ class GameOverSubState extends MusicBeatSubState
     boyfriend.isDead = true;
     add(boyfriend);
     boyfriend.resetCharacter();
-    boyfriend.playAnimation('firstDeath', true, true);
 
     // Assign a camera follow point to the boyfriend's position.
     cameraFollowPoint = new FlxObject(PlayState.instance.cameraFollowPoint.x, PlayState.instance.cameraFollowPoint.y, 1, 1);
@@ -118,15 +118,30 @@ class GameOverSubState extends MusicBeatSubState
 
     // The conductor now represents the BPM of the game over music.
     Conductor.songPosition = 0;
-
-    // Play the "blue balled" sound. May play a variant if one has been assigned.
-    playBlueBalledSFX();
   }
 
+  var hasStartedAnimation:Bool = false;
+
   override function update(elapsed:Float)
   {
     super.update(elapsed);
 
+    if (!hasStartedAnimation)
+    {
+      hasStartedAnimation = true;
+
+      if (boyfriend.hasAnimation('fakeoutDeath') && FlxG.random.bool((1 / 4096) * 100))
+      {
+        boyfriend.playAnimation('fakeoutDeath', true, true);
+      }
+      else
+      {
+        boyfriend.playAnimation('firstDeath', true, true);
+        // Play the "blue balled" sound. May play a variant if one has been assigned.
+        playBlueBalledSFX();
+      }
+    }
+
     //
     // Handle user inputs.
     //
@@ -145,14 +160,18 @@ class GameOverSubState extends MusicBeatSubState
     }
 
     // KEYBOARD ONLY: Restart the level when pressing the assigned key.
-    if (controls.ACCEPT)
+    if (controls.ACCEPT && blueballed)
     {
+      blueballed = false;
       confirmDeath();
     }
 
     // KEYBOARD ONLY: Return to the menu when pressing the assigned key.
     if (controls.BACK)
     {
+      blueballed = false;
+      PlayState.instance.deathCounter = 0;
+      // PlayState.seenCutscene = false; // old thing...
       gameOverMusic.stop();
 
       if (PlayStatePlaylist.isStoryMode) FlxG.switchState(new StoryMenuState());
@@ -252,12 +271,15 @@ class GameOverSubState extends MusicBeatSubState
     }
   }
 
+  static var blueballed:Bool = false;
+
   /**
    * Play the sound effect that occurs when
    * boyfriend's testicles get utterly annihilated.
    */
-  function playBlueBalledSFX()
+  public static function playBlueBalledSFX()
   {
+    blueballed = true;
     FlxG.sound.play(Paths.sound('fnf_loss_sfx' + blueBallSuffix));
   }
 
diff --git a/source/funkin/ui/story/Level.hx b/source/funkin/ui/story/Level.hx
index 3ff0a5321..83682fec9 100644
--- a/source/funkin/ui/story/Level.hx
+++ b/source/funkin/ui/story/Level.hx
@@ -156,7 +156,10 @@ class Level implements IRegistryEntry<LevelData>
     for (propIndex in 0..._data.props.length)
     {
       var propData = _data.props[propIndex];
-      var propSprite:LevelProp = LevelProp.build(propData);
+
+      var propSprite:Null<LevelProp> = LevelProp.build(propData);
+      if (propSprite == null) continue;
+
       propSprite.x += FlxG.width * 0.25 * propIndex;
       props.push(propSprite);
     }
diff --git a/source/funkin/ui/story/LevelProp.hx b/source/funkin/ui/story/LevelProp.hx
index a474b363c..4dce7bfb3 100644
--- a/source/funkin/ui/story/LevelProp.hx
+++ b/source/funkin/ui/story/LevelProp.hx
@@ -16,8 +16,10 @@ class LevelProp extends Bopper
     playAnimation('confirm', true, true);
   }
 
-  public static function build(propData:LevelPropData):Null<LevelProp>
+  public static function build(propData:Null<LevelPropData>):Null<LevelProp>
   {
+    if (propData == null) return null;
+
     var isAnimated:Bool = propData.animations.length > 0;
     var prop:LevelProp = new LevelProp(propData.danceEvery);
 
diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx
index b61f1bdee..1dc59f3ec 100644
--- a/source/funkin/ui/story/StoryMenuState.hx
+++ b/source/funkin/ui/story/StoryMenuState.hx
@@ -52,6 +52,11 @@ class StoryMenuState extends MusicBeatState
    */
   var scoreText:FlxText;
 
+  /**
+   * The mode text at the top-middle.
+   */
+  var modeText:FlxText;
+
   /**
    * The list of songs on the left.
    */
@@ -146,16 +151,22 @@ class StoryMenuState extends MusicBeatState
 
     updateProps();
 
-    scoreText = new FlxText(10, 10, 0, 'HIGH SCORE: 42069420');
-    scoreText.setFormat("VCR OSD Mono", 32);
-    add(scoreText);
-
     tracklistText = new FlxText(FlxG.width * 0.05, levelBackground.x + levelBackground.height + 100, 0, "Tracks", 32);
     tracklistText.setFormat("VCR OSD Mono", 32);
     tracklistText.alignment = CENTER;
     tracklistText.color = 0xFFe55777;
     add(tracklistText);
 
+    scoreText = new FlxText(10, 10, 0, 'HIGH SCORE: 42069420');
+    scoreText.setFormat("VCR OSD Mono", 32);
+    add(scoreText);
+
+    modeText = new FlxText(10, 10, 0, 'Base Game Levels [TAB to switch]');
+    modeText.setFormat("VCR OSD Mono", 32);
+    modeText.screenCenter(X);
+    modeText.visible = hasModdedLevels();
+    add(modeText);
+
     levelTitleText = new FlxText(FlxG.width * 0.7, 10, 0, 'LEVEL 1');
     levelTitleText.setFormat("VCR OSD Mono", 32, FlxColor.WHITE, RIGHT);
     levelTitleText.alpha = 0.7;
@@ -256,7 +267,7 @@ class StoryMenuState extends MusicBeatState
     displayingModdedLevels = moddedLevels;
     buildLevelTitles();
 
-    changeLevel(0);
+    changeLevel(999999); // Jump past the end of the list to the beginning.
     changeDifficulty(0);
   }
 
@@ -268,6 +279,9 @@ class StoryMenuState extends MusicBeatState
 
     scoreText.text = 'LEVEL SCORE: ${Math.round(highScoreLerp)}';
 
+    modeText.text = displayingModdedLevels ? 'Mods [TAB to switch]' : 'Base Game [TAB to switch]';
+    modeText.screenCenter(X);
+
     levelTitleText.text = currentLevel.getTitle();
     levelTitleText.x = FlxG.width - (levelTitleText.width + 10); // Right align.
 
@@ -322,7 +336,7 @@ class StoryMenuState extends MusicBeatState
           changeDifficulty(-1);
         }
 
-        if (FlxG.keys.justPressed.TAB)
+        if (FlxG.keys.justPressed.TAB && modeText.visible)
         {
           switchMode(!displayingModdedLevels);
         }
@@ -342,6 +356,11 @@ class StoryMenuState extends MusicBeatState
     }
   }
 
+  function hasModdedLevels():Bool
+  {
+    return LevelRegistry.instance.listModdedLevelIds().length > 0;
+  }
+
   /**
    * Changes the selected level.
    * @param change +1 (down), -1 (up)