app.hypergames.hypersdk 1.11.0-beta.1 → 1.11.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/Runtime/Internal/Core/HyperRuntime.cs +62 -5
  3. package/Runtime/Internal/Managers/DataManager.cs +2 -1
  4. package/Runtime/Internal/Managers/GameManager.cs +102 -52
  5. package/Runtime/Internal/Managers/ReplayManager.cs +7 -0
  6. package/Runtime/Internal/Managers/TimeManager.cs +57 -40
  7. package/Runtime/Internal/Replay/ReplaySessionState.cs +60 -3
  8. package/Runtime/Internal/UI/Components/ReplayController.cs +39 -9
  9. package/Runtime/Internal/UI/Modals/ReplayOverModal.cs +7 -0
  10. package/Runtime/Internal/UI/Modals/ReplayPausedModal.cs +145 -0
  11. package/Runtime/Internal/UI/Modals/ReplayPausedModal.cs.meta +2 -0
  12. package/Runtime/Internal/UI/Modals/StartingInstructionModal.cs +2 -1
  13. package/Runtime/Public/Core/HyperSDK.cs +16 -0
  14. package/Runtime/Public/Replay/ReplayPlaybackEngine.cs +56 -1
  15. package/Runtime/Resources/Fonts/Nunito/Nunito-Bold SDF.asset +500 -457
  16. package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Normal.png +0 -0
  17. package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Normal.png.meta +156 -0
  18. package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Pressed.png +0 -0
  19. package/Runtime/Resources/Sprites/Buttons/Hyper Long White Button_Pressed.png.meta +156 -0
  20. package/Runtime/Resources/Sprites/Replays/Replay.png +0 -0
  21. package/Runtime/Resources/Sprites/Replays/{Recording.png.meta → Replay.png.meta} +9 -9
  22. package/Runtime/Resources/UIPrefabs/ControlBar.prefab +5 -5
  23. package/Runtime/Resources/UIPrefabs/ReplayController.prefab +301 -182
  24. package/Runtime/Resources/UIPrefabs/ReplayPausedModal.prefab +2194 -0
  25. package/Runtime/Resources/UIPrefabs/ReplayPausedModal.prefab.meta +7 -0
  26. package/Runtime/Resources/UIPrefabs/ReplaySeekOverlay.prefab +1 -1
  27. package/Runtime/Shared/Replay/IReplayPlaybackEngine.cs +3 -0
  28. package/Samples~/LaneRunner/LaneRunnerSample.unity +4 -3
  29. package/Samples~/LaneRunner/Prefabs/DoubleScorePickup.prefab +1 -1
  30. package/Samples~/LaneRunner/Prefabs/Obstacle.prefab +1 -1
  31. package/Samples~/LaneRunner/README.md +8 -1
  32. package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerPlayer.cs +18 -4
  33. package/Samples~/LaneRunner/Scripts/Gameplay/LaneRunnerSpawner.cs +3 -1
  34. package/Samples~/LaneRunner/Scripts/Hyper/LaneRunnerTournamentAdapter.cs +8 -0
  35. package/package.json +1 -1
  36. package/Runtime/Resources/Sprites/Replays/Recording.png +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,88 @@
