diff --git a/.github/actions/setup-haxeshit/action.yml b/.github/actions/setup-haxeshit/action.yml
index dcf5fd0a7..cb5e68f61 100644
--- a/.github/actions/setup-haxeshit/action.yml
+++ b/.github/actions/setup-haxeshit/action.yml
@@ -13,7 +13,7 @@ runs:
     - name: Installing Haxe lol
       run: |
         haxe -version
-        haxelib git haxelib https://github.com/HaxeFoundation/haxelib.git development
+        haxelib git haxelib https://github.com/HaxeFoundation/haxelib.git master
         haxelib version
         haxelib --global install hmm
       shell: bash
diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx
index ae73524a8..918e7c725 100644
--- a/source/funkin/FreeplayState.hx
+++ b/source/funkin/FreeplayState.hx
@@ -535,16 +535,19 @@ class FreeplayState extends MusicBeatSubState
           // this creates a filter to return all the songs that start with a letter between those two
           var filterRegexp = new EReg("^[" + filterStuff.filterData + "].*", "i");
           tempSongs = tempSongs.filter(str -> {
+            if (str == null) return true; // Random
             return filterRegexp.match(str.songName);
           });
         case STARTSWITH:
           tempSongs = tempSongs.filter(str -> {
+            if (str == null) return true; // Random
             return str.songName.toLowerCase().startsWith(filterStuff.filterData);
           });
         case ALL:
         // no filter!
         case FAVORITE:
           tempSongs = tempSongs.filter(str -> {
+            if (str == null) return true; // Random
             return str.isFav;
           });
         default:
@@ -555,7 +558,7 @@ class FreeplayState extends MusicBeatSubState
     var hsvShader:HSVShader = new HSVShader();
 
     var randomCapsule:SongMenuItem = grpCapsules.recycle(SongMenuItem);
-    randomCapsule.init(FlxG.width, 0, "Random");
+    randomCapsule.init(FlxG.width, 0, null);
     randomCapsule.onConfirm = function() {
       capsuleOnConfirmRandom(randomCapsule);
     };
@@ -574,8 +577,7 @@ class FreeplayState extends MusicBeatSubState
 
       var funnyMenu:SongMenuItem = grpCapsules.recycle(SongMenuItem);
 
-      funnyMenu.init(FlxG.width, 0, tempSongs[i].songName);
-      if (tempSongs[i].songCharacter != null) funnyMenu.setCharacter(tempSongs[i].songCharacter);
+      funnyMenu.init(FlxG.width, 0, tempSongs[i]);
       funnyMenu.onConfirm = function() {
         capsuleOnConfirmDefault(funnyMenu);
       };
@@ -946,11 +948,29 @@ class FreeplayState extends MusicBeatSubState
     }
   }
 
-  function capsuleOnConfirmRandom(cap:SongMenuItem):Void
+  function capsuleOnConfirmRandom(randomCapsule:SongMenuItem):Void
   {
     trace("RANDOM SELECTED");
 
     busy = true;
+
+    var availableSongCapsules:Array<SongMenuItem> = grpCapsules.members.filter(function(cap:SongMenuItem) {
+      // Dead capsules are ones which were removed from the list when changing filters.
+      return cap.alive && cap.songData != null;
+    });
+
+    trace('Available songs: ${availableSongCapsules.map(function(cap) {
+      return cap.songData.songName;
+    })}');
+
+    var targetSong:SongMenuItem = FlxG.random.getObject(availableSongCapsules);
+
+    // Seeing if I can do an animation...
+    curSelected = grpCapsules.members.indexOf(targetSong);
+    changeSelection(0); // Trigger an update.
+
+    // Act like we hit Confirm on that song.
+    capsuleOnConfirmDefault(targetSong);
   }
 
   function capsuleOnConfirmDefault(cap:SongMenuItem):Void
@@ -959,8 +979,7 @@ class FreeplayState extends MusicBeatSubState
 
     PlayStatePlaylist.isStoryMode = false;
 
