diff --git a/source/funkin/GitarooPause.hx b/source/funkin/GitarooPause.hx
index 5747de5e5..a4dc766be 100644
--- a/source/funkin/GitarooPause.hx
+++ b/source/funkin/GitarooPause.hx
@@ -3,6 +3,7 @@ package funkin;
 import flixel.FlxSprite;
 import flixel.graphics.frames.FlxAtlasFrames;
 import funkin.play.PlayState;
+import flixel.addons.transition.FlxTransitionableState;
 
 class GitarooPause extends MusicBeatState
 {
@@ -61,6 +62,8 @@ class GitarooPause extends MusicBeatState
     {
       if (replaySelect)
       {
+        FlxTransitionableState.skipNextTransIn = false;
+        FlxTransitionableState.skipNextTransOut = false;
         FlxG.switchState(new PlayState(previousParams));
       }
       else
diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx
index 161da5191..6483ea9e5 100644
--- a/source/funkin/play/GameOverSubState.hx
+++ b/source/funkin/play/GameOverSubState.hx
@@ -124,8 +124,6 @@ class GameOverSubState extends MusicBeatSubState
 
   override function update(elapsed:Float)
   {
-    super.update(elapsed);
-
     if (!hasStartedAnimation)
     {
       hasStartedAnimation = true;
@@ -205,12 +203,13 @@ class GameOverSubState extends MusicBeatSubState
           if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished())
           {
             startDeathMusic(1.0, false);
+            boyfriend.playAnimation('deathLoop' + animationSuffix);
           }
       }
     }
 
-    // Dispatch the onUpdate event.
-    dispatchEvent(new UpdateScriptEvent(elapsed));
+    // Start death music before firstDeath gets replaced
+    super.update(elapsed);
   }
 
   /**
diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx
index 4d4cf3d40..5e8f964d1 100644
--- a/source/funkin/play/PlayState.hx
+++ b/source/funkin/play/PlayState.hx
@@ -488,8 +488,6 @@ class PlayState extends MusicBeatSubState
    */
   public override function create():Void
   {
-    super.create();
-
     if (instance != null)
     {
       // TODO: Do something in this case? IDK.
@@ -630,6 +628,9 @@ class PlayState extends MusicBeatSubState
       startCountdown();
     }
 
+    // Do this last to prevent beatHit from being called before create() is done.
+    super.create();
+
     leftWatermarkText.cameras = [camHUD];
     rightWatermarkText.cameras = [camHUD];
 
@@ -810,6 +811,16 @@ class PlayState extends MusicBeatSubState
       FlxG.watch.addQuick('bfAnim', currentStage.getBoyfriend().getCurrentAnimation());
     }
 
+    if (currentStage.getBoyfriend() != null)
+    {
+      FlxG.watch.addQuick('bfCameraFocus', currentStage.getBoyfriend().cameraFocusPoint);
+    }
+
+    if (currentStage.getDad() != null)
+    {
+      FlxG.watch.addQuick('dadCameraFocus', currentStage.getDad().cameraFocusPoint);
+    }
+
     // TODO: Add a song event for Handle GF dance speed.
 
     // Handle player death.
@@ -857,6 +868,8 @@ class PlayState extends MusicBeatSubState
         #end
 
         var gameOverSubState = new GameOverSubState();
+        FlxTransitionableSubState.skipNextTransIn = true;
+        FlxTransitionableSubState.skipNextTransOut = true;
         openSubState(gameOverSubState);
 
         #if discord_rpc
@@ -971,6 +984,9 @@ class PlayState extends MusicBeatSubState
 
       if (event.eventCanceled) return;
 
+      // Resume
+      FlxG.sound.music.play();
+
       if (FlxG.sound.music != null && !startingSong && !isInCutscene) resyncVocals();
 
       // Resume the countdown.