1
+ # [1.11.0-beta.11](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.10...v1.11.0-beta.11) (2026-08-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **replay:** apply 30x seek speed on beta ([564769e](https://github.com/mvmhyper/hyper-sdk/commit/564769e4764f27fd301f0e1dc52a4434635f93b7))
7
+ * **replay:** reduce default seek speed ([2cd0a34](https://github.com/mvmhyper/hyper-sdk/commit/2cd0a34c6390725d1c57fc3fa5f691f618c45083))
8
+
9
+
10
+ ### Features
11
+
12
+ * **replay:** increase default seek speed ([d1a5a46](https://github.com/mvmhyper/hyper-sdk/commit/d1a5a464c1e3e149255bf0d2d183439e9c29cfb3))
13
+
14
+ # [1.11.0-beta.10](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.9...v1.11.0-beta.10) (2026-08-30)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **replay:** reduce default seek speed ([f70551a](https://github.com/mvmhyper/hyper-sdk/commit/f70551aea942274ace1cb952ddae4e9edb0c1c12))
20
+
21
+ # [1.11.0-beta.9](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.8...v1.11.0-beta.9) (2026-08-30)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **replay:** show loader while exiting paused replay ([4a2e7a6](https://github.com/mvmhyper/hyper-sdk/commit/4a2e7a6045017ea8ed3ae3525271440dbf013e6c))
27
+
28
+ # [1.11.0-beta.8](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.7...v1.11.0-beta.8) (2026-08-30)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * **replay:** mute audio while seeking ([5ab8cd1](https://github.com/mvmhyper/hyper-sdk/commit/5ab8cd1411493cb5add07b51dc190c85251f99d2))
34
+
35
+ # [1.11.0-beta.7](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.6...v1.11.0-beta.7) (2026-08-30)
36
+
37
+
38
+ ### Bug Fixes
39
+
40
+ * **replay:** stabilize scene reload seeking ([dd9ac63](https://github.com/mvmhyper/hyper-sdk/commit/dd9ac632d08349d9578f64ae0b2dc2ab905a26af))
41
+
42
+ # [1.11.0-beta.6](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.5...v1.11.0-beta.6) (2026-08-29)
43
+
44
+
45
+ ### Bug Fixes
46
+
47
+ * **timer:** restore gameplay timers after pause ([ca82d57](https://github.com/mvmhyper/hyper-sdk/commit/ca82d57df87618807cbae611c0a9d6acc14f8470))
48
+
49
+ # [1.11.0-beta.5](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.4...v1.11.0-beta.5) (2026-08-28)
50
+
51
+
52
+ ### Bug Fixes
53
+
54
+ * **replay:** wait for custom restart readiness ([43f1aeb](https://github.com/mvmhyper/hyper-sdk/commit/43f1aeb6a127c8c12dbb8379e7230d64ef5e0763))
55
+
56
+
57
+ ### Features
58
+
59
+ * **replay:** add replay pause controls ([b9fb470](https://github.com/mvmhyper/hyper-sdk/commit/b9fb470e65c69e66a8a9611b0caa7e5417b1e4bf))
60
+ * **replay:** update replay control bar assets ([79ce8c0](https://github.com/mvmhyper/hyper-sdk/commit/79ce8c0f1b68129ae5b8bcf18a302117cf11c885))
61
+
62
+ # [1.11.0-beta.4](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.3...v1.11.0-beta.4) (2026-08-28)
63
+
64
+
65
+ ### Bug Fixes
66
+
67
+ * **replay:** align recording with fixed simulation ([ae2b322](https://github.com/mvmhyper/hyper-sdk/commit/ae2b32216a0a9ea125572d788eee3bfd846414b0))
68
+
69
+ # [1.11.0-beta.3](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.2...v1.11.0-beta.3) (2026-08-28)
70
+
71
+
72
+ ### Bug Fixes
73
+
74
+ * **replay:** reset random state before playback restart ([526a4d9](https://github.com/mvmhyper/hyper-sdk/commit/526a4d98c9b22241e3c52bb6837145bad999fb2b))
75
+ * **sample:** support lane runner custom restart ([49da385](https://github.com/mvmhyper/hyper-sdk/commit/49da385aaa917de438672a8630d4fe7927741b2a))
76
+
77
+ # [1.11.0-beta.2](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.1...v1.11.0-beta.2) (2026-08-27)
78
+
79
+
80
+ ### Bug Fixes
81
+
82
+ * **replay:** respect custom restart flows ([7470a17](https://github.com/mvmhyper/hyper-sdk/commit/7470a17c60534465500a202c24b0e360f61850fc))
83
+ * **replay:** shorten automatic replay start ([d05dc92](https://github.com/mvmhyper/hyper-sdk/commit/d05dc9267fbf05d392135eac3bb7c4f69b786eff))
84
+ * **timer:** align game time with fixed simulation ([b690d86](https://github.com/mvmhyper/hyper-sdk/commit/b690d861e178f05b21f1a7fbd87e255d97008a8b))
85
+
1
86
  # [1.11.0-beta.1](https://github.com/mvmhyper/hyper-sdk/compare/v1.10.0...v1.11.0-beta.1) (2026-08-26)
2
87
 
3
88
 
@@ -20,6 +20,8 @@ namespace Hyper.Internal
20
20
 
21
21
  private static bool _isInitialized;
22
22
  private static bool _isSoftRestarting;
23
+ private static bool _replayRandomResetPending;
24
+ private static bool _replayCustomRestartPending;
23
25
  private static bool _customLoadingComplete;
24
26
  private static bool _customLoadingActive;
25
27
  private static float _customLoadingProgress;
@@ -32,6 +34,7 @@ namespace Hyper.Internal
32
34
  private static EventManager _eventManager;
33
35
  private static TimerManager _timerManager;
34
36
  private static ReplayManager _replayManager;
37
+ private static double _fixedSimulationTimeSeconds;
35
38
 
36
39
  internal static bool IsInitialized => _isInitialized;
37
40
  internal static bool IsSoftRestarting
@@ -39,6 +42,7 @@ namespace Hyper.Internal
39
42
  get => _isSoftRestarting;
40
43
  set => _isSoftRestarting = value;
41
44
  }
45
+ internal static bool IsReplayCustomRestartPending => _replayCustomRestartPending;
42
46
  internal static bool CustomLoadingComplete
43
47
  {
44
48
  get => _customLoadingComplete;
@@ -58,6 +62,7 @@ namespace Hyper.Internal
58
62
  internal static EventManager EventManager => _eventManager;
59
63
  internal static TimerManager Timer => _timerManager;
60
64
  internal static ReplayManager ReplayManager => _replayManager;
65
+ internal static double FixedSimulationTimeSeconds => _fixedSimulationTimeSeconds;
61
66
 
62
67
  internal static event Action CustomLoadingStarted
63
68
  {
@@ -118,13 +123,12 @@ namespace Hyper.Internal
118
123
  }
119
124
 
120
125
  /// <summary>
121
- /// Restarts a replay from HyperLoader even when custom restart is enabled.
122
- /// Replay metadata, including the original seed value, remains available to the loader.
126
+ /// Restarts replay playback through HyperLoader while preserving replay session data.
123
127
  /// </summary>
124
128
  internal static void RestartReplaySession()
125
129
  {
126
130
  ReplaySessionState.ResetForWatchAgain();
127
- RestartReplayFromLoader();
131
+ RestartReplay();
128
132
  }
129
133
 
130
134
  internal static void SeekReplaySession(float targetProgress, float resumeSpeed, float seekSpeed)
@@ -133,14 +137,18 @@ namespace Hyper.Internal
133
137
 
134
138
  ReplaySessionState.RequestSeek(targetProgress, resumeSpeed, seekSpeed);
135
139
  ReplaySessionState.ResetForSeekRestart();
136
- RestartReplayFromLoader();
140
+ RestartReplay();
137
141
  }
138
142
 
139
- private static void RestartReplayFromLoader()
143
+ private static void RestartReplay()
140
144
  {
141
145
  _isSoftRestarting = true;
142
146
  Time.timeScale = 1f;
143
147
 
148
+ _replayCustomRestartPending = false;
149
+ _replayRandomResetPending = false;
150
+ _replayManager?.PrepareForRestart();
151
+
144
152
  if (_host != null)
145
153
  {
146
154
  _host.StartCoroutine(RestartSessionCoroutine());
@@ -152,6 +160,47 @@ namespace Hyper.Internal
152
160
  }
153
161
  }
154
162
 
163
+ internal static void ResetReplayRandomState()
164
+ {
165
+ int originalSeed = unchecked((int)ReplaySessionState.OriginalRandomSeed);
166
+ if (HyperRandom.CurrentSeed == originalSeed)
167
+ {
168
+ // Preserve references held by game code while rewinding every stream.
169
+ HyperRandom.ResetAll();
170
+ return;
171
+ }
172
+
173
+ HyperRandom.Init(ReplaySessionState.OriginalRandomSeed);
174
+ }
175
+
176
+ internal static void ApplyPendingReplayRandomReset()
177
+ {
178
+ if (!_replayRandomResetPending) return;
179
+
180
+ _replayRandomResetPending = false;
181
+ ResetReplayRandomState();
182
+ }
183
+
184
+ internal static void DeferReplayRandomReset()
185
+ {
186
+ _replayRandomResetPending = true;
187
+ }
188
+
189
+ internal static void CompleteCustomRestart()
190
+ {
191
+ if (!_replayCustomRestartPending || _host == null) return;
192
+
193
+ _replayCustomRestartPending = false;
194
+ _host.StartCoroutine(CompleteReplayCustomRestartNextFrame());
195
+ }
196
+
197
+ private static IEnumerator CompleteReplayCustomRestartNextFrame()
198
+ {
199
+ yield return null;
200
+ _gameManager?.CompleteReplayCustomRestart();
201
+ _isSoftRestarting = false;
202
+ }
203
+
155
204
  /// <summary>
156
205
  /// Coroutine-based restart that properly unloads all scenes before reloading.
157
206
  /// Handles async scene operations and ensures clean state before restart.
@@ -160,6 +209,7 @@ namespace Hyper.Internal
160
209
  {
161
210
  yield return UnloadAllScenesCoroutine();
162
211
 
212
+ Clear();
163
213
  ClearAllDontDestroyOnLoadObjects();
164
214
  SceneManager.LoadScene("HyperLoader");
165
215
  }
@@ -357,6 +407,7 @@ namespace Hyper.Internal
357
407
  internal static void FixedTick()
358
408
  {
359
409
  if (!_isInitialized) return;
410
+ _fixedSimulationTimeSeconds += Time.fixedDeltaTime;
360
411
  _replayManager?.FixedTick();
361
412
  _timerManager?.FixedTick();
362
413
  }
@@ -390,6 +441,9 @@ namespace Hyper.Internal
390
441
  _customLoadingComplete = false;
391
442
  _customLoadingActive = false;
392
443
  _customLoadingProgress = 0f;
444
+ _replayRandomResetPending = false;
445
+ _replayCustomRestartPending = false;
446
+ _fixedSimulationTimeSeconds = 0d;
393
447
 
394
448
  if (_singletonObject != null)
395
449
  {
@@ -448,6 +502,9 @@ namespace Hyper.Internal
448
502
  _customLoadingComplete = false;
449
503
  _customLoadingActive = false;
450
504
  _customLoadingProgress = 0f;
505
+ _replayRandomResetPending = false;
506
+ _replayCustomRestartPending = false;
507
+ _fixedSimulationTimeSeconds = 0d;
451
508
  }
452
509
  }
453
510
  }
@@ -219,6 +219,7 @@ namespace Hyper.Internal.Managers
219
219
  internal void ConfigurePlayerSoundSetting()
220
220
  {
221
221
  SetSound(GetSound());
222
+ ReplaySessionState.EnsureAudioMutedDuringSeek();
222
223
  if (_gameManager == null) _gameManager = HyperRuntime.GameManager;
223
224
  }
224
225
 
@@ -462,7 +463,7 @@ namespace Hyper.Internal.Managers
462
463
 
463
464
  private static double GetSimulationTimeSeconds()
464
465
  {
465
- return Time.fixedTimeAsDouble;
466
+ return HyperRuntime.FixedSimulationTimeSeconds;
466
467
  }
467
468
 
468
469
  private ScoreData GetPooledScoreData()
@@ -191,6 +191,41 @@ namespace Hyper.Internal.Managers
191
191
  Resources.UnloadUnusedAssets();
192
192
  }
193
193
 
194
+ internal void PauseReplay()
195
+ {
196
+ if (!IsReplayMode || !_hasGameStarted || _isPaused || _hasGameEnded)
197
+ {
198
+ return;
199
+ }
200
+
201
+ _isPaused = true;
202
+ _savedReplayTimeScale = Time.timeScale > 0f
203
+ ? Time.timeScale
204
+ : ReplaySessionState.PlaybackSpeed;
205
+ Time.timeScale = 0f;
206
+ HyperRuntime.Timer.PauseGameplayTimers();
207
+
208
+ _previousTimeScale = 0f;
209
+ _eventManager.InvokeTimeScaleFrozenEvent();
210
+ ReplayPresentationCanvas.SetSeekingLayer(false);
211
+ SetBlockerActive(true);
212
+ ShowReplayPauseModal();
213
+ }
214
+
215
+ internal void ResumeReplay()
216
+ {
217
+ if (!IsReplayMode || !_isPaused || _hasGameEnded) return;
218
+
219
+ _isPaused = false;
220
+ HidePauseModals();
221
+ Time.timeScale = _savedReplayTimeScale > 0f ? _savedReplayTimeScale : 1f;
222
+ HyperRuntime.Timer.ResumeGameTimersAfterPause();
223
+
224
+ _previousTimeScale = Time.timeScale;
225
+ _eventManager.InvokeTimeScaleResumedEvent();
226
+ ReplayPresentationCanvas.SetSeekingLayer(ReplaySessionState.IsSeeking);
227
+ }
228
+
194
229
  internal void ResumeGame()
195
230
  {
196
231
  _isPaused = false;
@@ -222,51 +257,7 @@ namespace Hyper.Internal.Managers
222
257
  private void HandleReplayFocus(bool hasFocus)
223
258
  {
224
259
  if (!_hasGameStarted || _hasGameEnded) return;
225
-
226
- if (!hasFocus && _replayFocusResumeCoroutine != null)
227
- {
228
- StopCoroutine(_replayFocusResumeCoroutine);
229
- _replayFocusResumeCoroutine = null;
230
- }
231
-
232
- if (!hasFocus && !_replayFocusSuspended)
233
- {
234
- _replayFocusSuspended = true;
235
- _savedReplayTimeScale = Time.timeScale;
236
- Time.timeScale = 0f;
237
- HyperRuntime.Timer.PauseGameplayTimers();
238
-
239
- // WebGL may stop producing frames immediately after focus loss,
240
- // so suspend replay timing here instead of waiting for Update.
241
- _previousTimeScale = 0f;
242
- _eventManager.InvokeTimeScaleFrozenEvent();
243
- HyperDebug.Log("Time scale frozen event invoked");
244
- }
245
- else if (hasFocus && _replayFocusSuspended)
246
- {
247
- if (_replayFocusResumeCoroutine == null)
248
- {
249
- _replayFocusResumeCoroutine = StartCoroutine(ResumeReplayAfterFocus());
250
- }
251
- }
252
- }
253
-
254
- private IEnumerator ResumeReplayAfterFocus()
255
- {
256
- // WebGL reports focus before Unity refreshes its unscaled clock. Keep
257
- // gameplay and replay frozen briefly while session time continues.
258
- yield return new WaitForSecondsRealtime(1f);
259
-
260
- _replayFocusResumeCoroutine = null;
261
- if (!_replayFocusSuspended || _hasGameEnded) yield break;
262
-
263
- _replayFocusSuspended = false;
264
- Time.timeScale = _savedReplayTimeScale > 0f ? _savedReplayTimeScale : 1f;
265
- HyperRuntime.Timer.ResumeGameTimersAfterPause();
266
-
267
- _previousTimeScale = Time.timeScale;
268
- _eventManager.InvokeTimeScaleResumedEvent();
269
- HyperDebug.Log("Time scale resumed event invoked");
260
+ if (!hasFocus) PauseReplay();
270
261
  }
271
262
 
272
263
  void HandlePauseState(bool shouldPause)
@@ -552,7 +543,7 @@ namespace Hyper.Internal.Managers
552
543
 
553
544
  internal void ShowStartGameDeadline(int timeLeft)
554
545
  {
555
- if (_hasGameStarted || !IsInGameScene) return;
546
+ if (_hasGameStarted || !IsInGameScene || IsReplayMode) return;
556
547
 
557
548
  EnsureStartGameDeadlineBar();
558
549
  _eventManager.OnSessionAboutToExpire += ChangeDeadlineColorToRed;
@@ -728,7 +719,6 @@ namespace Hyper.Internal.Managers
728
719
  private bool _isPortrait;
729
720
  private float _previousTimeScale = 1f;
730
721
  private float _savedTimeScaleBeforePause = 1f;
731
- private bool _replayFocusSuspended;
732
722
  private float _savedReplayTimeScale = 1f;
733
723
 
734
724
  #endregion
@@ -1025,6 +1015,8 @@ namespace Hyper.Internal.Managers
1025
1015
  if (_gameStartRequested || _hasGameStarted || _hasGameEnded || !IsInGameScene) return;
1026
1016
  _gameStartRequested = true;
1027
1017
 
1018
+ HyperRuntime.ApplyPendingReplayRandomReset();
1019
+
1028
1020
  HideStartGameDeadlineSnackBar();
1029
1021
  _dataManager.UpdateScore(0);
1030
1022
  HyperRuntime.Timer.StartActiveGameTimer();
@@ -1062,26 +1054,58 @@ namespace Hyper.Internal.Managers
1062
1054
 
1063
1055
  /// <summary>
1064
1056
  /// Resets SDK UI state for custom restart flow.
1065
- /// Called after OnCustomRestart event is fired to prepare the SDK for the developer's restart logic.
1057
+ /// Called before OnCustomRestart so the developer's cleanup starts from reset SDK state.
1066
1058
  /// </summary>
1067
1059
  internal void ResetUIStateForCustomRestart()
1068
1060
  {
1069
1061
  HideGameOverModal();
1070
1062
  HidePauseModals();
1063
+ if (_replayOverModal != null) _replayOverModal.SetActive(false);
1071
1064
 
1072
1065
  // Reset game state flags
1073
1066
  _hasGameStarted = false;
1074
1067
  _gameStartRequested = false;
1075
1068
  _hasGameEnded = false;
1069
+ _replayEndHandled = false;
1076
1070
  _isPaused = false;
1077
1071
  _isFrozenBeforePause = false;
1078
1072
 
1079
- HyperRuntime.Timer.Reset();
1073
+ HyperRuntime.Timer.ResetForGameRestart();
1080
1074
  HyperRuntime.DataManager.UpdateScore(0);
1081
1075
  HyperRuntime.DataManager.RestoreAudioAfterGameSessionEnd();
1082
1076
 
1083
1077
  ShowControlBarElements();
1084
- ShowStartingInstructionModal();
1078
+ _replayControllerComponent?.ResetForReplayRestart();
1079
+
1080
+ if (IsReplayMode && HyperRuntime.IsReplayCustomRestartPending)
1081
+ {
1082
+ HideStartingInstructionModal();
1083
+ return;
1084
+ }
1085
+
1086
+ if (IsReplayMode && ReplaySessionState.IsSeeking)
1087
+ {
1088
+ HideStartingInstructionModal();
1089
+ StartCoroutine(StartSeekingReplayWhenReady());
1090
+ }
1091
+ else
1092
+ {
1093
+ ShowStartingInstructionModal();
1094
+ }
1095
+ }
1096
+
1097
+ internal void CompleteReplayCustomRestart()
1098
+ {
1099
+ if (!IsReplayMode || _gameStartRequested || _hasGameStarted || _hasGameEnded) return;
1100
+
1101
+ if (ReplaySessionState.IsSeeking)
1102
+ {
1103
+ StartCoroutine(StartSeekingReplayWhenReady());
1104
+ }
1105
+ else
1106
+ {
1107
+ ShowStartingInstructionModal();
1108
+ }
1085
1109
  }
1086
1110
 
1087
1111
  #endregion
@@ -1125,7 +1149,6 @@ namespace Hyper.Internal.Managers
1125
1149
 
1126
1150
  _replayEndHandled = true;
1127
1151
  _hasGameEnded = true;
1128
- _replayFocusSuspended = false;
1129
1152
  Time.timeScale = 1f;
1130
1153
  _eventManager.InvokeGameEndedEvent();
1131
1154
  HyperRuntime.Timer.StopAllTimers();
@@ -1147,10 +1170,12 @@ namespace Hyper.Internal.Managers
1147
1170
  _eventManager.InvokeGameEndedEvent();
1148
1171
  }
1149
1172
 
1173
+ _isPaused = false;
1150
1174
  Time.timeScale = 1f;
1151
1175
  HyperRuntime.Timer.StopAllTimers();
1152
1176
  _dataManager.StopCapturingScores();
1153
1177
  HyperRuntime.BackendManager.StopSendingScores();
1178
+ HidePauseModals();
1154
1179
  _replayControllerComponent?.SetReplayEnded();
1155
1180
  ReplaySessionState.Clear();
1156
1181
  ReplayPresentationCanvas.DestroyCurrent();
@@ -1261,8 +1286,8 @@ namespace Hyper.Internal.Managers
1261
1286
  private GameObject _replayControllerObject;
1262
1287
  private ReplayController _replayControllerComponent;
1263
1288
  private GameObject _replayOverModal;
1289
+ private GameObject _replayPausedModal;
1264
1290
  private Coroutine _replayConnectionCheckCoroutine;
1265
- private Coroutine _replayFocusResumeCoroutine;
1266
1291
 
1267
1292
  private GameObject _connectionStatusBar;
1268
1293
  private GameObject _startGameDeadlineStatusBar;
@@ -1492,6 +1517,30 @@ namespace Hyper.Internal.Managers
1492
1517
  _replayOverModal.transform.SetAsLastSibling();
1493
1518
  }
1494
1519
 
1520
+ private void ShowReplayPauseModal()
1521
+ {
1522
+ if (_replayPausedModal == null)
1523
+ {
1524
+ if (_canvas == null) CreateCanvas();
1525
+ GameObject prefab = Resources.Load<GameObject>("UIPrefabs/ReplayPausedModal");
1526
+ if (prefab == null)
1527
+ {
1528
+ HyperDebug.LogWarning("[GameManager] ReplayPausedModal prefab not found.");
1529
+ ResumeReplay();
1530
+ return;
1531
+ }
1532
+
1533
+ _replayPausedModal = InstantiateModal(prefab);
1534
+ if (_replayPausedModal.GetComponent<ReplayPausedModal>() == null)
1535
+ {
1536
+ _replayPausedModal.AddComponent<ReplayPausedModal>();
1537
+ }
1538
+ }
1539
+
1540
+ _replayPausedModal.SetActive(true);
1541
+ _replayPausedModal.transform.SetAsLastSibling();
1542
+ }
1543
+
1495
1544
  private void EnsureConnectionStatusBar()
1496
1545
  {
1497
1546
  if (_connectionStatusBar != null) return;
@@ -1740,6 +1789,7 @@ namespace Hyper.Internal.Managers
1740
1789
  internal void HidePauseModals()
1741
1790
  {
1742
1791
  SetBlockerActive(false);
1792
+ if (_replayPausedModal != null) _replayPausedModal.SetActive(false);
1743
1793
  if (_battleGamePausedModal != null) _battleGamePausedModal.SetActive(false);
1744
1794
  if (_practicePausedModal != null) _practicePausedModal.SetActive(false);
1745
1795
  if (_battleGamePausedLandscapeModal != null) _battleGamePausedLandscapeModal.SetActive(false);
@@ -39,6 +39,12 @@ namespace Hyper.Internal.Managers
39
39
  ReplaySessionState.SetProgress(_playback.Progress01);
40
40
  }
41
41
 
42
+ internal void PrepareForRestart()
43
+ {
44
+ _endingGame = false;
45
+ _playback?.Stop();
46
+ }
47
+
42
48
  internal void Cleanup()
43
49
  {
44
50
  if (_eventManager != null)
@@ -68,6 +74,7 @@ namespace Hyper.Internal.Managers
68
74
  }
69
75
 
70
76
  _playback.Begin(ReplaySessionState.ReplayNdjson);
77
+ ReplaySessionState.SetGameplayStartProgress(_playback.GameplayStartProgress01);
71
78
  }
72
79
 
73
80
  private void HandleGameEnded()