app.hypergames.hypersdk 1.11.0-beta.1 → 1.11.0-beta.2
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.
- package/CHANGELOG.md +9 -0
- package/Runtime/Internal/Core/HyperRuntime.cs +29 -5
- package/Runtime/Internal/Managers/GameManager.cs +15 -2
- package/Runtime/Internal/Managers/ReplayManager.cs +6 -0
- package/Runtime/Internal/Managers/TimeManager.cs +32 -32
- package/Runtime/Internal/UI/Components/ReplayController.cs +26 -0
- package/Runtime/Internal/UI/Modals/ReplayOverModal.cs +7 -0
- package/Runtime/Internal/UI/Modals/StartingInstructionModal.cs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# [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)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **replay:** respect custom restart flows ([7470a17](https://github.com/mvmhyper/hyper-sdk/commit/7470a17c60534465500a202c24b0e360f61850fc))
|
|
7
|
+
* **replay:** shorten automatic replay start ([d05dc92](https://github.com/mvmhyper/hyper-sdk/commit/d05dc9267fbf05d392135eac3bb7c4f69b786eff))
|
|
8
|
+
* **timer:** align game time with fixed simulation ([b690d86](https://github.com/mvmhyper/hyper-sdk/commit/b690d861e178f05b21f1a7fbd87e255d97008a8b))
|
|
9
|
+
|
|
1
10
|
# [1.11.0-beta.1](https://github.com/mvmhyper/hyper-sdk/compare/v1.10.0...v1.11.0-beta.1) (2026-08-26)
|
|
2
11
|
|
|
3
12
|
|
|
@@ -118,13 +118,13 @@ namespace Hyper.Internal
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/// <summary>
|
|
121
|
-
/// Restarts
|
|
122
|
-
///
|
|
121
|
+
/// Restarts replay playback while preserving its downloaded data and original seed.
|
|
122
|
+
/// Uses the configured custom restart flow when available, otherwise reloads HyperLoader.
|
|
123
123
|
/// </summary>
|
|
124
124
|
internal static void RestartReplaySession()
|
|
125
125
|
{
|
|
126
126
|
ReplaySessionState.ResetForWatchAgain();
|
|
127
|
-
|
|
127
|
+
RestartReplay();
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
internal static void SeekReplaySession(float targetProgress, float resumeSpeed, float seekSpeed)
|
|
@@ -133,14 +133,25 @@ namespace Hyper.Internal
|
|
|
133
133
|
|
|
134
134
|
ReplaySessionState.RequestSeek(targetProgress, resumeSpeed, seekSpeed);
|
|
135
135
|
ReplaySessionState.ResetForSeekRestart();
|
|
136
|
-
|
|
136
|
+
RestartReplay();
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
private static void
|
|
139
|
+
private static void RestartReplay()
|
|
140
140
|
{
|
|
141
141
|
_isSoftRestarting = true;
|
|
142
142
|
Time.timeScale = 1f;
|
|
143
143
|
|
|
144
|
+
if (_settings != null && _settings.useCustomRestartFlow &&
|
|
145
|
+
_gameManager != null && _eventManager != null)
|
|
146
|
+
{
|
|
147
|
+
_replayManager?.PrepareForRestart();
|
|
148
|
+
ResetReplayRandomState();
|
|
149
|
+
_gameManager.ResetUIStateForCustomRestart();
|
|
150
|
+
_eventManager.InvokeCustomRestartEvent();
|
|
151
|
+
_isSoftRestarting = false;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
144
155
|
if (_host != null)
|
|
145
156
|
{
|
|
146
157
|
_host.StartCoroutine(RestartSessionCoroutine());
|
|
@@ -152,6 +163,19 @@ namespace Hyper.Internal
|
|
|
152
163
|
}
|
|
153
164
|
}
|
|
154
165
|
|
|
166
|
+
internal static void ResetReplayRandomState()
|
|
167
|
+
{
|
|
168
|
+
int originalSeed = unchecked((int)ReplaySessionState.OriginalRandomSeed);
|
|
169
|
+
if (HyperRandom.CurrentSeed == originalSeed)
|
|
170
|
+
{
|
|
171
|
+
// Preserve references held by game code while rewinding every stream.
|
|
172
|
+
HyperRandom.ResetAll();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
HyperRandom.Init(ReplaySessionState.OriginalRandomSeed);
|
|
177
|
+
}
|
|
178
|
+
|
|
155
179
|
/// <summary>
|
|
156
180
|
/// Coroutine-based restart that properly unloads all scenes before reloading.
|
|
157
181
|
/// Handles async scene operations and ensures clean state before restart.
|
|
@@ -1068,20 +1068,33 @@ namespace Hyper.Internal.Managers
|
|
|
1068
1068
|
{
|
|
1069
1069
|
HideGameOverModal();
|
|
1070
1070
|
HidePauseModals();
|
|
1071
|
+
if (_replayOverModal != null) _replayOverModal.SetActive(false);
|
|
1071
1072
|
|
|
1072
1073
|
// Reset game state flags
|
|
1073
1074
|
_hasGameStarted = false;
|
|
1074
1075
|
_gameStartRequested = false;
|
|
1075
1076
|
_hasGameEnded = false;
|
|
1077
|
+
_replayEndHandled = false;
|
|
1078
|
+
_replayFocusSuspended = false;
|
|
1076
1079
|
_isPaused = false;
|
|
1077
1080
|
_isFrozenBeforePause = false;
|
|
1078
1081
|
|
|
1079
|
-
HyperRuntime.Timer.
|
|
1082
|
+
HyperRuntime.Timer.ResetForGameRestart();
|
|
1080
1083
|
HyperRuntime.DataManager.UpdateScore(0);
|
|
1081
1084
|
HyperRuntime.DataManager.RestoreAudioAfterGameSessionEnd();
|
|
1082
1085
|
|
|
1083
1086
|
ShowControlBarElements();
|
|
1084
|
-
|
|
1087
|
+
_replayControllerComponent?.ResetForReplayRestart();
|
|
1088
|
+
|
|
1089
|
+
if (IsReplayMode && ReplaySessionState.IsSeeking)
|
|
1090
|
+
{
|
|
1091
|
+
HideStartingInstructionModal();
|
|
1092
|
+
StartCoroutine(StartSeekingReplayWhenReady());
|
|
1093
|
+
}
|
|
1094
|
+
else
|
|
1095
|
+
{
|
|
1096
|
+
ShowStartingInstructionModal();
|
|
1097
|
+
}
|
|
1085
1098
|
}
|
|
1086
1099
|
|
|
1087
1100
|
#endregion
|
|
@@ -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)
|
|
@@ -43,7 +43,7 @@ namespace Hyper.Internal.Managers
|
|
|
43
43
|
private bool _isSessionRunning;
|
|
44
44
|
private bool _sessionWarningTriggered;
|
|
45
45
|
private bool _timeUpTriggered;
|
|
46
|
-
private bool
|
|
46
|
+
private bool _timeUpPending;
|
|
47
47
|
|
|
48
48
|
private float _lastUnscaledTime;
|
|
49
49
|
private bool _hasGameEnded;
|
|
@@ -65,7 +65,7 @@ namespace Hyper.Internal.Managers
|
|
|
65
65
|
_hasBackendSessionDuration = false;
|
|
66
66
|
_lastUnscaledTime = Time.unscaledTime;
|
|
67
67
|
_timeUpTriggered = false;
|
|
68
|
-
|
|
68
|
+
_timeUpPending = false;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
#endregion
|
|
@@ -91,27 +91,21 @@ namespace Hyper.Internal.Managers
|
|
|
91
91
|
float unscaledDelta = Time.unscaledTime - _lastUnscaledTime;
|
|
92
92
|
_lastUnscaledTime = Time.unscaledTime;
|
|
93
93
|
|
|
94
|
-
if (!_gameManager.IsReplayMode)
|
|
95
|
-
{
|
|
96
|
-
float gameTimerDelta = Mathf.Approximately(Time.timeScale, 0f)
|
|
97
|
-
? 0f
|
|
98
|
-
: unscaledDelta;
|
|
99
|
-
|
|
100
|
-
UpdatePracticeTimer(gameTimerDelta);
|
|
101
|
-
UpdateBattleTimer(gameTimerDelta);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
94
|
UpdateSessionTimer(unscaledDelta);
|
|
105
|
-
|
|
95
|
+
DispatchPendingTimeUp();
|
|
106
96
|
}
|
|
107
97
|
|
|
108
98
|
internal void FixedTick()
|
|
109
99
|
{
|
|
110
|
-
if (
|
|
100
|
+
if (Mathf.Approximately(Time.timeScale, 0f))
|
|
111
101
|
return;
|
|
112
102
|
|
|
113
|
-
|
|
114
|
-
|
|
103
|
+
float gameTimerDelta = _gameManager != null && _gameManager.IsReplayMode
|
|
104
|
+
? Time.fixedDeltaTime
|
|
105
|
+
: Time.fixedUnscaledDeltaTime;
|
|
106
|
+
|
|
107
|
+
UpdatePracticeTimer(gameTimerDelta);
|
|
108
|
+
UpdateBattleTimer(gameTimerDelta);
|
|
115
109
|
}
|
|
116
110
|
|
|
117
111
|
public void Reset()
|
|
@@ -120,6 +114,19 @@ namespace Hyper.Internal.Managers
|
|
|
120
114
|
_lastUnscaledTime = Time.unscaledTime;
|
|
121
115
|
}
|
|
122
116
|
|
|
117
|
+
internal void ResetForGameRestart()
|
|
118
|
+
{
|
|
119
|
+
_practiceTimer = 0f;
|
|
120
|
+
_battleTimer = _gameManager != null ? _gameManager.Config.TimeLimit : 0f;
|
|
121
|
+
_isPracticeRunning = false;
|
|
122
|
+
_isBattleRunning = false;
|
|
123
|
+
_timeUpTriggered = false;
|
|
124
|
+
_timeUpPending = false;
|
|
125
|
+
_hasGameEnded = false;
|
|
126
|
+
_hasGameStarted = false;
|
|
127
|
+
_lastUnscaledTime = Time.unscaledTime;
|
|
128
|
+
}
|
|
129
|
+
|
|
123
130
|
public void ResumeGameTimersAfterPause()
|
|
124
131
|
{
|
|
125
132
|
if (_gameManager.IsBattleMode)
|
|
@@ -150,7 +157,7 @@ namespace Hyper.Internal.Managers
|
|
|
150
157
|
public void StopAllTimers()
|
|
151
158
|
{
|
|
152
159
|
_hasGameEnded = true;
|
|
153
|
-
|
|
160
|
+
_timeUpPending = false;
|
|
154
161
|
StopBattle();
|
|
155
162
|
StopPractice();
|
|
156
163
|
}
|
|
@@ -262,7 +269,7 @@ namespace Hyper.Internal.Managers
|
|
|
262
269
|
}
|
|
263
270
|
}
|
|
264
271
|
|
|
265
|
-
private void UpdateBattleTimer(float delta
|
|
272
|
+
private void UpdateBattleTimer(float delta)
|
|
266
273
|
{
|
|
267
274
|
if (_isBattleRunning)
|
|
268
275
|
{
|
|
@@ -280,7 +287,7 @@ namespace Hyper.Internal.Managers
|
|
|
280
287
|
_battleTimer = 0;
|
|
281
288
|
if (!_timeUpTriggered)
|
|
282
289
|
{
|
|
283
|
-
|
|
290
|
+
QueueTimeUp();
|
|
284
291
|
}
|
|
285
292
|
}
|
|
286
293
|
}
|
|
@@ -292,30 +299,23 @@ namespace Hyper.Internal.Managers
|
|
|
292
299
|
|
|
293
300
|
if (_battleTimer <= 0 && !_timeUpTriggered)
|
|
294
301
|
{
|
|
295
|
-
|
|
302
|
+
QueueTimeUp();
|
|
296
303
|
}
|
|
297
304
|
}
|
|
298
305
|
}
|
|
299
306
|
}
|
|
300
307
|
|
|
301
|
-
private void
|
|
308
|
+
private void QueueTimeUp()
|
|
302
309
|
{
|
|
303
|
-
|
|
304
|
-
{
|
|
305
|
-
_replayTimeUpPending = true;
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
_timeUpTriggered = true;
|
|
310
|
-
_eventManager?.InvokeTimeUpEvent();
|
|
310
|
+
_timeUpPending = true;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
private void
|
|
313
|
+
private void DispatchPendingTimeUp()
|
|
314
314
|
{
|
|
315
|
-
if (!
|
|
315
|
+
if (!_timeUpPending)
|
|
316
316
|
return;
|
|
317
317
|
|
|
318
|
-
|
|
318
|
+
_timeUpPending = false;
|
|
319
319
|
if (_hasGameEnded || _timeUpTriggered)
|
|
320
320
|
return;
|
|
321
321
|
|
|
@@ -132,6 +132,32 @@ namespace Hyper.Internal
|
|
|
132
132
|
if (progressSlider != null) progressSlider.SetValueWithoutNotify(1f);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
internal void ResetForReplayRestart()
|
|
136
|
+
{
|
|
137
|
+
float playbackSpeed = ReplaySessionState.UserPlaybackSpeed;
|
|
138
|
+
if (!ReplaySessionState.IsSeeking && playbackSpeeds != null && playbackSpeeds.Length > 0)
|
|
139
|
+
{
|
|
140
|
+
playbackSpeed = SanitizePlaybackSpeed(playbackSpeeds[0]);
|
|
141
|
+
ReplaySessionState.SetPlaybackSpeed(playbackSpeed);
|
|
142
|
+
Time.timeScale = playbackSpeed;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
isCapturingSeek = false;
|
|
146
|
+
pendingSeekTarget = ReplaySessionState.IsSeeking
|
|
147
|
+
? ReplaySessionState.SeekTarget01
|
|
148
|
+
: 0f;
|
|
149
|
+
wasSeeking = ReplaySessionState.IsSeeking;
|
|
150
|
+
|
|
151
|
+
if (progressSlider != null)
|
|
152
|
+
{
|
|
153
|
+
progressSlider.SetValueWithoutNotify(pendingSeekTarget);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
UpdatePlaybackSpeedLabel(playbackSpeed);
|
|
157
|
+
AlignPlaybackSpeedIndex(playbackSpeed);
|
|
158
|
+
SetSeekingPresentation(ReplaySessionState.IsSeeking);
|
|
159
|
+
}
|
|
160
|
+
|
|
135
161
|
private void ExitReplay()
|
|
136
162
|
{
|
|
137
163
|
if (exitButton != null) exitButton.interactable = false;
|
|
@@ -23,6 +23,13 @@ namespace Hyper.Internal
|
|
|
23
23
|
if (exitButton != null) exitButton.onClick.AddListener(Exit);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
private void OnEnable()
|
|
27
|
+
{
|
|
28
|
+
_handled = false;
|
|
29
|
+
if (watchAgainButton != null) watchAgainButton.interactable = true;
|
|
30
|
+
if (exitButton != null) exitButton.interactable = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
private void OnDestroy()
|
|
27
34
|
{
|
|
28
35
|
if (watchAgainButton != null) watchAgainButton.onClick.RemoveListener(WatchAgain);
|
|
@@ -14,7 +14,7 @@ namespace Hyper.Internal
|
|
|
14
14
|
[SerializeField] private BlinkingText blinkingText;
|
|
15
15
|
[SerializeField] private RectTransform swipeGif;
|
|
16
16
|
[SerializeField] private RectTransform handSpriteInGif;
|
|
17
|
-
[SerializeField] private float replayAutoStartDelay =
|
|
17
|
+
[SerializeField] private float replayAutoStartDelay = 1f;
|
|
18
18
|
private GameManager _gameManager;
|
|
19
19
|
private StartCTA _currentCTA;
|
|
20
20
|
private SwipeDirection _swipeDirection;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "app.hypergames.hypersdk",
|
|
3
|
-
"version": "1.11.0-beta.
|
|
3
|
+
"version": "1.11.0-beta.2",
|
|
4
4
|
"displayName": "HyperSDK",
|
|
5
5
|
"description": "Official Unity SDK for Hyper: multiplayer battles, leaderboards, deterministic RNG, session management, tutorials, and WebGL optimizations for production-ready games.",
|
|
6
6
|
"unity": "6000.0",
|