@@ -1669,6 +1685,9 @@ class PlayState extends MusicBeatSubState
   {
     if (_exiting || vocals == null) return;
 
+    // Skip this if the music is paused (GameOver, Pause menu, etc.)
+    if (!FlxG.sound.music.playing) return;
+
     vocals.pause();
 
     FlxG.sound.music.play();
@@ -1700,6 +1719,8 @@ class PlayState extends MusicBeatSubState
    */
   function onKeyPress(event:PreciseInputEvent):Void
   {
+    if (isGamePaused) return;
+
     // Do the minimal possible work here.
     inputPressQueue.push(event);
   }
@@ -1709,6 +1730,8 @@ class PlayState extends MusicBeatSubState
    */
   function onKeyRelease(event:PreciseInputEvent):Void
   {
+    if (isGamePaused) return;
+
     // Do the minimal possible work here.
     inputReleaseQueue.push(event);
   }
diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx
index bcb73d543..42dfd2da4 100644
--- a/source/funkin/play/character/BaseCharacter.hx
+++ b/source/funkin/play/character/BaseCharacter.hx
@@ -227,12 +227,15 @@ class BaseCharacter extends Bopper
   public function resetCharacter(resetCamera:Bool = true):Void
   {
     // Reset the animation offsets. This will modify x and y to be the absolute position of the character.
-    this.animOffsets = [0, 0];
+    // this.animOffsets = [0, 0];
 
     // Now we can set the x and y to be their original values without having to account for animOffsets.
     this.resetPosition();
 
-    // Make sure we are playing the idle animation (to reapply animOffsets)...
+    // Then reapply animOffsets...
+    // applyAnimationOffsets(getCurrentAnimation());
+
+    // Make sure we are playing the idle animation
     this.dance(true); // Force to avoid the old animation playing with the wrong offset at the start of the song.
     // ...then update the hitbox so that this.width and this.height are correct.
     this.updateHitbox();
@@ -344,7 +347,7 @@ class BaseCharacter extends Bopper
 
     if (isDead)
     {
-      playDeathAnimation();
+      // playDeathAnimation();
       return;
     }
 
@@ -392,20 +395,6 @@ class BaseCharacter extends Bopper
     FlxG.watch.addQuick('holdTimer-${characterId}', holdTimer);
   }
 
-  /**
-   * Since no `onBeatHit` or `dance` calls happen in GameOverSubState,
-   * this regularly gets called instead.
-   *
-   * @param force Force the deathLoop animation to play, even if `firstDeath` is still playing.
-   */
-  public function playDeathAnimation(force:Bool = false):Void
-  {
-    if (force || (getCurrentAnimation().startsWith('firstDeath') && isAnimationFinished()))
-    {
-      playAnimation('deathLoop' + GameOverSubState.animationSuffix);
-    }
-  }
-
   public function isSinging():Bool
   {
     return getCurrentAnimation().startsWith('sing');
diff --git a/source/funkin/play/stage/Bopper.hx b/source/funkin/play/stage/Bopper.hx
index 5fb1022fe..d88618f8a 100644
--- a/source/funkin/play/stage/Bopper.hx
+++ b/source/funkin/play/stage/Bopper.hx
@@ -158,8 +158,11 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
    */
   public function resetPosition()
   {
-    this.x = originalPosition.x + animOffsets[0];
-    this.y = originalPosition.y + animOffsets[1];
+    var oldAnimOffsets = [animOffsets[0], animOffsets[1]];
+    animOffsets = [0, 0];
+    this.x = originalPosition.x;
+    this.y = originalPosition.y;
+    animOffsets = oldAnimOffsets;
   }
 
   function update_shouldAlternate():Void
diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx
index ef2d28430..dafba1c06 100644
--- a/source/funkin/play/stage/Stage.hx
+++ b/source/funkin/play/stage/Stage.hx
@@ -78,6 +78,10 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass
     if (getBoyfriend() != null)
     {
       getBoyfriend().resetCharacter(true);
+      // Reapply the camera offsets.
+      var charData = _data.characters.bf;
+      getBoyfriend().cameraFocusPoint.x += charData.cameraOffsets[0];
+      getBoyfriend().cameraFocusPoint.y += charData.cameraOffsets[1];
     }
     else
     {
@@ -86,10 +90,18 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass
     if (getGirlfriend() != null)
     {
       getGirlfriend().resetCharacter(true);
+      // Reapply the camera offsets.
+      var charData = _data.characters.gf;
+      getGirlfriend().cameraFocusPoint.x += charData.cameraOffsets[0];
+      getGirlfriend().cameraFocusPoint.y += charData.cameraOffsets[1];
     }
     if (getDad() != null)
     {
       getDad().resetCharacter(true);
+      // Reapply the camera offsets.
+      var charData = _data.characters.dad;
+      getDad().cameraFocusPoint.x += charData.cameraOffsets[0];
+      getDad().cameraFocusPoint.y += charData.cameraOffsets[1];
     }
 
     // Reset positions of named props.
@@ -216,8 +228,12 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass
         {
           cast(propSprite, Bopper).setAnimationOffsets(propAnim.name, propAnim.offsets[0], propAnim.offsets[1]);
         }
-        cast(propSprite, Bopper).originalPosition.x = dataProp.position[0];
-        cast(propSprite, Bopper).originalPosition.y = dataProp.position[1];
+
+        if (!Std.isOfType(propSprite, BaseCharacter))
+        {
+          cast(propSprite, Bopper).originalPosition.x = dataProp.position[0];
+          cast(propSprite, Bopper).originalPosition.y = dataProp.position[1];
+        }
       }
 
       if (dataProp.startingAnimation != null)
@@ -357,8 +373,12 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass
       character.x = charData.position[0] - character.characterOrigin.x + character.globalOffsets[0];
       character.y = charData.position[1] - character.characterOrigin.y + character.globalOffsets[1];
 
-      character.originalPosition.x = character.x;
-      character.originalPosition.y = character.y;
+      @:privateAccess(funkin.play.stage.Bopper)
+      {
+        // Undo animOffsets before saving original position.
+        character.originalPosition.x = character.x + character.animOffsets[0];
+        character.originalPosition.y = character.y + character.animOffsets[1];
+      }
 
       character.cameraFocusPoint.x += charData.cameraOffsets[0];
       character.cameraFocusPoint.y += charData.cameraOffsets[1];
diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx
index ddd50073a..8e5a65c80 100644
--- a/source/funkin/ui/debug/charting/ChartEditorState.hx
+++ b/source/funkin/ui/debug/charting/ChartEditorState.hx
@@ -6,6 +6,7 @@ import flixel.FlxCamera;
 import flixel.FlxSprite;
 import flixel.FlxSubState;
 import flixel.group.FlxSpriteGroup;
+import flixel.addons.transition.FlxTransitionableState;
 import flixel.input.keyboard.FlxKey;
 import flixel.math.FlxPoint;
 import flixel.math.FlxRect;
@@ -3336,6 +3337,9 @@ class ChartEditorState extends HaxeUIState
     subStateClosed.add(fixCamera);
     subStateClosed.add(updateConductor);
 
+    FlxTransitionableState.skipNextTransIn = false;
+    FlxTransitionableState.skipNextTransOut = false;
+
     openSubState(new PlayState(
       {
         targetSong: targetSong,
diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx
index 29bc4beca..8d2db0543 100644
--- a/source/funkin/ui/story/StoryMenuState.hx
+++ b/source/funkin/ui/story/StoryMenuState.hx
@@ -5,6 +5,7 @@ import flixel.addons.transition.FlxTransitionableState;
 import flixel.FlxSprite;
 import flixel.group.FlxGroup.FlxTypedGroup;
 import flixel.text.FlxText;
+import flixel.addons.transition.FlxTransitionableState;
 import flixel.tweens.FlxEase;
 import flixel.tweens.FlxTween;
 import flixel.util.FlxColor;
@@ -521,6 +522,9 @@ class StoryMenuState extends MusicBeatState
     }
 
     new FlxTimer().start(1, function(tmr:FlxTimer) {
+      FlxTransitionableState.skipNextTransIn = false;
+      FlxTransitionableState.skipNextTransOut = false;
+
       LoadingState.loadAndSwitchState(new PlayState(
         {
           targetSong: targetSong,