-    var songId:String = cap.songTitle.toLowerCase();
-    var targetSong:Song = SongRegistry.instance.fetchEntry(songId);
+    var targetSong:Song = SongRegistry.instance.fetchEntry(cap.songData.songId);
     var targetDifficulty:String = currentDifficulty;
 
     // TODO: Implement Pico into the interface properly.
@@ -970,7 +989,7 @@ class FreeplayState extends MusicBeatSubState
       targetCharacter = 'pico';
     }
 
-    PlayStatePlaylist.campaignId = songs[curSelected].levelId;
+    PlayStatePlaylist.campaignId = cap.songData.levelId;
 
     // Visual and audio effects.
     FlxG.sound.play(Paths.sound('confirmMenu'));
@@ -981,7 +1000,7 @@ class FreeplayState extends MusicBeatSubState
     targetSong.cacheCharts(true);
 
     new FlxTimer().start(1, function(tmr:FlxTimer) {
-      Paths.setCurrentLevel(songs[curSelected].levelId);
+      Paths.setCurrentLevel(cap.songData.levelId);
       LoadingState.loadAndSwitchState(new PlayState(
         {
           targetSong: targetSong,
@@ -1013,16 +1032,21 @@ class FreeplayState extends MusicBeatSubState
     FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
     // FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName));
 
+    var prevSelected = curSelected;
+
     curSelected += change;
 
     if (curSelected < 0) curSelected = grpCapsules.countLiving() - 1;
     if (curSelected >= grpCapsules.countLiving()) curSelected = 0;
 
-    var daSong = songs[curSelected];
-    if (daSong != null)
+    var daSongCapsule = grpCapsules.members[curSelected];
+    if (daSongCapsule.songData != null)
     {
-      diffIdsCurrent = daSong.songDifficulties;
-      rememberedSongId = daSong.songId;
+      var songScore:SaveScoreData = Save.get().getSongScore(daSongCapsule.songData.songId, currentDifficulty);
+      intendedScore = songScore?.score ?? 0;
+      intendedCompletion = songScore?.accuracy ?? 0.0;
+      diffIdsCurrent = daSongCapsule.songData.songDifficulties;
+      rememberedSongId = daSongCapsule.songData.songId;
       changeDiff();
     }
     else
@@ -1054,7 +1078,12 @@ class FreeplayState extends MusicBeatSubState
       }
       else
       {
-        // TODO: Try to stream the music?
+        // TODO: Stream the instrumental of the selected song?
+        if (prevSelected == 0)
+        {
+          FlxG.sound.playMusic(Paths.music('freakyMenu/freakyMenu'));
+          FlxG.sound.music.fadeIn(2, 0, 0.8);
+        }
       }
       grpCapsules.members[curSelected].selected = true;
     }
diff --git a/source/funkin/freeplayStuff/SongMenuItem.hx b/source/funkin/freeplayStuff/SongMenuItem.hx
index 5fd7eb576..06de92886 100644
--- a/source/funkin/freeplayStuff/SongMenuItem.hx
+++ b/source/funkin/freeplayStuff/SongMenuItem.hx
@@ -1,5 +1,6 @@
 package funkin.freeplayStuff;
 
+import funkin.FreeplayState.FreeplaySongData;
 import funkin.shaderslmfao.HSVShader;
 import funkin.shaderslmfao.GaussianBlurShader;
 import flixel.group.FlxGroup;
@@ -19,9 +20,13 @@ class SongMenuItem extends FlxSpriteGroup
 
   var pixelIcon:FlxSprite;
 
-  public var selected(default, set):Bool;
+  /**
+   * Modify this by calling `init()`
+   * If `null`, assume this SongMenuItem is for the "Random Song" option.
+   */
+  public var songData(default, null):Null<FreeplaySongData> = null;
 
-  public var songTitle:String = "Test";
+  public var selected(default, set):Bool;
 
   public var songText:CapsuleText;
   public var favIcon:FlxSprite;
@@ -45,12 +50,10 @@ class SongMenuItem extends FlxSpriteGroup
 
   public var hsvShader(default, set):HSVShader;
 
-  public function new(x:Float, y:Float, song:String, ?character:String)
+  public function new(x:Float, y:Float)
   {
     super(x, y);
 
-    this.songTitle = song;
-
     capsule = new FlxSprite();
     capsule.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule');
     capsule.animation.addByPrefix('selected', 'mp3 capsule w backing0', 24);
@@ -86,7 +89,7 @@ class SongMenuItem extends FlxSpriteGroup
         ranking.x -= 10;
     }
 
-    songText = new CapsuleText(capsule.width * 0.26, 45, songTitle, Std.int(40 * realScaled));
+    songText = new CapsuleText(capsule.width * 0.26, 45, 'Random', Std.int(40 * realScaled));
     add(songText);
     grpHide.add(songText);
 
@@ -97,8 +100,6 @@ class SongMenuItem extends FlxSpriteGroup
     add(pixelIcon);
     grpHide.add(pixelIcon);
 
-    if (character != null) setCharacter(character);
-
     favIcon = new FlxSprite(400, 40);
     favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart');
     favIcon.animation.addByPrefix('fav', "favorite heart", 24, false);
@@ -144,18 +145,21 @@ class SongMenuItem extends FlxSpriteGroup
 
     if (value) textAppear();
 
-    selectedAlpha();
+    updateSelected();
   }
 
-  public function init(x:Float, y:Float, song:String, ?character:String)
+  public function init(x:Float, y:Float, songData:Null<FreeplaySongData>)
   {
     this.x = x;
     this.y = y;
-    this.songTitle = song;
-    songText.text = this.songTitle;
-    if (character != null) setCharacter(character);
+    this.songData = songData;
 
-    selected = selected;
+    // Update capsule text.
+    songText.text = songData?.songName ?? 'Random';
+    // Update capsule character.
+    if (songData?.songCharacter != null) setCharacter(songData.songCharacter);
+    // Update opacity, offsets, etc.
+    updateSelected();
   }
 
   /**
@@ -169,6 +173,7 @@ class SongMenuItem extends FlxSpriteGroup
 
     trace(char);
 
+    // TODO: Put this in the character metadata where it belongs.
     switch (char)
     {
       case "monster-christmas":
@@ -244,7 +249,7 @@ class SongMenuItem extends FlxSpriteGroup
   {
     visible = true;
     capsule.alpha = 1;
-    selectedAlpha();
+    updateSelected();
     doLerp = true;
     doJumpIn = false;
     doJumpOut = false;
@@ -319,24 +324,22 @@ class SongMenuItem extends FlxSpriteGroup
     return (index * ((height * realScaled) + 10)) + 120;
   }
 
-  /**
-   * Merely a helper function to call set_selected, to make sure that the alpha is correct on the rankings/selections
-   */
-  public function selectedAlpha():Void
-  {
-    selected = selected;
-  }
-
   function set_selected(value:Bool):Bool
   {
     // cute one liners, lol!
-    diffGrayscale.setAmount(value ? 0 : 0.8);
-    songText.alpha = value ? 1 : 0.6;
-    songText.blurredText.visible = value ? true : false;
-    capsule.offset.x = value ? 0 : -5;
-    capsule.animation.play(value ? "selected" : "unselected");
-    ranking.alpha = value ? 1 : 0.7;
-    ranking.color = value ? 0xFFFFFFFF : 0xFFAAAAAA;
-    return value;
+    selected = value;
+    updateSelected();
+    return selected;
+  }
+
+  function updateSelected():Void
+  {
+    diffGrayscale.setAmount(this.selected ? 0 : 0.8);
+    songText.alpha = this.selected ? 1 : 0.6;
+    songText.blurredText.visible = this.selected ? true : false;
+    capsule.offset.x = this.selected ? 0 : -5;
+    capsule.animation.play(this.selected ? "selected" : "unselected");
+    ranking.alpha = this.selected ? 1 : 0.7;
+    ranking.color = this.selected ? 0xFFFFFFFF : 0xFFAAAAAA;
   }
 }